
/*
*	jquery.suggest 1.1 - 2007-08-06
*
*	Uses code and techniques from following libraries:
*	1. http://www.dyve.net/jquery/?autocomplete
*	2. http://dev.jquery.com/browser/trunk/plugins/interface/iautocompleter.js
*
*	All the new stuff written by Peter Vulgaris (www.vulgarisoip.com)
*	Feel free to do whatever you want with this file
*    
*   修改 skey 2008-07-14
*   修正在输入法下无法显示自动提示的问题
*   修正在IE和FF和safari以及opear的兼容性问题
*   修正按住向下键不能连续选择的问题
*/

(function($) {

	$.suggest = function(input, options) {

		var $input = $(input).attr("autocomplete", "off");
		var $results = $(document.createElement("ul"));

		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?)

        $('#Csuggest').html($results.addClass(options.resultsClass));
		//$results.addClass(options.resultsClass).appendTo('body');


		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 ($.browser.mozilla || $.browser.safari || $.browser.opera){
			//addEventListenser触发修复输入法状态下的BUG
			$input.get(0).addEventListener("input",processKey,false);
		}
		else{
			//attachEvent触发修复输入法状态下的BUG
			$input.get(0).attachEvent('onpropertychange',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() {			
			//Firefox浏览器
			if ($.browser.mozilla ||$.browser.safari){
				$(input).keydown(pressdown);

				if ($input.val().length != prevLength) {
					if (timeout)
					clearTimeout(timeout);
					timeout = setTimeout(suggest, options.delay);
					prevLength = $input.val().length;
				}
			}
			//IE浏览器
			else{
				if ($input.val().length != prevLength) {
					if (timeout)
					clearTimeout(timeout);
					timeout = setTimeout(suggest, options.delay);
					prevLength = $input.val().length;

				}else{

					document.getElementById("keyword").attachEvent('onkeydown',pressdown);

				}
			}

		}

        //
		function pressdown(e){

			if (!$.browser.mozilla){
				e = window.event
			}
			// 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 9:  // tab
					case 13: // return
					selectCurrentResult();
					break;

					case 27: //	escape
					$results.hide();
					break;

				}

			}
		}

		function suggest() {

			var q = $.trim($input.val());

			if (q.length >= options.minchars) {

				cached = checkCache(q);

				if (cached) {

					displayItems(cached['items']);

				} else {

					$.get(options.source, {q: q}, function(txt) {

						$results.hide();

						var items = parseTxt(txt, q);

						displayItems(items);
						addToCache(q, items, txt.length);

					});

				}

			} else {

				$results.hide();

			}

		}


		function checkCache(q) {

			for (var i = 0; i < cache.length; i++)
			if (cache[i]['q'] == q) {
				cache.unshift(cache.splice(i, 1)[0]);
				return cache[0];
			}

			return false;

		}

		function addToCache(q, items, size) {

			while (cache.length && (cacheSize + size > options.maxCacheSize)) {
				var cached = cache.pop();
				cacheSize -= cached['size'];
			}

			cache.push({
				q: q,
				size: size,
				items: items
			});

			cacheSize += size;

		}

		function displayItems(items) {

			if (!items)
			return;

			if (!items.length) {
				$results.hide();
				return;
			}

			var html = '';
			for (var i = 0; i < items.length; i++)
			{
				tmp=items[i].split("[id]");
				id=tmp[1];
			    html += '<li onclick="location.href=\'http://www.xiazaiba.com/downinfo/'+ tmp[1]+'.html\'" id="'+tmp[1]+'">'+tmp[0] +'</li>';
			}
			$results.html(html).show();

			$results
			.children('li')
			.mouseover(function() {
				$results.children('li').removeClass(options.selectClass);
				$(this).addClass(options.selectClass);
			})
			.click(function(e) {
				e.preventDefault();
				e.stopPropagation();
				selectCurrentResult();
			});

		}

		function parseTxt(txt, q) {

			var items = [];
			var tokens = txt.split(options.delimiter);

			// parse returned data for non-empty items
			for (var i = 0; i < tokens.length; i++) {
				var token = $.trim(tokens[i]);
				if (token) {
					token = token.replace(
					new RegExp(q, 'ig'),
					function(q) { return '<span class="' + options.matchClass + '">' + q + '</span>' }
					);
					items[items.length] = token;
				}
			}

			return items;
		}

		function getCurrentResult() {

			if (!$results.is(':visible'))
			return false;

			var $currentResult = $results.children('li.' + options.selectClass);

			if (!$currentResult.length)
			$currentResult = false;

			return $currentResult;

		}
	 
		function selectCurrentResult() {

			$currentResult = getCurrentResult();

			if ($currentResult) {
				$input.val($currentResult.text());
				$results.hide();
                 if ($currentResult.attr("id")!="undefined")
                 {
					 location.href='http://www.xiazaiba.com/downinfo/'+$currentResult.attr("id")+'.html';
                 }
				//if (options.onSelect)
				//options.onSelect.apply($input[0]);

			}
			return false;

		}

		function nextResult() {

			$currentResult = getCurrentResult();

			if ($currentResult)
			$currentResult
			.removeClass(options.selectClass)
			.next()
			.addClass(options.selectClass);
			else
			$results.children('li:first-child').addClass(options.selectClass);

		}

		function prevResult() {

			$currentResult = getCurrentResult();

			if ($currentResult)
			$currentResult
			.removeClass(options.selectClass)
			.prev()
			.addClass(options.selectClass);
			else
			$results.children('li:last-child').addClass(options.selectClass);

		}

	}

	$.fn.suggest = function(source, options) {

		if (!source)
		return;

		options = options || {};
		options.source = source;
		options.delay = options.delay || 100;
		options.resultsClass = options.resultsClass || 'ac_results';
		options.selectClass = options.selectClass || 'ac_over';
		options.matchClass = options.matchClass || 'ac_match';
		options.minchars = options.minchars || 2;
		options.delimiter = options.delimiter || '\n';
		options.onSelect = options.onSelect || false;
		options.maxCacheSize = options.maxCacheSize || 65536;

		this.each(function() {
			new $.suggest(this, options);
		});

		return this;

	};

})(jQuery);


