	(function($) {

	    $.suggest = function(input, options) {

	        var $input = $(input).attr("autocomplete", "off");
	        var $results;

	        var timeout = false; 	// hold timeout ID for suggestion results to appear	
	        var prevLength = 0; 		// last recorded length of $input.val()
	        var cache = []; 			// cache MRU list
	        var cacheSize = 0; 		// size of cache in chars (bytes?)

	        if ($.trim($input.val()) == '' || $.trim($input.val()) == options.tip_Labels.defa) { $input.val(options.tip_Labels.defa).css('color', '#aaa'); $(options.btnObject).attr("disabled", true); }
	        if (!options.attachObject)
	            options.attachObject = $(document.createElement("ul")).appendTo('body');

	        $results = $(options.attachObject);
	        $results.addClass(options.resultsClass);

	        resetPosition();
	        $(window)
				.load(resetPosition)		// just in case user is changing size of page while loading
				.resize(resetPosition);

	        $input.blur(function() {

	            setTimeout(function() { $results.hide() }, 200);

	            if ($.trim($(this).val()) == '' || $.trim($(this).val()) == options.tip_Labels.defa) {
	                $(this).val(options.tip_Labels.defa).css('color', '#aaa');
	            }

	            selectCurrentResult();
	        });

	        $input.focus(function() {
	            resetPosition();
	            if ($.trim($(this).val()) == options.tip_Labels.defa) {
	                $(this).val('').css('color', '#000');
	            }
	            if ($.trim($(this).val()) == '') {
	                displayItems(''); //显示热门城市列表
	            }
	        });
	        $input.click(function() {
	            var q = $.trim($(this).val());
	            displayItems(q);
	            $(this).select();
	        });

	        // help IE users if possible
	        try {
	            $results.bgiframe();
	        } catch (e) { }

	        $input.keyup(processKey); //

	        function resetPosition() {
	            // requires jquery.dimension plugin
	            var offset = $input.offset();
	            $results.css({
	                top: (offset.top + input.offsetHeight) + 'px',
	                left: offset.left + 'px'
	            });
	        }


	        function processKey(e) {
	            //alert(e.keyCode);
	            if (/8$/.test(e.keyCode))
	                prevLength = -1;
	            // handling up/down/escape requires results to be visible
	            // handling enter/tab requires that AND a result to be selected
	            if ((/27$|38$|40$/.test(e.keyCode) && $results.is(':visible')) ||
					(/^13$|^9$/.test(e.keyCode) && getCurrentResult())) {

	                if (e.preventDefault)
	                    e.preventDefault();
	                if (e.stopPropagation)
	                    e.stopPropagation();

	                e.cancelBubble = true;
	                e.returnValue = false;

	                switch (e.keyCode) {

	                    case 38: // up
	                        prevResult();
	                        break;

	                    case 40: // down
	                        nextResult();
	                        break;
	                    case 13: // return
	                        selectCurrentResult();
	                        break;

	                    case 27: //	escape
	                        $results.hide();
	                        break;
	                }

	            } else if ($input.val().length != prevLength) {
	                if (timeout)
	                    clearTimeout(timeout);
	                timeout = setTimeout(suggest, options.delay);
	                prevLength = $input.val().length;

	            }


	        }

	        function suggest() {

	            var q = $.trim($input.val());
	            displayItems(q);
	        }


	        function displayItems(items) {

	            if (items == options.tip_Labels.defa) {
	                items = "";
	                $input.val('');
	            }
	            var html = '';
	            if (items == '') {//热门城市遍历
				var count=0;
	                for (h in options.hot_list) {
	                    if(!isNaN(parseInt(h))&&count<10)
						{
							count++;
	                        html += '<li rel="' + options.hot_list[h].key + '" link="' + options.hot_list[h].link + '"><a href="#' + h + '"><span>' + options.hot_list[h].fullcode + '</span>' + options.hot_list[h].key + '</a></li>';
						}
	                }
	                html = '<div class="gray ac_result_tip">' + options.tip_Labels.title + ' ' + options.tip_Labels.desc + '</div><ul>' + html + '</ul>';
	            }
	            else {
	                /*if (!items)
	                return;
	                if (!items.length) {
	                $results.hide();
	                return;
	                }*/
	                //alert(options.source.length);

	                var num = 1;

	                for (var i = 0; i < options.source.length; i++) {//国内城市匹配
	                    var reg = new RegExp('^' + items + '.*$', 'im');

	                    //items.replace('\\', '');

	                    var temp = new RegExp(items.replace('\\', ''), 'im'); // exec
	                    var strInKey = options.source[i].key.replace(temp, "<font style='color:red'>" + temp.exec(options.source[i].key) + "</font>");
	                    var strInShortCode = options.source[i].shortcode.replace(temp, "<font style='color:red'>" + temp.exec(options.source[i].shortcode) + "</font>");
	                    var strInFullCode = options.source[i].fullcode.replace(temp, "<font style='color:red'>" + temp.exec(options.source[i].fullcode) + "</font>");

	                    //str = Regex.Replace(str, items, "$1", RegexOptions.IgnoreCase);

	                    var str = strInFullCode;
	                    if (reg.test(options.source[i].shortcode)) {
	                        str = strInShortCode;
	                    }
	                    if (reg.test(options.source[i].key) || reg.test(options.source[i].shortcode) || reg.test(options.source[i].fullcode)) {
	                        html += '<li rel="' + options.source[i].key + '" link="' + options.source[i].link + '"><a href="#' + i + '"><span>' + str + '</span>' + strInKey + '</a></li>';
	                        num++;
	                    }
	                    if (num > 8) {
	                        break;
	                    }
	                }
	                if (html == '') {

	                    $(options.btnObject).attr("disabled", true);

	                    suggest_tip = '<div class="gray ac_result_tip">对不起，找不到：' + items + '</div>';
	                }
	                else {
	                    $(options.btnObject).attr("disabled", false);

	                    suggest_tip = '<div class="gray ac_result_tip">' + items + '，' + options.tip_Labels.desc + '</div>';
	                }
	                html = suggest_tip + '<ul>' + html + '</ul>';
	            }

	            $results.html(html).show();
	            $results.children('ul').children('li:first-child').addClass(options.selectClass);

	            $results.children('ul')
					.children('li')
					.mouseover(function() {
					    $results.children('ul').children('li').removeClass(options.selectClass);
					    $(this).addClass(options.selectClass);
					})
					.click(function(e) {
					    e.preventDefault();
					    e.stopPropagation();
					    selectCurrentResult();
					});
	        }

	        function getCurrentResult() {

	            if (!$results.is(':visible'))
	                return false;

	            var $currentResult = $results.children('ul').children('li.' + options.selectClass);
	            if (!$currentResult.length)
	                $currentResult = false;

	            return $currentResult;

	        }

	        function selectCurrentResult() {

	            $currentResult = getCurrentResult();

	            if ($currentResult) {

	                //$input.val($currentResult.children('a').html().replace(regEx, ""));
	                //	                var regEx = /<[^>]*>/g;
	                //	                $input.val($currentResult.html().replace(/<span>.+?<\/span>/i, '').replace(regEx, ""));
	                $input.val($currentResult.attr('rel'))
	                $input.attr("link", $currentResult.attr('link'));

	                $results.hide();

	                if ($input.val() != options.tip_Labels.defa) {
	                    $input.css('color', '#000');
	                }

	                if (options.onSelect) {
	                    options.onSelect.apply($input[0]);
	                }
	            }

	        }

	        function nextResult() {

	            $currentResult = getCurrentResult();

	            if ($currentResult)
	                $currentResult
						.removeClass(options.selectClass)
						.next()
							.addClass(options.selectClass);
	            else
	                $results.children('ul').children('li:first-child').addClass(options.selectClass);

	        }

	        function prevResult() {

	            $currentResult = getCurrentResult();

	            if ($currentResult)
	                $currentResult
						.removeClass(options.selectClass)
						.prev()
							.addClass(options.selectClass);
	            else
	                $results.children('ul').children('li:last-child').addClass(options.selectClass);

	        }

	    }

	    $.fn.suggest = function(source, options) {

	        if (!source)
	            return;

	        options = options || {};
	        options.source = source;
	        options.hot_list = options.hot_list || [];
	        options.delay = options.delay || 0;
	        options.resultsClass = options.resultsClass || 'ac_results';
	        options.selectClass = options.selectClass || 'ac_over';
	        options.matchClass = options.matchClass || 'ac_match';
	        options.minchars = options.minchars || 1;
	        options.delimiter = options.delimiter || '\n';
	        options.onSelect = options.onSelect || false;
	        options.dataDelimiter = options.dataDelimiter || '\t';
	        options.dataContainer = options.dataContainer || '#SuggestResult';
	        options.attachObject = options.attachObject || null;


	        $(options.btnObject).attr("disabled", true);

	        this.each(function() {
	            new $.suggest(this, options);
	        });

	        return this;

	    };

	})(jQuery);
