var id_ship = 0;

$(function(){
    if($.sexyCombo) {
        $('.select-shipname').sexyCombo({
            emptyText: 'Type in or select your ship'
        });
    }
    $('.custom-select').jcombox({
        fx: 'slide'
    });
	
    $select_startdate = $('#id_voyage');
	
    $('.date-pick').datePicker({
        clickInput: false,
        showYearNavigation: true
    });

    $('#bagIE6input').click(function(event){
        event.preventDefault();
        $('form#searchBox').submit();
    });

    $('.date-pick').bind("dateSelected", function(e, selectedDates){
        if($(this).attr('name') == 'date_arrival'){
            $last = $('.date-pick[name=date_departure]');
            $last.dpSetStartDate($(this).val());
            $last.dpSetSelected($(this).val());
            $last.val($(this).val());
        }
    });

    $('a#buttonEnterShipDetails').click(function(event){
        event.preventDefault();
        $('#departure').slideToggle();
        $('#arrival').slideToggle();
        $('#selectName').slideToggle();
        $('#select').slideToggle();
        $('#inputName').slideToggle('normal', function(){
            $('input#inputShipName').focus();
        });
        $('#buttonEnterShipDetails').toggleHtml("Select your ship name", "Can't find your ship in the list?");
        $('#customShip').toggleValue('0', '1');
    });

    $('form#searchBox').submit(function(event){

        var errors = [];
        
        custom = parseInt($('#customShip').val());
        if(custom){
            if (!$('#inputShipName').val()){
                errors.push('Please, enter ship name.');
                $('#inputShipName').focus();
            } else {
                date_arrival = parseInt($('#date_icon1').val(), 10);
                date_departure = parseInt($('#date_icon2').val(), 10);

                if(!date_arrival){
                    errors.push('Please, enter arrival date.');
                }

                if(!date_departure){
                    errors.push('Please, enter day of departure.');
                }
            }
        } else if (!parseInt($('#selectShipName').val())){
            errors.push('Please, type in or select your ship.');
            $('#selectShipName').focus();
        }

        if(errors.length){
            event.preventDefault();
            alert(errors.join('\n'));
        }
    });
    
    
    $('.date-pick').mask("19/39/2999", {
        label: 'mm/dd/yyyy'
    });
    $('#selectShipName').change(function(event){
        if(parseInt($(this).val()) && $(this).val() != id_ship){
            id_ship = $(this).val();
			
            $select_startdate.jcClear("Loading dates...");
            $select_startdate.jcDisable();
            $.post('/ships/schedule/',
            {
                id_ship: id_ship
            },
            function(data){
                if(data.ok){
                    var first = true;
                    $select_startdate.jcClear();
                    $.each(data.voyages, function(i){
                        var cl = this.discount ? "hot-deal" : "";
                        var date = new Date();

                        // Учёт смещения по часовм поясам
                        var offset = 0;
                        if (date.getTimezoneOffset() > -240)
                            // Часовой пояс западнее Спб
                            offset = (date.getTimezoneOffset() + 240 ) * 60;
                        else if (date.getTimezoneOffset() < -240)
                            // Часовой пояс восточнее Спб
                            offset = (date.getTimezoneOffset() + 240) * -60

                        this.date = parseInt(this.date) + offset;
                        date.setTime(parseInt(this.date) * 1000);
                        $select_startdate.jcAdd(this.id, date.format("longDate"), first, cl);
                        first = false;
                    });
                    $select_startdate.jcEnable();
                }
            }, 'json');
			
        } else if(!parseInt($(this).val())) {
            $select = $('#select-arrival');
            $select.html('<option>Type in or select your ship</option>');
            $select.disable();
            id_ship = $(this).val();
        }
    });
    
    $('.search-block').each(function(){
        $this = $(this);
        $('h2', $this).click(function(event){
            event.preventDefault();
            var id = $(this).parents('.section').attr('id').split('-')[1];
            showBlock(id);
        });

        function showBlock(id){
            var idStr = '#search-' + id;
            $('.section', $this).filter(idStr).removeClass('closed').end().not(idStr).addClass('closed');
        }

        showBlock('citybreaks');
    });
	
    $('#searchCitybreaksForm').submit(function(event){
        var errors = [];
		
        var date_start = parseInt($('#cb_start').val(), 10);

        if(!date_start){
            errors.push('Please, enter tour start date.');
        }
		
        if(errors.length){
            event.preventDefault();
            alert(errors.join('\n'));
        }
    });
});

/**
 * jCombox
 */
(function ($) {
    $.fn.setOffCss = function (a) {
        var b = this.parent();
        if ($(window).height() + (document.documentElement.scrollTop || document.body.scrollTop) < b.offset().top
            + this.height() + b.height()) {
            objTop = b.offset().top - ($.browser.msie ? 3 : 1) - this.height()
        } else {
            objTop = b.offset().top + ($.browser.msie ? -1 : 1) + b.height()
        }
        return this.css({
            //left: b.offset().left - ($.browser.msie ? 2 : 0),
            //top: objTop,
            width: b.width() + ($.browser.msie ? 2 : 0)
        });
    };
    $.fn.fadesTo = function (o) {
        return this.animate({
            opacity: o
        },
        0,
        function () {
            if (o == 1 && $.browser.msie) {
                this.style.removeAttribute("filter");
            }
        });
    };
    $.fn.addClassAll = function(cssClass){
        $(this).addClass('disabled');
        $('*', $(this)).addClass('disabled');
    };
    $.fn.removeClassAll = function(cssClass){
        $(this).removeClass('disabled');
        $('*', $(this)).removeClass('disabled');
    };
    $.fn.jcombox = function (o) {
        o = $.extend({
            fn: null,
            fx: "toggle",
            fxType: "easeOutBounce",
            fxDelay: 0,
            set: false,
            theme: "default",
            linkUrl: null
        },
        o || {});
        return this.each(function () {
            var b = $(this),
            _7 = "",
            _8 = b.attr("name"),
            _9 = $("option", b).eq(0).text(),
            _a = $("option", b).eq(0).val(),
            _b = "#" + _8,
            _c = b.attr("size"),
            _d = b.attr("rows") || 0,
            _e = b.attr("width") || 0,
            _f = b.attr("disabled") || 0,
            _10 = b.attr("onchange") || b.attr("onChange") || 0;
			
            //if(b.attr('id')) _b = '#' + b.attr('id');
			
            $("option", b).each(function () {
                if ($(this).attr("selected")) {
                    _9 = $(this).text();
                    _a = $(this).val()
                }
                _7 += ("<a href='" + (o.linkUrl != null ? "?" + _8 + "=" + $(this).val() : "#") + "' rel='"
                    + $(this).val() + "' class='item "+this.className+"'>" + $(this).text() + "</a>");
            });
            if (_c > 0) {
                b.replaceWith("<div class='jcombox-m " + o.theme + "' id='" + _8 + "'><input type='hidden' name='" + _8
                    + "' value='" + _a + "' /><div>" + _7 + "</div></div>");
                $(_b).css("background-image", "none");
                if (!$("div a", _b).eq(0).text()) {
                    $("div a", _b).eq(0).text("-");
                }
                $(_b).width($("div", _b).width() + 40 + "px");
                $(_b).height($("div a", _b).height() * _c + ($.browser.msie ? 4 : 2) + "px")
            } else {
                b.replaceWith("<div class='jcombox " + o.theme + "' id='" + _8 + "'><span class='field'>" + _9
                    + "</span><input type='hidden' name='"
                    + _8 + "' value='" + _a + "' id='" + _8 + "-field' /><div class='menu'>" + _7
                    + "</div><a class='icon'></a></div>");
                var c = $(_b);
                if ($("span", _b).width() > $("div", _b).width()) {
                //$(_b).width($("span", _b).width() + 35 + "px");
                } else {
                //$(_b).width($("div", _b).width() + 40 + "px");
                }
                if (_d > 1) {
                    $("div", _b).height($("span", _b).height() * _d + ($.browser.msie ? 2 : 0) + "px");
                }
                $(document).click(function (e) {
                    if ($("div", _b).css("display") == "block") {
                        $("div", _b).hide();
                    }
                });
				
                c.hover(function () {
                    clearTimeout(this.timeout);
                },
                function () {
                    this.timeout = setTimeout(function () {
                        if ($("div", _b).css("display") == "block") {
                            c.trigger("click");
                        }
                    },
                    750);
                });
                if (!$("span.field", _b).text()) {
                    $("span.field", _b).text("-");
                }
                if (o.set) {
                    c.css({
                        "border": "transparent",
                        "background-color": "transparent",
                        "padding-right": "2px"
                    });
                    $("span", _b).css({
                        "border": "transparent",
                        "background-image": c.css("background-image"),
                        "background-position": "left center",
                        "padding": "0 0px 3px 5px"
                    })
                }
            }
            $("div", _b).find("a[rel='" + $(":hidden", _b).val() + "']").addClass("current");
            $(_b).bind("jcDisable", function () {
                $(":hidden", _b).val("");
                $(":hidden", _b).trigger("change");
                if ($("div", _b).css("display") == "block" && !_c > 0) {
                    $("div", _b).hide();
                }
				
                $(_b).unbind("click");
                $(_b).addClassAll("disabled");
                $("div a", _b).unbind("click").bind("click", function () {
                    return false;
                });
            });
			
            $(_b).bind("jcEnable", function () {
                $(_b).removeClassAll("disabled");
                $(":hidden", this).val($(".current", this).attr("rel"));
                if (!_c > 0) {
                    $(_b).unbind("click").bind("click", function (e) {
                        var a = $("div", _b);
                        switch (o.fx) {
                            case "toggle":
                                a.setOffCss().toggle();
                                break;
                            case "slide":
                                a.setOffCss().slideToggle(o.fxDelay);
                                break;
                            case "fade":
                                a.setOffCss().animate({
                                    opacity:
                                    "toggle"
                                },
                                o.fxDelay).fadesTo(1);
                                break;
                            case "slideFade":
                                a.setOffCss().animate({
                                    opacity:
                                    "toggle",
                                    height: "toggle"
                                },
                                o.fxDelay).fadesTo(1);
                                break;
                            case "easing":
                                a.setOffCss().slideToggle(o.fxDelay, o.fxType);
                                break
                        }
                        e.stopPropagation();
                    });
                }
                $("a.item", _b).unbind("click").bind("click", function () {
                    if ($(this).hasClass("disabled")) {
                        return false;
                    }
                    $("a", _b).removeClass("current");
                    $(this).addClass("current");
                    if ($.browser.safari) {
                        $(this).fadesTo(0.99).fadesTo(1);
                    }
                    if (!_c > 0) {
                        $("span.field", _b).text($(this).text());
                        $(_b).trigger("click");
                    }
					
                    if($(this).hasClass('hot-deal')){
                        $("span.field", _b).addClass('hot-deal');
                    } else {
                        $('span.field', _b).removeClass('hot-deal');
                    }
					
                    $(":hidden", _b).val($(this).attr("rel"));
                    $(":hidden", _b).trigger("change");
                    if (o.fn) {
                        o.fn();
                    }
                    if ($.browser.msie && _10) {
                        eval(_10());
                    } else {
                        if (_10) {
                            eval(_10);
                        }
                    }
                    return false;
                });
                $("a", this).css("color", $("." + o.theme).css("color"));
                $("span.field", this).css("overflow", "hidden");
            });
            if (b.attr("disabled")) {
                $(_b).trigger("jcDisable");
            } else {
                $(_b).trigger("jcEnable");
            }
            $(_b).bind("selectstart mousedown", function () {
                return false
            }).css("MozUserSelect", "none");
            $(_b).hover(function () {
                $(this).addClass(o.theme + "-hover");
                if (o.set) {
                    $("span", _b).css("background-image", c.css("background-image"));
                }
            },
            function () {
                $(this).removeClass(o.theme + "-hover");
                if (o.set) {
                    $("span", _b).css("background-image", $("." + o.theme).css("background-image"));
                }
            });
            if (_e) {
                $(_b).width(_e + "px");
            }
			
            $("div", _b).mouseover(function(){
                $('.current', $(this)).removeClass('current');
            });
        })
    };
    var d = ["jcEnable", "jcDisable", "jcClear"];
    for (var i = 0; i < d.length; i++) {
        $.fn[d[i]] = (function (a) {
            return function () {
                this.trigger(a);
            }
        })(d[i])
    }
    $.fn.jcSelected = function (a) {
        if (a) {
            return $(".current", this).text();
        } else {
            return $(":hidden", this).val();
        }
    };
	
    $.fn.jcAdd = function (a, b, c, cl) {
        if (c) {
            $("a.current", this).removeClass()
        }
        $("div", this).append("<a class='item " + (c ? "current ": "") + cl + "' href='#' rel='" + a + "' >" + b + "</a>");
        if (c) {
            $("span.field", this).text($(".current", this).text());
            if(cl) {
                $("span.field", this).addClass(cl);
            } else {
                $("span.field", this).removeClass('hot-deal');
            }
        }
    };
	
    $.fn.jcEdit = function (a, b) {
        $(".current", this).replaceWith("<a class='current' href='#' rel='" + a + "' >" + b + "</a>");
        this.jcEnable();
        if ($(".current", this).text()) {
            $("span.field", this).text($(".current", this).text());
        }
    };
	
    $.fn.jcClear = function (a) {
        if (parseInt(a)) {
            $("a.current", this).removeClass()
        } else {
            $(".current", this).slideUp(function () {
                $(this).remove();
            })
        }
        this.jcEnable();
        $("span.field", this).text(a?a:"-");
        $(":hidden", this).val("");
        $('a.item', this).each(function(){
            $(this).remove();
        });
    }

})(jQuery);

/**
 * Sexy combo
 */
(function ($) {
    $.fn.sexyCombo = function (config) {
        return this.each(function () {
            if ("SELECT" != this.tagName.toUpperCase()) {
                return
            }
            new $sc(this, config)
        })
    };
	
    var defaults = {
        skin: "sexy",
        suffix: "__sexyCombo",
        hiddenSuffix: "__sexyComboHidden",
        initialHiddenValue: "",
        emptyText: "",
        autoFill: false,
        triggerSelected: true,
        filterFn: null,
        dropUp: false,
        separator: ",",
        showListCallback: null,
        hideListCallback: null,
        initCallback: null,
        initEventsCallback: null,
        changeCallback: null,
        textChangeCallback: null
    };
	
    $.sexyCombo = function (selectbox, config) {
        if (selectbox.tagName.toUpperCase() != "SELECT") return;
        this.config = $.extend({},
            defaults, config || {});
        this.selectbox = $(selectbox);
        this.options = this.selectbox.children().filter("option");
        this.wrapper = this.selectbox.wrap("<div>").hide().parent().addClass("combo").addClass(this.config.skin);
        this.input = $("<input type='text' />").appendTo(this.wrapper).attr("autocomplete", "off").attr("value", "").attr("name", this.selectbox.attr("name") + this.config.suffix);
        this.hidden = $("<input type='hidden' />").appendTo(this.wrapper).attr("autocomplete", "off").attr("value", this.config.initialHiddenValue).attr("name", this.selectbox.attr("name") + this.config.hiddenSuffix);
        this.emptyText = 'No matches';
        this.icon = $("<div />").appendTo(this.wrapper).addClass("icon");
        this.listWrapper = $("<div />").appendTo(this.wrapper).addClass("list-wrapper");
        if ("function" == typeof this.listWrapper.bgiframe) {
            this.listWrapper.bgiframe({
                height: 1000
            })
        }
        this.updateDrop();
        this.list = $("<ul />").appendTo(this.listWrapper);
        var self = this;
        this.options.each(function () {
            var optionText = $.trim($(this).text());
            if(optionText){
                $("<li />").appendTo(self.list).html("<span>" + optionText + "</span>").addClass("visible")
            }
        });
        this.listItems = this.list.children();
        var optWidths = [];
        this.listItems.find("span").each(function () {
            optWidths.push($(this).outerWidth())
        });
        optWidths = optWidths.sort(function (a, b) {
            return a - b
        });
        var maxOptionWidth = optWidths[optWidths.length - 1];
        this.singleItemHeight = this.listItems.outerHeight();
        this.listWrapper.addClass("invisible");
        if ($.browser.opera) {
            this.wrapper.css({
                position: "relative",
                left: "0",
                top: "0"
            })
        }
        this.filterFn = ("function" == typeof(this.config.filterFn)) ? this.config.filterFn: this.filterFn;
        this.lastKey = null;
        this.multiple = this.selectbox.attr("multiple");
        var self = this;
        this.wrapper.data("sc:lastEvent", "click");
        this.overflowCSS = "overflowY";
        if (this.listWrapper.innerWidth() < maxOptionWidth) {
            this.overflowCSS = "overflow"
        }
        this.notify("init");
        this.initEvents()
    };
	
    var $sc = $.sexyCombo;
    $sc.fn = $sc.prototype = {};
    $sc.fn.extend = $sc.extend = $.extend;
    $sc.fn.extend({
		
        __getCurrentValue: function (prop) {
            prop = this[prop];
            if (!this.multiple) return $.trim(prop.val());
            return $.trim(prop.val().split(this.config.separator).pop())
        },
		
        __getValue: function (prop) {
            prop = this[prop];
            if (!this.multiple) return $.trim(prop.val());
            var tmpVals = prop.val().split(this.config.separator);
            var vals = [];
            for (var i = 0, len = tmpVals.length; i < len; ++i) {
                vals.push($.trim(tmpVals[i]))
            }
            vals = $sc.normalizeArray(vals);
            return vals
        },

        applyEmptyText: function () {
            if (!this.config.emptyText.length) return;
            if(this.input.val() == '') {
                this.input.addClass("empty").val(this.config.emptyText)
            }
        },
		
        autoFill: function () {
            if (!this.config.autoFill || ($sc.KEY.BACKSPACE == this.lastKey) || this.multiple) return;
            var curVal = this.input.val();
            var newVal = this.getActive().text();
            this.input.val(newVal);
            this.selection(this.input.get(0), curVal.length, newVal.length)
        },
		
        filter: function () {
            this.highlight(false);
            if (this.wrapper.data("sc:optionsChanged") == 'yes') {
                var self = this;
                this.listItems.remove();
                this.options = this.selectbox.children().filter("option");
                this.options.each(function () {
                    var optionText = $.trim($(this).text());
                    if(optionText){
                        $("<li />").appendTo(self.list).text(optionText).addClass("visible");
                    }
                });
                this.listItems = this.list.children();
                $('span', this.listItems).bind("mouseover", function (e) {
                    self.highlight($(e.target).parent('li'));
                });
                this.listItems.bind("click", function (e) {
                    self.listItemClick($(e.target))
                });
                self.wrapper.data("sc:optionsChanged", "")
            }
            var comboValue = this.input.val();
            var self = this;
            this.listItems.each(function () {
                var $this = $(this);
                var itemValue = $this.text();
                if (self.filterFn.call(self, self.getCurrentTextValue(), itemValue, self.getTextValue()) &&
                    !$this.hasClass('empty')) {
                    $this.removeClass("invisible").addClass("visible");
                    searchValue = self.getCurrentTextValue();
                    var re = new RegExp('(' + searchValue + ')', 'i');
                    $('span', $this).html(itemValue.replace(re, '<b class="highlight">$1</b>'));
                } else {
                    $this.removeClass("visible").addClass("invisible")
                }
            });
			
            if(!this.listItems.filter('.visible').length){
                if(!this.listItems.filter('.empty').length){
                    this.listItems.push($('<li />').appendTo(self.list).text(this.emptyText)
                        .addClass('empty').get(0));
                }
                this.listItems.filter('.empty').addClass('visible');
            }
            this.setOverflow();
            this.setListHeight()
        },
		
        filterFn: function (currentComboValue, itemValue, allComboValues) {
            if ("click" == this.wrapper.data("sc:lastEvent")) {
                return true
            }
            if (!this.multiple) {
                return itemValue.toLowerCase().search(currentComboValue.toLowerCase()) > -1
            } else {
                for (var i = 0, len = allComboValues.length; i < len; ++i) {
                    if (itemValue == allComboValues[i]) {
                        return false
                    }
                }
                return itemValue.toLowerCase().search(currentComboValue.toLowerCase()) == 0
            }
        },
		
        getActive: function () {
            return this.listItems.filter(".active");
        },
		
        getActiveIndex: function () {
            return $.inArray(this.getActive().get(0), this.listItems.filter(".visible").get())
        },
		
        getCurrentHiddenValue: function () {
            return this.__getCurrentValue("hidden")
        },
		
        getCurrentTextValue: function () {
            return this.__getCurrentValue("input")
        },
		
        getFirst: function(){
            return this.listItems.filter('.visible').removeClass("active").filter(":first");
        },
		
        getHiddenValue: function () {
            return this.__getValue("hidden")
        },
		
        getListItemsHeight: function () {
            var itemHeight = this.singleItemHeight;
            return itemHeight * this.liLen()
        },
		
        getListMaxHeight: function () {
            var result = parseInt(this.listWrapper.css("maxHeight"), 10);
            if (isNaN(result)) {
                result = 200
            }
            return result
        },
		
        getTextValue: function () {
            return this.__getValue("input")
        },
		
        hideList: function () {
            if (this.listWrapper.hasClass("invisible")) return;
            this.listWrapper.removeClass("visible").addClass("invisible");
            this.wrapper.css("zIndex", "0");
            this.listWrapper.css("zIndex", "99999");
            this.notify("hideList")
        },
		
        highlight: function ($activeItem) {
            this.listItems.removeClass('active');
            $('span', this.listItems).removeClass('active');
			
            if($activeItem){
                $activeItem.addClass("active");
                $('span', $activeItem).addClass('active');
            }
        },
		
        highlightFirst: function () {
            this.highlight($this.getFirst());
            this.autoFill()
        },
		
        highlightNext: function () {
            var $active = this.getActive();
            if($active.length){
                var $next = $active.next();
                while ($next.hasClass("invisible") && $next.length) {
                    $next = $next.next()
                }
            } else {
                $next = this.getFirst();
            }
            if ($next.length) {
                this.highlight($next);
                this.scrollDown()
            }
        },
		
        highlightPrev: function () {
            var $prev = this.getActive().prev();
            while ($prev.length && $prev.hasClass("invisible")) {
                $prev = $prev.prev();
            }
            if ($prev.length) {
                this.highlight($prev);
                this.scrollUp()
            }
        },
		
        iconClick: function () {
            if (this.listVisible()) {
                this.hideList();
                this.input.blur()
            } else {
                this.showList();
                this.input.focus();
                this.inputFocus();
                if (this.input.val().length) {
                    this.selection(this.input.get(0), 0, this.input.val().length)
                }
            }
        },
		
        initEvents: function () {
            var self = this;
			
            this.icon
            .click(function(event){
                if (self.input.attr("disabled")) {
                    self.input.attr("disabled", false)
                }
                self.wrapper.data("sc:lastEvent", "click");
                if (!self.wrapper.data("sc:positionY")) {
                    self.wrapper.data("sc:positionY", event.pageY)
                }
                self.filter();
                self.iconClick();
            });
			
            $('span', this.listItems).mouseover(function(event){
                self.highlight($(event.target).parent('li'));
            });
			
            this.listItems.click(function(event){
                self.listItemClick($(event.target))
            });
						
            this.input
            .click(function(event){
                self.wrapper.data("sc:lastEvent", "click");
                self.icon.trigger("click");
                if (!self.wrapper.data("sc:positionY")) {
                    self.wrapper.data("sc:positionY", event.pageY)
                }
            })
            .keydown(function(event){
                if (9 == event.keyCode) {
                    event.preventDefault()
                }
            })
            .keyup(function(event){
                self.wrapper.data("sc:lastEvent", "key");
                self.keyUp(event)
            })
            .keypress(function(event){
                if (event.keyCode == $sc.KEY.TAB || event.keyCode == $sc.KEY.RETURN) {
                    event.preventDefault()
                }
            })
            /**
				 * Обработчик фокуса поля запускается в обработчике клика по иконке
				 */
            .focus(function(event){
                $(this).addClass('ffocus');
            })
            .blur(function(event){
                self.inputBlur();
            });
			
            this.wrapper
            .click(function(event){
                self.wrapper.data("sc:lastEvent", "click");
                if (!self.wrapper.data("sc:positionY")) {
                    self.wrapper.data("sc:positionY", event.pageY)
                }
            })
            .keyup(function(event){
                var k = event.keyCode;
                for (key in $sc.KEY) {
                    if ($sc.KEY[key] == k) {
                        return
                    }
                }
                self.wrapper.data("sc:lastEvent", "key")
            });
			
            $(document).bind("click", function (e) {
                if ((self.icon.get(0) == e.target) || (self.input.get(0) == e.target)) return;
                self.hideList();
            });
			
            this.triggerSelected();
            this.applyEmptyText();
			
            this.notify("initEvents")
        },
		
        inputBlur: function () {
            if ("" == this.input.val()) {
                this.input.addClass("empty").val(this.config.emptyText)
            }
            this.input.removeClass('ffocus');
        },
		
        inputChanged: function () {
            this.filter();
            if (this.liLen()) {
                this.showList();
                this.setOverflow();
                this.setListHeight()
            } else {
                this.hideList()
            }
            this.setHiddenValue(this.input.val());
            this.notify("textChange")
        },
		
        inputFocus: function () {
            if (this.input.hasClass("empty")) {
                this.input.removeClass("empty").val("")
            }
        },
		
        keyUp: function (event) {
            this.lastKey = event.keyCode;
            var k = $sc.KEY;
            switch (event.keyCode) {
                case k.RETURN:
                case k.TAB:
                    this.setComboValue(this.getActive().text(), true, true);
                    if (!this.multiple) this.input.blur();
                    break;
                case k.DOWN:
                    this.highlightNext();
                    break;
                case k.UP:
                    this.highlightPrev();
                    break;
                case k.ESC:
                    this.hideList();
                    break;
                default:
                    this.inputChanged();
                    break
            }
        },
		
        liLen: function () {
            return this.listItems.filter(".visible").length
        },
		
        listItemClick: function (item) {
            this.setComboValue(item.text(), true, true);
            this.inputFocus()
        },
		
        listVisible: function () {
            return this.listWrapper.hasClass("visible")
        },
		
        notify: function (evt) {
            if (!$.isFunction(this.config[evt + "Callback"])) return;
            this.config[evt + "Callback"].call(this)
        },
		
        scrollDown: function () {
            if ("scroll" != this.listWrapper.css(this.overflowCSS)) return;
            var beforeActive = this.getActiveIndex() + 1;
            var minScroll = this.listItems.outerHeight() * beforeActive - this.listWrapper.height();
            if ($.browser.msie) minScroll += beforeActive;
            if (this.listWrapper.scrollTop() < minScroll) this.listWrapper.scrollTop(minScroll)
        },
		
        scrollUp: function () {
            if ("scroll" != this.listWrapper.css(this.overflowCSS)) return;
            var maxScroll = this.getActiveIndex() * this.listItems.outerHeight();
            if (this.listWrapper.scrollTop() > maxScroll) {
                this.listWrapper.scrollTop(maxScroll)
            }
        },
		
        selection: function (field, start, end) {
            if (field.createTextRange) {
                var selRange = field.createTextRange();
                selRange.collapse(true);
                selRange.moveStart("character", start);
                selRange.moveEnd("character", end);
                selRange.select()
            } else if (field.setSelectionRange) {
                field.setSelectionRange(start, end)
            } else {
                if (field.selectionStart) {
                    field.selectionStart = start;
                    field.selectionEnd = end
                }
            }
        },
		
        setComboValue: function (val, pop, hideList) {
            var oldVal = this.input.val();
            var v = "";
            if (this.multiple) {
                v = this.getTextValue();
                if (pop) v.pop();
                v.push($.trim(val));
                v = $sc.normalizeArray(v);
                v = v.join(this.config.separator) + this.config.separator
            } else {
                v = $.trim(val)
            }
            this.input.val(v);
            this.setHiddenValue(val);
            this.filter();
            if (hideList) this.hideList();
            this.input.removeClass("empty");
            if (this.multiple) this.input.focus();
            if (this.input.val() != oldVal) this.notify("textChange")
        },
		
        setDropUp: function (drop) {
            this.config.dropUp = drop;
            this.updateDrop()
        },
		
        setHiddenValue: function (val) {
            var set = false;
            val = $.trim(val);
            var oldVal = this.hidden.val();
            if (!this.multiple) {
                for (var i = 0, len = this.options.length; i < len; ++i) {
                    if (val == this.options.eq(i).text()) {
                        this.hidden.val(this.options.eq(i).val());
                        set = true;
                        break
                    }
                }
            } else {
                var comboVals = this.getTextValue();
                var hiddenVals = [];
                for (var i = 0, len = comboVals.length; i < len; ++i) {
                    for (var j = 0, len1 = this.options.length; j < len1; ++j) {
                        if (comboVals[i] == this.options.eq(j).text()) {
                            hiddenVals.push(this.options.eq(j).val())
                        }
                    }
                }
                if (hiddenVals.length) {
                    set = true;
                    this.hidden.val(hiddenVals.join(this.config.separator))
                }
            }
            if (!set) {
                this.hidden.val(this.config.initialHiddenValue)
            }
            if (oldVal != this.hidden.val()) this.notify("change");
            this.selectbox.val(this.hidden.val());
            this.selectbox.trigger("change")
        },
		
        setListHeight: function () {
            var liHeight = this.getListItemsHeight();
            var maxHeight = this.getListMaxHeight();
            var listHeight = this.listWrapper.height();
            if (liHeight < listHeight) {
                this.listWrapper.height(liHeight);
                return liHeight
            } else if (liHeight > listHeight) {
                this.listWrapper.height(Math.min(maxHeight, liHeight));
                return Math.min(maxHeight, liHeight)
            }
        },
				
        setOverflow: function () {
            var maxHeight = this.getListMaxHeight();
            if (this.getListItemsHeight() > maxHeight) {
                this.listWrapper.css(this.overflowCSS, "scroll");
            } else {
                this.listWrapper.css(this.overflowCSS, "hidden")
            }
        },
		
        showList: function () {
            if (!this.listItems.filter(".visible").length) return;
            this.listWrapper.removeClass("invisible").addClass("visible");
            this.wrapper.css("zIndex", "99999");
            this.listWrapper.css("zIndex", "99999");
            this.setListHeight();
            var listHeight = this.listWrapper.height();
            var inputHeight = this.wrapper.height();
            var bottomPos = parseInt(this.wrapper.data("sc:positionY")) + inputHeight + listHeight;
            var maxShown = $(window).height() + $(document).scrollTop();
            if (bottomPos > maxShown) {
                this.setDropUp(true)
            } else {
                this.setDropUp(false)
            }
            this.listWrapper.scrollTop(0);
            this.notify("showList")
        },

        triggerSelected: function () {
            if (!this.config.triggerSelected) return;
            var self = this;
            var set = false;
            this.options.each(function () {
                if ($(this).attr("selected")) {
                    set = true;
                    self.setComboValue($(this).text(), false, true)
                }
            })
        },

        updateDrop: function () {
            if (this.config.dropUp) this.listWrapper.addClass("list-wrapper-up");
            else this.listWrapper.removeClass("list-wrapper-up")
        }
    });
	
    $sc.extend({
        KEY: {
            UP: 38,
            DOWN: 40,
            DEL: 46,
            TAB: 9,
            RETURN: 13,
            ESC: 27,
            COMMA: 188,
            PAGEUP: 33,
            PAGEDOWN: 34,
            BACKSPACE: 8
        },
		
        log: function (msg) {
            var $log = $("#log");
            $log.html($log.html() + msg + "<br />")
        },
		
        createSelectbox: function (config) {
            var $selectbox = $("<select />").appendTo(config.container).attr({
                name: config.name,
                id: config.id,
                size: "1"
            });
            if (config.multiple) $selectbox.attr("multiple", true);
            var data = config.data;
            var selected = false;
            for (var i = 0, len = data.length; i < len; ++i) {
                selected = data[i].selected || false;
                $("<option />").appendTo($selectbox).attr("value", data[i].value).text(data[i].text).attr("selected", selected);
            }
            return $selectbox.get(0)
        },
		
        create: function (config) {
            var defaults = {
                name: "",
                id: "",
                data: [],
                multiple: false,
                container: $(document),
                url: "",
                ajaxData: {}
            };
            config = $.extend({},
                defaults, config || {});
            if (config.url) {
                return $.getJSON(config.url, config.ajaxData, function (data) {
                    delete config.url;
                    delete config.ajaxData;
                    config.data = data;
                    return $sc.create(config)
                })
            }
            config.container = $(config.container);
            var selectbox = $sc.createSelectbox(config);
            return new $sc(selectbox, config)
        },
		
        deactivate: function ($select) {
            $select = $($select);
            $select.each(function () {
                if ("SELECT" != this.tagName.toUpperCase()) {
                    return
                }
                var $this = $(this);
                if (!$this.parent().is(".combo")) {
                    return
                }
            })
        },
		
        activate: function ($select) {
            $select = $($select);
            $select.each(function () {
                if ("SELECT" != this.tagName.toUpperCase()) {
                    return
                }
                var $this = $(this);
                if (!$this.parent().is(".combo")) {
                    return
                }
                $this.parent().find("input[type='text']").attr("disabled", false)
            })
        },
		
        changeOptions: function ($select) {
            $select = $($select);
            $select.each(function () {
                if ("SELECT" != this.tagName.toUpperCase()) {
                    return
                }
                var $this = $(this);
                var $wrapper = $this.parent();
                var $input = $wrapper.find("input[type='text']");
                var $listWrapper = $wrapper.find("ul").parent();
                $listWrapper.removeClass("visible").addClass("invisible");
                $wrapper.css("zIndex", "0");
                $listWrapper.css("zIndex", "99999");
                $input.val("");
                $wrapper.data("sc:optionsChanged", "yes");
                var $selectbox = $this;
                $selectbox.parent().find("input[type='text']").val($selectbox.find("option:eq(0)").text());
                $selectbox.parent().data("sc:lastEvent", "click");
                $selectbox.find("option:eq(0)").attr('selected', 'selected')
            })
        },
		
        normalizeArray: function (arr) {
            var result = [];
            for (var i = 0, len = arr.length; i < len; ++i) {
                if ("" == arr[i]) continue;
                result.push(arr[i])
            }
            return result
        }
    })
})(jQuery);