/**
* combobox - jQuery EasyUI
* 
* Licensed under the GPL:
*   http://www.gnu.org/licenses/gpl.txt
*
* Copyright 2010 stworthy [ stworthy@gmail.com ] 
* 
* Dependencies:
*   combo_ciho
* 
*/
(function ($) {
    /**
    * select previous item
    */
    function selectPrev(target) {
        var layoutpanel = $(target).combo_ciho('layoutpanel');
        var values = $(target).combo_ciho('getValues');
        var item = layoutpanel.find('div.combobox-item[value=' + values.pop() + ']');
        if (item.length) {
            var prev = item.prev(':visible');
            if (prev.length) {
                item = prev;
            }
        } else {
            item = layoutpanel.find('div.combobox-item:visible:last');
        }
        var value = item.attr('value');
        setValues(target, [value]);

        if (item.position()) {
            if (item.position().top <= 0) {
                var h = layoutpanel.scrollTop() + item.position().top;
                layoutpanel.scrollTop(h);
            } else if (item.position().top + item.outerHeight() > layoutpanel.height()) {
                var h = layoutpanel.scrollTop() + item.position().top + item.outerHeight() - layoutpanel.height();
                layoutpanel.scrollTop(h);
            }
        }
    }

    /**
    * select next item
    */
    function selectNext(target) {
        var layoutpanel = $(target).combo_ciho('layoutpanel');
        var values = $(target).combo_ciho('getValues');
        var item = layoutpanel.find('div.combobox-item[value=' + values.pop() + ']');
        if (item.length) {
            var next = item.next(':visible');
            if (next.length) {
                item = next;
            }
        } else {
            item = layoutpanel.find('div.combobox-item:visible:first');
        }
        var value = item.attr('value');
        setValues(target, [value]);

        if (item.position()) {
            if (item.position().top <= 0) {
                var h = layoutpanel.scrollTop() + item.position().top;
                layoutpanel.scrollTop(h);
            } else if (item.position().top + item.outerHeight() > layoutpanel.height()) {
                var h = layoutpanel.scrollTop() + item.position().top + item.outerHeight() - layoutpanel.height();
                layoutpanel.scrollTop(h);
            }
        }
        //end of next
    }

    function selectCurr(target) {
        var layoutpanel = $(target).combo_ciho('layoutpanel');
        var item = layoutpanel.find('div.combobox-item-selected');
        if ([item.attr('value')] != "") {//ciho
            setValues(target, [item.attr('value')]);
        } //ciho
        $(target).combo_ciho('hidePanel');
    }

    /**
    * select the specified value
    */
    function select(target, value) {
        var opts = $.data(target, 'combobox').options;
        var data = $.data(target, 'combobox').data;

        if (opts.multiple) {
            var values = $(target).combo_ciho('getValues');
            for (var i = 0; i < values.length; i++) {
                if (values[i] == value) return;
            }
            values.push(value);
            setValues(target, values);
        } else {
            setValues(target, [value]);
            $(target).combo_ciho('hidePanel');
        }

        for (var i = 0; i < data.length; i++) {
            if (data[i][opts.valueField] == value) {
                opts.onSelect.call(target, data[i]);
                return;
            }
        }
    }

    /**
    * unselect the specified value
    */
    function unselect(target, value) {
        var opts = $.data(target, 'combobox').options;
        var data = $.data(target, 'combobox').data;
        var values = $(target).combo_ciho('getValues');
        for (var i = 0; i < values.length; i++) {
            if (values[i] == value) {
                values.splice(i, 1);
                setValues(target, values);
                break;
            }
        }
        for (var i = 0; i < data.length; i++) {
            if (data[i][opts.valueField] == value) {
                opts.onUnselect.call(target, data[i]);
                return;
            }
        }
    }

    /**
    * set values
    */
    function setValues(target, values, remainText) {
        var opts = $.data(target, 'combobox').options;
        var data = $.data(target, 'combobox').data;
        var layoutpanel = $(target).combo_ciho('layoutpanel');

        layoutpanel.find('div.combobox-item-selected').removeClass('combobox-item-selected');
        var vv = [], ss = [];
        for (var i = 0; i < values.length; i++) {
            var v = values[i];
            var s = v;
            for (var j = 0; j < data.length; j++) {
                if (data[j][opts.valueField] == v) {
                    s = data[j][opts.textField];
                    break;
                }
            }
            vv.push(v);
            ss.push(s);
            layoutpanel.find('div.combobox-item[value=' + v + ']').addClass('combobox-item-selected');
        }
        //        //debugger
        //        alert("ddd");
        $(target).combo_ciho('setValues', vv);
        if (!remainText) {
            $(target).combo_ciho('setText', ss.join(opts.separator));
        }
        //增加afterChange事件。
        if (opts.multiple) {
            opts.afterChange.call(target, vv, ss);
        } else {
            opts.afterChange.call(target, vv[0], $(target).combo_ciho('getText'));
        }
    }

    /**
    * set value
    */
    function setValue(target, value) {
        var opts = $.data(target, 'combobox').options;
        var v = value;
        if (typeof value == 'object') {
            v = value[opts.valueField];
        }
        setValues(target, [v]);
    }

    function transformData(target) {
        var opts = $.data(target, 'combobox').options;
        var data = [];
        $('>option', target).each(function () {
            var item = {};
            item[opts.valueField] = $(this).attr('value') || $(this).html();
            item[opts.textField] = $(this).html();
            item['selected'] = $(this).attr('selected');
            data.push(item);
        });
        return data;
    }

    /**
    * load data, the old list items will be removed.
    */
    function loadData(target, data) {
        var opts = $.data(target, 'combobox').options;
        var layoutpanel = $(target).combo_ciho('layoutpanel');

        $.data(target, 'combobox').data = data;

        //combobox自适应高度
        if (data.length != 0) {
            var iHeight = getComHeight(data);
            $(target).combo_ciho({
                panelHeight: iHeight
            });
            opts.panelHeight = iHeight;
        }

        var selected = [];
        layoutpanel.empty(); // clear old data
        for (var i = 0; i < data.length; i++) {
            var item = $('<div class="combobox-item"></div>').appendTo(layoutpanel);
            item.attr('title', $("<font>" +data[i][opts.textField] + "<font>").text());
            item.attr('value', data[i][opts.valueField]);
            item.html(data[i][opts.textField]);
            if (data[i]['selected']) {
                selected.push(data[i][opts.valueField]);
            }
        }
        if (opts.multiple) {
            setValues(target, selected);
        } else {
            if (selected.length) {
                setValues(target, [selected[0]]);
            } else {
                setValues(target, []);
            }
        }

        opts.onLoadSuccess.call(target, data);

        //设置下拉框中，添加基本信息项的字体颜色
       // layoutpanel.find("div.combobox-item[value='-1']").css("color", "red");

        $('.combobox-item', layoutpanel).hover(
			function () { $(this).addClass('combobox-item-hover'); },
			function () { $(this).removeClass('combobox-item-hover'); }
		).click(function () {
		    var item = $(this);
		    if (opts.multiple) {
		        if (item.hasClass('combobox-item-selected')) {
		            unselect(target, item.attr('value'));
		        } else {
		            select(target, item.attr('value'));
		        }
		    } else {
		        select(target, item.attr('value'));
		    }
		});
    }

    /**
    * request remote data if the url property is setted.
    */
    function request(target, url) {
        var opts = $.data(target, 'combobox').options;
        if (url) {
            opts.url = url;
        }
        if (!opts.url) return;

        $.ajax({
            url: opts.url,
            dataType: 'json',
            success: function (data) {
                loadData(target, data);
            },
            error: function () {
                opts.onLoadError.apply(this, arguments);
            }
        })
    }

    function filter(target, query) {
        $(target).combo_ciho('showPanel');
        var data = $.data(target, 'combobox').data;
        var layoutpanel = $(target).combo_ciho('layoutpanel');
        setValues(target, [], true);
        //设定第一项选中
        var bFirst = true;
        var i = 0;
        layoutpanel.find('div.combobox-item').each(function () {
            var item = $(this);
            if (item.text().indexOf(query) >= 0) {

                item.show();
                if (bFirst) {
                    bFirst = false;
                    item.addClass('combobox-item-selected');
                }
            }
            else if (data[i]["jc"] != null && data[i]["jc"].toString().indexOf(query) >= 0) {
                item.show();
                //if (data[i]["jc"] == query) {
                if (bFirst) {
                    bFirst = false;
                    item.addClass('combobox-item-selected');
                }
            }
            else if (data[i]["jp"] != null && data[i]["jp"].toString().toUpperCase().indexOf(query.toUpperCase()) >= 0) {
                item.show();
                //if (data[i]["jp"] == query) {
                if (bFirst) {
                    bFirst = false;
                    item.addClass('combobox-item-selected');
                }
            }
            else if (data[i]["newbh"] != null && data[i]["newbh"].toString().indexOf(query) >= 0) {
                item.show();
                //if (data[i]["newbh"] == query) {
                if (bFirst) {
                    bFirst = false;
                    item.addClass('combobox-item-selected');
                }
            }
            else {
                item.hide();
            }
            //选中
            if (item.text() == query) {
                setValues(target, [item.attr("value")]);
                item.addClass('combobox-item-selected');
            }
            i++;
        });
    }

    function create(target) {
        var opts = $.data(target, 'combobox').options;
        $(target).combo_ciho(opts);
    }

    /**
    * parse options from markup.
    */
    function parseOptions(target) {
        var t = $(target);
        return $.extend({}, t.combo_ciho('parseOptions'), {
            valueField: t.attr('valueField'),
            textField: t.attr('textField'),
            url: t.attr('url')
        });
    }

    $.fn.combobox = function (options, param) {
        if (typeof options == 'string') {
            var method = $.fn.combobox.methods[options];
            if (method) {
                return method(this, param);
            } else {
                return this.combo_ciho(options, param);
            }
        }

        options = options || {};
        return this.each(function () {
            var state = $.data(this, 'combobox');
            if (state) {
                $.extend(state.options, options);
                create(this);
            } else {
                state = $.data(this, 'combobox', {
                    options: $.extend({}, $.fn.combo_ciho.defaults, $.fn.combobox.defaults, parseOptions(this), options)
                });
                create(this);
                loadData(this, transformData(this));
            }
            if (state.options.data) {
                loadData(this, state.options.data);
            }
            request(this);
        });
    };


    $.fn.combobox.methods = {
        parseOptions: function (jq) {
            return parseOptions(jq[0]);
        },
        options: function (jq) {
            return $.data(jq[0], 'combobox').options;
        },
        getData: function (jq) {
            return $.data(jq[0], 'combobox').data;
        },
        setValues: function (jq, values) {
            return jq.each(function () {
                setValues(this, values);
            });
        },
        setValue: function (jq, value) {
            return jq.each(function () {
                setValue(this, value);
            });
        },
        loadData: function (jq, data) {
            return jq.each(function () {
                loadData(this, data);
            });
        },
        reload: function (jq, url) {
            return jq.each(function () {
                request(this, url);
            });
        },
        select: function (jq, value) {
            return jq.each(function () {
                select(this, value);
            });
        },
        unselect: function (jq, value) {
            return jq.each(function () {
                unselect(this, value);
            });
        }
    };

    $.fn.combobox.defaults = {
        valueField: 'value',
        textField: 'text',
        url: null,
        data: null,

        selectPrev: function () { selectPrev(this); },
        selectNext: function () { selectNext(this); },
        selectCurr: function () { selectCurr(this); },
        filter: function (query) { filter(this, query); },

        onLoadSuccess: function () { },
        onLoadError: function () { },
        onSelect: function (record) { },
        onUnselect: function (record) { },
        afterChange: function (newValue, newText) { }
    };
})(jQuery);