﻿$.widget('ui.textbox', {
    options: {
        hint: '',
        cssClassError: 'textbox-error',
        cssClassHint: 'textbox-hint',
        cssClassNormal: 'textbox-normal',
        cookieName: null,
        autocomplete: null,
        autocompleteDelay: 200,
        regexp: null
    },
    _timerID: 0,
    _create: function() {
        var self = this;
        $(this.element)
        .keypress(function(e) { self._onKeyPress(e); })
        .keydown(function(e) { self.switchToNormal(); })
        .keyup(function(e) { self.switchToNormal(); })
        .click(function() { self.switchToNormal(); })
        .focus(function() { self.switchToNormal(); })
        .blur(function() {
            $(this).toggleClass(self.options.cssClassError, false);
            if ($(this).val().length == 0) $(this).val(self.options.hint).toggleClass(self.options.cssClassNormal, false).toggleClass(self.options.cssClassHint, true);
            if (self.options.autocomplete) self._hideAutocomplete();
        });

        if (this.options.autocomplete) $(this.element).keyup(function() { self.showAutocomplete(); });

        if (this.options.cookieName && ($(this.element).val() == '')) {
            var text = getCookie(this.options.cookieName);
            if (text) $(this.element).val(text);
        }

        if ($(this.element).val() == '') this.reset();
        else $(this.element).toggleClass(this.options.cssClassNormal, true).toggleClass(this.options.cssClassHint, false).toggleClass(this.options.cssClassError, false);

        if (this.options.autocomplete) {
            var dropdown = $('<div class="ui-dropdown-body ui-frame" style="position:absolute"></div>');
            dropdown.bind('mousedown', function(e) { e.stopImmediatePropagation(); });
            dropdown.hide();
            dropdown.insertAfter(this.element);
            this.element.data('dropdown', dropdown);
        }
    },
    _onKeyPress: function(e) {
        if (this.options.regexp) {
            if (this._isPrintable(e.which) && !this.options.regexp.test(String.fromCharCode(e.which))) {
                e.preventDefault();
                return false;
            }
        }
    },
    _isPrintable: function(code) {
        return (code >= 32 && code < 127);
    },    
    switchToNormal: function() {
        var e = $(this.element);
        e.toggleClass(this.options.cssClassError, false);
        if ((e.val() == this.options.hint) || (!e.val().length && !this.options.hint)) e.val('').toggleClass(this.options.cssClassNormal, true).toggleClass(this.options.cssClassHint, false);
    },
    showAutocomplete: function() {
        this._clearTimer();
        var self = this;
        this._timerID = setTimeout(function() { self._showAutocomplete(); }, this.options.autocompleteDelay);
    },
    _hideAutocomplete: function() {
        this._clearTimer();
        var dd = this.element.data('dropdown');
        if (dd) dd.hide();
    },
    _clearTimer: function() {
        if (this._timerID) {
            clearTimeout(this._timerID);
            this._timerID = null;
        }
    },
    _showAutocomplete: function() {
        var self = this;
        this._clearTimer();
        if (this.options.autocomplete)
            this.options.autocomplete(this.text(), function(list) { self._fillAutocomplete(list); });
    },
    _fillAutocomplete: function(list) {
        var dd = this.element.data('dropdown');
        var self = this;
        if (list && list.length) {
            var e = $(this.element);
            var pos = e.position();
            dd.css('width', e.outerWidth() + 'px');
            dd.css('top', (pos.top + e.outerHeight()) + 'px');
            dd.css('left', pos.left + 'px');

            dd.empty();
            $.each(list, function(idx, val) {
                var d = $('<div></div>').appendTo(dd);
                $('<a href="javascript://">' + val + '</a>').appendTo(d).mousedown(function() { self.set($(this).text()); });
            });
            dd.show();
        } else {
            dd.hide();
        }
    },
    reset: function() {
        $(this.element).val(this.options.hint).toggleClass(this.options.cssClassNormal, false).toggleClass(this.options.cssClassHint, true).toggleClass(this.options.cssClassError, false);
    },
    error: function() {
        $(this.element).toggleClass(this.options.cssClassNormal, false).toggleClass(this.options.cssClassHint, false).toggleClass(this.options.cssClassError, true);
    },
    text: function() {
        var txt = $(this.element).val();
        this.remember();
        return (txt == this.options.hint ? '' : txt);
    },
    set: function(txt) {
        if (txt && txt.length) $(this.element).val(txt).toggleClass(this.options.cssClassNormal, true).toggleClass(this.options.cssClassHint, false).toggleClass(this.options.cssClassError, false);
        else this.reset();
    },
    remember: function() {
        if (this.options.cookieName) {
            var date = new Date();
            date.setFullYear(date.getFullYear() + 1, date.getMonth(), date.getDate());

            var txt = $(this.element).val();
            setCookie(this.options.cookieName, (txt == this.options.hint ? '' : txt), date);
        }
    },
    destroy: function() {
        $.Widget.prototype.destroy.apply(this, arguments);
    }
});    
