﻿/*
* jQuery UI Autocomplete 1.7.2
*
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI/Autocomplete
*
* Depends:
*	ui.core.js
*/

(function ($) {

    $.extend($.ui, { autocomplete: { version: "1.7.2"} });

    var PROP_NAME = 'autocomplete';

    function Autocomplete() {
        this._mainDivId = 'ui-autocomplete-div';
        this._currPage = 1;
        this._totalPages = 1;

        this.regional = [];
        this.regional[''] = {
            defaultText: "输入中文/拼音或↑↓选择.",
            queryText: "<span>{0}</span> ,按拼音排序",
            notFoundText: "对不起, 找不到: <span>{0}</span>",
            pageText: "←→翻页, 共<span>{0}</span>项, 共<span>{1}</span>页"
        };
        this._defaults = {
            //Config
            remoteData: null,
            localData: null,
            dataFormat: null,
            itemFormat: null,
            dataFilter: null,
            pageSize: 10,
            timeout: 6000,
            defaultClientSort: true,
            clientSort: true,
            clientCache: false,
            asyncCache: false,
            fixedInput: true,

            //Event
            onBeforShow: null,
            onShow: null,
            onClose: null,
            onSelect: null
        };

        $.extend(this._defaults, this.regional['']);
        this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-autocomplete ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>');
    }

    $.extend(Autocomplete.prototype, {
        markerClassName: 'hasAutocomplete',

        /* Debug logging (if enabled). */
        log: function () {
            if (this.debug)
                console.log.apply('', arguments);
        },

        _get: function (inst, name) {
            return inst.settings[name] !== undefined ?
			inst.settings[name] : this._defaults[name];
        },

        _newInst: function (target) {
            var id = target[0].id.replace(/([:\[\]\.])/g, '\\\\$1'); // escape jQuery meta chars
            return {
                id: id,
                input: target,
                queryText: 'empty',
                data: [],
                filterData: [],
                dpDiv: this.dpDiv
            };
        },

        _getInst: function (target) {
            try {
                return $.data(target, PROP_NAME);
            }
            catch (err) {
                throw 'Missing instance data for this autocomplete';
            }
        },

        _attachAutocomplete: function (target, settings) {

            var nodeName = target.nodeName.toLowerCase();

            if (!target.id)
                target.id = 'dp' + (++this.uuid);
            var inst = this._newInst($(target));
            inst.settings = $.extend({}, settings || {});
            if (nodeName == 'input' || nodeName == 'textarea') {
                var $input = $(inst.input).attr("autocomplete", "off");
                this._connectAutocomplete(target, inst);
            }
        },

        /* Attach the date picker to an input field. */
        _connectAutocomplete: function (target, inst) {
            var input = $(target);
            inst.append = $([]);
            inst.trigger = $([]);
            if (input.hasClass(this.markerClassName))
                return;


            input.focus(this._asyncAutocomplete);
            input.click(this._asyncAutocomplete);

            input.addClass(this.markerClassName).keydown(this._doKeyDown).keyup(this._doKeyUp).
			bind("setValue.autocomplete", function (event, key, value) {
			    inst.settings[key] = value;
			}).bind("getValue.autocomplete", function (event, key) {
			    return this._get(inst, key);
			});
            $.data(target, PROP_NAME, inst);
        },

        _asyncAutocomplete: function (input) {
            input = input.target || input;
            var inst = $.autocomplete._getInst(input);
            var queryText = encodeURIComponent($(input).val());
            var onBeforeShow = $.autocomplete._get(inst, 'onBeforeShow');
            var beforeShowReturnValue = true;
            if (onBeforeShow)
                beforeShowReturnValue = onBeforeShow.apply((inst.input ? inst.input[0] : null),
				[(inst.input ? inst.input.val() : ''), inst]);
            if (beforeShowReturnValue === false)
                return;

            if ($.autocomplete._animing)
                return;
            else if ($.autocomplete._lastInput == input && $.autocomplete._autocompleteShowing && queryText == inst.queryText) // already here
                return;
            else if ($.autocomplete._lastInput != input)
                $.autocomplete._hideAutocomplete(null, '');


            inst.queryText = queryText;
            var remoteData = $.autocomplete._get(inst, 'remoteData');
            var localData = $.autocomplete._get(inst, 'localData');

            if (remoteData != null) {
                var url = typeof remoteData == 'string' ? remoteData + queryText
				: remoteData.apply(input, [queryText, inst]);
                var timeout = $.autocomplete._get(inst, 'timeout');
                var asyncCache = $.autocomplete._get(inst, 'asyncCache');
                var clientCache = $.autocomplete._get(inst, 'clientCache');
                var dataFormat = $.autocomplete._get(inst, 'dataFormat');
                if (clientCache && $.isArray(inst.data) && inst.data.length > 0) {

                    $.autocomplete._showAutocomplete.call($.autocomplete, input);
                    return;
                }

                $.ajax({
                    type: "GET",
                    url: url,
                    data: "",
                    dataType: "text",
                    timeout: timeout,
                    cache: asyncCache,
                    success: function (msg) {
                        var data = dataFormat == null ? $.autocomplete._dataFormat(input, msg) : dataFormat(input, msg);
                        inst.filterData = inst.data = data;

                        $.autocomplete._showAutocomplete.call($.autocomplete, input);
                    },
                    error: function (textStatus, errorThrown) {
                        //alert('服务器忙,请重试...');
                    }
                });
            } else if (localData != null) {
                var data = $.isArray(localData) ? localData : ($.isFunction(localData) ? localData.call(input, [queryText, inst]) : []);
                if (typeof data == 'string')
                    data = dataFormat == null ? $.autocomplete._dataFormat(input, _localData) : dataFormat(input, _localData);
                inst.filterData = inst.data = data;
                $.autocomplete._showAutocomplete.call($.autocomplete, input);
            }
        },

        _showAutocomplete: function (input) {

            $.autocomplete._currPage = 1;
            var inst = $.autocomplete._getInst(input);

            if (!$.autocomplete._pos) { // position below input
                $.autocomplete._pos = $.autocomplete._findPos(input);
                $.autocomplete._pos[1] += input.offsetHeight; // add the height
            }
            var isFixed = false;
            $(input).parents().each(function () {
                isFixed |= $(this).css('position') == 'fixed';
                return !isFixed;
            });
            if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
                $.autocomplete._pos[0] -= document.documentElement.scrollLeft;
                $.autocomplete._pos[1] -= document.documentElement.scrollTop;
            }
            var offset = { left: $.autocomplete._pos[0], top: $.autocomplete._pos[1] };
            $.autocomplete._pos = null;
            inst.rangeStart = null;
            // determine sizing offscreen
            inst.dpDiv.css({ position: 'absolute', display: 'block', top: '-1000px' });
            $.autocomplete._updateAutocomplete(inst);
            // fix width for dynamic number of date pickers
            // and adjust position before showing
            offset = $.autocomplete._checkOffset(inst, offset, isFixed);

            inst.dpDiv.css({ position: isFixed ? 'fixed' : 'absolute', display: 'none',
                left: offset.left + 'px', top: ($(input).position().top + input.offsetHeight) + 'px'
            });
            var showAnim = $.autocomplete._get(inst, 'showAnim') || 'show';
            var duration = $.autocomplete._get(inst, 'duration') || ($.autocomplete._autocompleteShowing ? '' : 'normal');

            var postProcess = function () {
                $.autocomplete._animing = false;
                $.autocomplete._autocompleteShowing = true;
                if ($.browser.msie && parseInt($.browser.version, 10) < 7) // fix IE < 7 select problems
                    $('iframe.ui-autocomplete-cover').css({ width: inst.dpDiv.width() + 4,
                        height: inst.dpDiv.height() + 4
                    });

                var onShow = $.autocomplete._get(inst, 'onShow');
                if (onShow)
                    onShow.apply((inst.input ? inst.input[0] : null),
					[(inst.input ? inst.input.val() : ''), inst]);
            };
            $.autocomplete._animing = true;
            if ($.effects && $.effects[showAnim])
                inst.dpDiv.show(showAnim, $.autocomplete._get(inst, 'showOptions'), duration, postProcess);
            else
                inst.dpDiv[showAnim](duration, postProcess);
            if (duration == '')
                postProcess();
            if (inst.input[0].type != 'hidden')
                inst.input[0].focus();
            $.autocomplete._lastInput = input;
            $.autocomplete._curInst = inst;

        },

        /* Generate the date picker content. */
        _updateAutocomplete: function (inst) {
            var dims = { width: inst.dpDiv.width() + 4,
                height: inst.dpDiv.height() + 4
            };
            var self = this;
            inst.dpDiv.empty().append(this._generateHTML(inst))
			.find('iframe.ui-autocomplete-cover').
				css({ width: dims.width, height: dims.height }).show()
			.end()
			.find('.ui-autocomplete-page a').click(function (event) {
			    var _goto = $(this).attr('goto');

			    $.autocomplete._currPage = _goto;
			    $.autocomplete._updateAutocomplete(inst);
			    return false;
			}).end()
			.find('.ui-autocomplete-list a').click(function (event) {
			    /*$('.ui-autocomplete-selected').removeClass('ui-autocomplete-selected');
			    inst.selectedItem = $(this);
			    $(inst.selectedItem).addClass('ui-autocomplete-selected');
			    */
			    var _index = $(this).attr('index');
			    $.autocomplete._selectItem(inst, _index);
			    return false;
			}).end()
			.click(function (event) {
			    if (inst.input && inst.input[0].type != 'hidden' && inst == $.autocomplete._curInst)
			        $(inst.input[0]).focus();
			    return false;
			});

            if (inst.input && inst.input[0].type != 'hidden' && inst == $.autocomplete._curInst)
                $(inst.input[0]).focus();

            //selectedItem
            inst.selectedItem = null; //$(inst.dpDiv).find('.ui-autocomplete-selected');
        },

        _generateHTML: function (inst) {

            var itemFormat = $.autocomplete._get(inst, 'itemFormat');
            var pagesize = $.autocomplete._get(inst, 'pageSize') || 15;
            var dataFilter = $.autocomplete._get(inst, 'dataFilter');
            var data = dataFilter == null ? this._dataFilter(inst) : dataFilter(inst);
            $.autocomplete._totalPages = Math.ceil(data.length / pagesize);

            var _defaultText = $.autocomplete._get(inst, 'defaultText');
            var _queryText = $.autocomplete._get(inst, 'queryText');
            var _notFoundText = $.autocomplete._get(inst, 'notFoundText');
            var _pageText = $.autocomplete._get(inst, 'pageText');

            var html = '<div class="ui-autocomplete-message">';
            if (inst.input.val() == '') {
                html += _defaultText;
            } else if (!data || data.length <= 0) {
                html += this._textFormat(_notFoundText, decodeURIComponent(inst.queryText));
            } else if (inst.input.val() != '') {
                html += this._textFormat(_queryText, decodeURIComponent(inst.queryText));
            }
            html += '</div>';
            html += '<div class="ui-autocomplete-list">';

            if ($.isArray(data)) {
                var isFirst = true;

                var loop = -1;
                for (var i = 0; i < data.length; i++) {
                    if (++loop < pagesize * ($.autocomplete._currPage - 1)) {
                        continue;
                    }
                    if (pagesize * $.autocomplete._currPage <= loop) {
                        break;
                    }
                    var itemHTML = itemFormat == null ? this._itemFormat(data[i]) : itemFormat(data[i]);
                    html += '<a href="#" index="' + i + '" class="ui-autocomplete-item' + (isFirst ? ' ui-autocomplete-selected' : '') + '">' + itemHTML + '</a>';
                    isFirst = false;
                }
            }
            html += '</div>';
            html += '<div class="ui-autocomplete-page">';
            var _goto = 1;
            if ($.autocomplete._totalPages > 1) {
                if ($.autocomplete._currPage > 1) {
                    _goto = parseInt($.autocomplete._currPage, 10) - 1;
                    html += '<a href="#" class="ui-autocomplete-arrowl" goto="' + _goto + '">&lt;-</a>';
                }
                var startPage = Math.max($.autocomplete._currPage - 2, 1);
                var endPage = Math.min($.autocomplete._totalPages, startPage + 4);
                for (var i = startPage; i <= endPage; i++) {
                    html += '<a href="#" class="ui-autocomplete-arrowr' + ((i == $.autocomplete._currPage) ? ' ui-autocomplete-page-current' : '') + '" goto="' + i + '">' + i + '</a>';
                }

                if ($.autocomplete._currPage != $.autocomplete._totalPages) {
                    _goto = parseInt($.autocomplete._currPage, 10) + 1;
                    html += '<a href="#" class="ui-autocomplete-arrowr" goto="' + _goto + '">-&gt;</a>';
                }
            }

            html += '<div>';
            html += this._textFormat(_pageText, data.length, $.autocomplete._totalPages);
            html += '</div>';

            html += '</div>';
            html += ($.browser.msie && parseInt($.browser.version, 10) < 7 ?
			'<iframe src="javascript:false;" class="ui-autocomplete-cover" frameborder="0"></iframe>' : '');
            return html;
        },

        /* Check positioning to remain on screen. */
        _checkOffset: function (inst, offset, isFixed) {
            var dpWidth = inst.dpDiv.outerWidth();
            var dpHeight = inst.dpDiv.outerHeight();
            var inputWidth = inst.input ? inst.input.outerWidth() : 0;
            var inputHeight = inst.input ? inst.input.outerHeight() : 0;
            var viewWidth = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) + $(document).scrollLeft();
            var viewHeight = (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) + $(document).scrollTop();
            //fixed scrollbar width
            var scrollBarWidth = $(document).scrollTop() > 0 ? 18 : 0;
            offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
            offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
            offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;

            // now check if autocomplete is showing outside window viewport - move to a better place if so.

            offset.left -= (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? Math.abs(offset.left + dpWidth - viewWidth + scrollBarWidth) : 0;
            offset.top -= (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? Math.abs(offset.top + dpHeight + inputHeight * 2 - viewHeight) : 0;

            return offset;
        },

        /* Find an object's position on the screen. */
        _findPos: function (obj) {
            while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
                obj = obj.nextSibling;
            }
            var position = $(obj).offset();
            return [position.left, position.top];
        },

        _doKeyDown: function (event) {
            if ($.autocomplete._animing) return false;

            var inst = $.autocomplete._getInst(event.target);
            var handled = true;
            inst._keyEvent = true;

            if ($.autocomplete._autocompleteShowing) {
                if (!inst.selectedItem) {
                    inst.selectedItem = $(inst.dpDiv).find('.ui-autocomplete-selected');
                }

                switch (event.keyCode) {
                    case 38: //up
                        if ($(inst.selectedItem).prev().length) {
                            $(inst.selectedItem).removeClass('ui-autocomplete-selected');
                            inst.selectedItem = inst.selectedItem.prev();
                            $(inst.selectedItem).addClass('ui-autocomplete-selected');
                        } else if ($.autocomplete._currPage > 1) {
                            $.autocomplete._currPage--;
                            $.autocomplete._updateAutocomplete(inst);
                        }
                        break;
                    case 40: //down
                        if ($(inst.selectedItem).next().length) {
                            $(inst.selectedItem).removeClass('ui-autocomplete-selected');
                            inst.selectedItem = inst.selectedItem.next();
                            $(inst.selectedItem).addClass('ui-autocomplete-selected');
                        } else if ($.autocomplete._currPage < $.autocomplete._totalPages) {
                            $.autocomplete._currPage++;
                            $.autocomplete._updateAutocomplete(inst);
                        }

                        break;
                    case 33:  //left
                    case 37:  //left
                    case 109: //left
                    case 188: //left
                    case 219: //left
                        if ($.autocomplete._currPage > 1) {
                            $.autocomplete._currPage--;
                            $.autocomplete._updateAutocomplete(inst);
                        }

                        break;
                    case 34:  //right
                    case 39:  //right
                    case 61:  //right
                    case 190: //right
                    case 221: //right
                        if ($.autocomplete._currPage < $.autocomplete._totalPages) {
                            $.autocomplete._currPage++;
                            $.autocomplete._updateAutocomplete(inst);
                        }

                        break;
                    case 9: //tab
                    case 13: //enter
                        var _index = $(inst.selectedItem).attr('index');
                        $.autocomplete._selectItem(inst, _index);
                        handled = false;
                        break;


                    case 27: //esc
                        $.autocomplete._hideAutocomplete(null, '');
                        break;

                    default:
                        handled = false;

                        break;
                }
            } else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
                $.autocomplete._showAutocomplete(this);
            else {
                handled = false;
            }
            if (handled) {
                event.preventDefault();
                event.stopPropagation();
            }
        },

        _doKeyUp: function (event) {
            var keyCode = '|' + event.keyCode + '|';
            if ('|38|40|33|37|109|188|219|34|39|61|190|221|13|'.indexOf(keyCode) == -1) {
                if ($.autocomplete._keyUpTimer) {
                    clearTimeout($.autocomplete._keyUpTimer);
                }
                $.autocomplete._keyUpTimer = setTimeout(function () {
                    $.autocomplete._currPage = 1;
                    $.autocomplete._asyncAutocomplete(event);
                }, 100);
            }
        },

        _selectItem: function (inst, index, hide) {
            hide = hide === false ? false : true;

            var selectedData = inst.filterData[index] ? inst.filterData[index] : [];
            inst.input.val(selectedData[1]);

            var onSelect = this._get(inst, 'onSelect');
            if (onSelect)
                onSelect.apply((inst.input ? inst.input[0] : null),
				[selectedData, inst]);
            if (hide)
                this._hideAutocomplete(null, 'normal', true);
        },

        _dataFilter: function (inst) {
            var clientCache = $.autocomplete._get(inst, 'clientCache');
            var localData = $.autocomplete._get(inst, 'localData');
            var data = inst.data;
            var filterData = [];

            if ((!clientCache && localData == null) || inst.queryText == '') {
                filterData = inst.filterData = data;

            } else {

                if ($.isArray(data) && data.length > 0) {
                    for (var i = 0; i < data.length; i++) {
                        var regex = new RegExp(inst.queryText.toUpperCase());
                        var regexText = encodeURIComponent(data[i].join("").toUpperCase());
                        if (regex.test(regexText)) {
                            filterData.push(data[i]);
                        }
                    }
                }
                inst.filterData = filterData;
            }
            return filterData;
        },

        _itemFormat: function (item) {

            return '<span>' + item[1] + '</span>' + item[0];
        },

        _dataFormat: function (input, data) {
            data = data.replace(/<[^>]+>/g, '').replace(/(^\s*)|(\s*$)/g, "");
            var splitData = data.split('@');
            var returnValue = [];
            for (var key in splitData) {
                if (splitData[key]) {
                    returnValue.push(splitData[key].split('|'));
                }
            }

            var val = $(input).val();
            var inst = $.autocomplete._getInst(input);
            var defaultClientSort = $.autocomplete._get(inst, 'defaultClientSort');
            var clientSort = $.autocomplete._get(inst, 'clientSort');
            if ((val == '' && defaultClientSort)
			|| (val != '' && clientSort)) {

                var fn = function (param1, param2) {
                    return $.autocomplete._dataCompare.call($.autocomplete, param1, param2);
                };
                returnValue.sort(fn);
            }

            return returnValue;
        },


        _dataCompare: function (param1, param2) {
            param1 = param1[0];
            param2 = param2[0];
            if (typeof param1 == "string" && typeof param2 == "string") {
                return param1.localeCompare(param2);
            }
            if (typeof param1 == "number" && typeof param2 == "string") {
                return -1;
            }
            if (typeof param1 == "string" && typeof param2 == "number") {
                return 1;
            }
            if (typeof param1 == "number" && typeof param2 == "number") {
                if (param1 > param2)
                    return 1;
                if (param1 == param2)
                    return 0;
                if (param1 < param2)
                    return -1;
            }
        },

        _hideAutocomplete: function (input, duration) {
            var inst = this._curInst;

            if (!inst || (input && inst != $.data(input, PROP_NAME)))
                return;
            //alert([1, this._autocompleteShowing].join(": "));

            if (this._autocompleteShowing) {
                //alert([2, this._autocompleteShowing].join(": "));
                var fixedInput = $.autocomplete._get(inst, 'fixedInput');
                if (fixedInput && inst.input.val() != '' && arguments.length < 3) {
                    var _index = $(inst.dpDiv).find('.ui-autocomplete-selected').attr('index');
                    $.autocomplete._selectItem(inst, _index, false);
                }
                //alert([3, this._autocompleteShowing].join(": "));

                duration = (duration != null && duration != '' ? duration : '');
                var showAnim = $.autocomplete._get(inst, 'showAnim') || 'show';

                var postProcess = function () {
                    var onClose = $.autocomplete._get(inst, 'onClose');
                    if (onClose)
                        onClose.apply((inst.input ? inst.input[0] : null),
						[(inst.input ? inst.input.val() : ''), inst]);
                };
                var method = (duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' :
					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide')));
                //alert([duration, method]);
                //if (duration != '' && $.effects && $.effects[showAnim])
                //	inst.dpDiv.hide(showAnim, $.autocomplete._get(inst, 'showOptions'),
                //		duration, postProcess);
                //else
                inst.dpDiv[method](duration, postProcess);

                this._autocompleteShowing = false;
                try { this._lastInput.blur(); } catch (e) { }
                this._lastInput = null;
            }
            this._curInst = null;

        },

        /* Close date picker if clicked elsewhere. */
        _checkExternalClick: function (event) {
            if (!$.autocomplete._curInst)
                return;
            var $target = $(event.target);
            if (($target.parents('#' + $.autocomplete._mainDivId).length == 0) &&
				!$target.hasClass($.autocomplete.markerClassName) &&
				$.autocomplete._autocompleteShowing)
                $.autocomplete._hideAutocomplete(null, '');
        },
        _textFormat: function (format) {
            var args = $.makeArray(arguments).slice(1);
            return format.replace(/\{(\d+)\}/g, function (m, i) {
                return args[i];
            });
        }
    });

    $.fn.autocomplete = function (options) {

        if (!$.autocomplete.initialized) {
            $(document).mousedown($.autocomplete._checkExternalClick).
			find('body').append($.autocomplete.dpDiv);
            $.autocomplete.initialized = true;
        }

        var otherArgs = Array.prototype.slice.call(arguments, 1);
        if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
            return $.autocomplete['_' + options + 'Autocomplete'].
			apply($.autocomplete, [this[0]].concat(otherArgs));
        return this.each(function () {
            typeof options == 'string' ?
			$.autocomplete['_' + options + 'Autocomplete'].
				apply($.autocomplete, [this].concat(otherArgs)) :
			$.autocomplete._attachAutocomplete(this, options);
        });
    };

    $.autocomplete = new Autocomplete();
    $.autocomplete.initialized = false;
    $.autocomplete.uuid = new Date().getTime();
    $.autocomplete.version = "1.7.2";

    window.DP_jQuery = $;

})(jQuery);

