/*	jquery.item-suggest 1.0 - 2009-01-16 -- by ddunlop.com
 *	based on Peter Vulgaris's (www.vulgarisoip.com) jquery.suggest
 */

(function($) {
	$.suggest = function(input, options) {
		var t = this;
		t.input = input;
		t.options = options;
		t.$input = $(input).attr("autocomplete", "off");
		t.$results = $(document.createElement("ul"));
		t.currentItem = -1;
		t.items = false;

		t.timeout = false;	// hold timeout ID for suggestion results to appear
		t.prevLength = 0;	// last recorded length of $input.val()
		t.cache = [];		// cache MRU list
		t.cacheSize = 0;	// size of cache in chars (bytes?)

		t.$results.addClass(t.options.resultsClass).appendTo('body');

		t.resetPosition();
		$(window)
			.load(function() { t.resetPosition() })		// just in case user is changing size of page while loading
			.resize(function() { t.resetPosition() });

		t.$input.blur(function() {
			setTimeout(function() {
				t.hideResults();
			}, 200);
		});

		// help IE users if possible
		try {
			t.$results.bgiframe();
		} catch(e) { }

		// I really hate browser detection, but I don\'t see any other way
		if ($.browser.mozilla)
			t.$input.keypress(function(e) { t.processKey(e); });	// onkeypress repeats arrow keys in Mozilla/Opera
		else
			t.$input.keydown(function(e) { t.processKey(e); });	// onkeydown repeats arrow keys in IE/Safari

	}

$.extend($.suggest.prototype, {
	addMatchClass:function(txt,q) {
		return txt.replace(new RegExp(q, 'ig'), '<span class="'+this.options.matchClass+'">$&</span>');
	},
	resetPosition:function() {
		var offset = this.$input.offset();
		this.$results.css({
			top: (offset.top + this.input.offsetHeight) + 'px',
			left: offset.left + 'px'
		});
	},
	processKey:function(e) {
		// 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) && this.$results.is(':visible')) ||
			(/^13$|^9$/.test(e.keyCode) && this.currentItem>=0)) {

			if (e.preventDefault) e.preventDefault();
			if (e.stopPropagation) e.stopPropagation();

			e.cancelBubble = true;
			e.returnValue = false;

			switch(e.keyCode) {
				case 38: // up
					this.selectItem(this.currentItem-1);
					break;
				case 40: // down
					this.selectItem(this.currentItem+1);
					break;
				case 9:  // tab
				case 13: // return
					this.selectCurrentItem();
					break;
				case 27: //	escape
					this.hideResults();
					break;

			}
		} else if (this.$input.val().length != this.prevLength) {
			var t=this;
			if (t.timeout)
				clearTimeout(t.timeout);
			t.timeout = setTimeout(function() { t.suggest() }, t.options.delay);
			t.prevLength = t.$input.val().length;
		}
	},
	suggest:function() {
		var q = $.trim(this.$input.val());

		if (q.length >= this.options.minchars) {
			cached = this.checkCache(q);

			if (cached) {
				this.items = cached['items'];
				this.displayItems(q);
			} else {
				var t = this;
				$.get(t.options.source, {q: q}, function(txt) {
					t.hideResults();

					t.items = t.options.createItems?t.options.createItems.call(this,txt):txt.split(t.options.delimiter);

					t.displayItems(q);
					t.addToCache(q, txt.length);
				});
			}
		} else {
			this.hideResults();
		}
	},
	checkCache:function(q) {
		for (var i = 0; i < this.cache.length; i++)
			if (this.cache[i]['q'] == q) {
				this.cache.unshift(this.cache.splice(i, 1)[0]); // add to front to implement LRU
				return this.cache[0];
			}
		return false;
	},
	addToCache:function(q, size) {
		while (this.cache.length && (this.cacheSize + size > this.options.maxCacheSize)) {
			var cached = this.cache.pop();
			this.cacheSize -= cached['size'];
		}

		this.cache.push({
			q:q,
			size:size,
			items:this.items
			});
		this.cacheSize += size;
	},
	displayItems:function(q) {
		var t = this;
		if (!t.items) return;

		var html = '';
		for (var i = 0; i < t.items.length; i++) {
			var item = t.options.formatItem?t.options.formatItem.call(t,t.items[i],q):t.formatItem(t.items[i],q);
			if(!item) t.items.splice(i,1); // remove false items
			else html+=item;
		}

		if (!t.items.length) {
			t.hideResults();
			return;
		}

		t.$results.html(html).show().children()
			.mouseover(function() {
				var $items = t.$results.children();
				for(var i=0;i<$items.length;i++) if($items[i]==this) break;
				t.selectItem(i);
			})
			.click(function(e) {
				t.selectCurrentItem();
				return false;
			});
	},
	formatItem:function(txt,q) {
		txt=$.trim(txt);
		if(txt) return '<li>'+this.addMatchClass(txt,q)+'</li>';
		return false;
	},
	hideResults:function() {
		this.$results.hide();
		this.currentItem=-1;
	},
	selectItem:function(i) {
		if(i<0) i=this.items.length-1;
		if(i>=this.items.length) i=0;
		this.currentItem=i;
		this.$results.children().removeClass(this.options.selectClass).eq(i).addClass(this.options.selectClass);
	},
	selectCurrentItem:function() {
		if (this.currentItem>=0) {
			var item = this.currentItem;
			this.$input.val(this.options.selectItemText?this.options.selectItemText.call(this,this.items[item]):this.$results.children().eq(item).text());
			this.hideResults();

			if (this.options.onSelect)
				this.options.onSelect.call(this.$input[0],this.items[item]);
		}
	}
});



	$.fn.suggest = function(source, options) {
		if (!source) return;

		options = $.extend({
			delay:100,
			resultsClass:'ac_results',
			selectClass:'ac_over',
			matchClass:'ac_match',
			minchars:2,
			delimiter:'\n',
			createItems:false,
			formatItem:false,
			selectItemText:false,
			onSelect:false,
			maxCacheSize:65536
		},options);
		options.source = source;

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

		return this;
	};
})(jQuery);




/*
 * jQuery Templates Plugin 1.0.0pre
 * http://github.com/jquery/jquery-tmpl
 * Requires jQuery 1.4.2
 *
 * Copyright Software Freedom Conservancy, Inc.
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 */
(function(a){var r=a.fn.domManip,d="_tmplitem",q=/^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,b={},f={},e,p={key:0,data:{}},i=0,c=0,l=[];function g(g,d,h,e){var c={data:e||(e===0||e===false)?e:d?d.data:{},_wrap:d?d._wrap:null,tmpl:null,parent:d||null,nodes:[],calls:u,nest:w,wrap:x,html:v,update:t};g&&a.extend(c,g,{nodes:[],parent:d});if(h){c.tmpl=h;c._ctnt=c._ctnt||c.tmpl(a,c);c.key=++i;(l.length?f:b)[i]=c}return c}a.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(f,d){a.fn[f]=function(n){var g=[],i=a(n),k,h,m,l,j=this.length===1&&this[0].parentNode;e=b||{};if(j&&j.nodeType===11&&j.childNodes.length===1&&i.length===1){i[d](this[0]);g=this}else{for(h=0,m=i.length;h<m;h++){c=h;k=(h>0?this.clone(true):this).get();a(i[h])[d](k);g=g.concat(k)}c=0;g=this.pushStack(g,f,i.selector)}l=e;e=null;a.tmpl.complete(l);return g}});a.fn.extend({tmpl:function(d,c,b){return a.tmpl(this[0],d,c,b)},tmplItem:function(){return a.tmplItem(this[0])},template:function(b){return a.template(b,this[0])},domManip:function(d,m,k){if(d[0]&&a.isArray(d[0])){var g=a.makeArray(arguments),h=d[0],j=h.length,i=0,f;while(i<j&&!(f=a.data(h[i++],"tmplItem")));if(f&&c)g[2]=function(b){a.tmpl.afterManip(this,b,k)};r.apply(this,g)}else r.apply(this,arguments);c=0;!e&&a.tmpl.complete(b);return this}});a.extend({tmpl:function(d,h,e,c){var i,k=!c;if(k){c=p;d=a.template[d]||a.template(null,d);f={}}else if(!d){d=c.tmpl;b[c.key]=c;c.nodes=[];c.wrapped&&n(c,c.wrapped);return a(j(c,null,c.tmpl(a,c)))}if(!d)return[];if(typeof h==="function")h=h.call(c||{});e&&e.wrapped&&n(e,e.wrapped);i=a.isArray(h)?a.map(h,function(a){return a?g(e,c,d,a):null}):[g(e,c,d,h)];return k?a(j(c,null,i)):i},tmplItem:function(b){var c;if(b instanceof a)b=b[0];while(b&&b.nodeType===1&&!(c=a.data(b,"tmplItem"))&&(b=b.parentNode));return c||p},template:function(c,b){if(b){if(typeof b==="string")b=o(b);else if(b instanceof a)b=b[0]||{};if(b.nodeType)b=a.data(b,"tmpl")||a.data(b,"tmpl",o(b.innerHTML));return typeof c==="string"?(a.template[c]=b):b}return c?typeof c!=="string"?a.template(null,c):a.template[c]||a.template(null,q.test(c)?c:a(c)):null},encode:function(a){return(""+a).split("<").join("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;")}});a.extend(a.tmpl,{tag:{tmpl:{_default:{$2:"null"},open:"if($notnull_1){__=__.concat($item.nest($1,$2));}"},wrap:{_default:{$2:"null"},open:"$item.calls(__,$1,$2);__=[];",close:"call=$item.calls();__=call._.concat($item.wrap(call,__));"},each:{_default:{$2:"$index, $value"},open:"if($notnull_1){$.each($1a,function($2){with(this){",close:"}});}"},"if":{open:"if(($notnull_1) && $1a){",close:"}"},"else":{_default:{$1:"true"},open:"}else if(($notnull_1) && $1a){"},html:{open:"if($notnull_1){__.push($1a);}"},"=":{_default:{$1:"$data"},open:"if($notnull_1){__.push($.encode($1a));}"},"!":{open:""}},complete:function(){b={}},afterManip:function(f,b,d){var e=b.nodeType===11?a.makeArray(b.childNodes):b.nodeType===1?[b]:[];d.call(f,b);m(e);c++}});function j(e,g,f){var b,c=f?a.map(f,function(a){return typeof a==="string"?e.key?a.replace(/(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g,"$1 "+d+'="'+e.key+'" $2'):a:j(a,e,a._ctnt)}):e;if(g)return c;c=c.join("");c.replace(/^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/,function(f,c,e,d){b=a(e).get();m(b);if(c)b=k(c).concat(b);if(d)b=b.concat(k(d))});return b?b:k(c)}function k(c){var b=document.createElement("div");b.innerHTML=c;return a.makeArray(b.childNodes)}function o(b){return new Function("jQuery","$item","var $=jQuery,call,__=[],$data=$item.data;with($data){__.push('"+a.trim(b).replace(/([\\'])/g,"\\$1").replace(/[\r\t\n]/g," ").replace(/\$\{([^\}]*)\}/g,"{{= $1}}").replace(/\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,function(m,l,k,g,b,c,d){var j=a.tmpl.tag[k],i,e,f;if(!j)throw"Unknown template tag: "+k;i=j._default||[];if(c&&!/\w$/.test(b)){b+=c;c=""}if(b){b=h(b);d=d?","+h(d)+")":c?")":"";e=c?b.indexOf(".")>-1?b+h(c):"("+b+").call($item"+d:b;f=c?e:"(typeof("+b+")==='function'?("+b+").call($item):("+b+"))"}else f=e=i.$1||"null";g=h(g);return"');"+j[l?"close":"open"].split("$notnull_1").join(b?"typeof("+b+")!=='undefined' && ("+b+")!=null":"true").split("$1a").join(f).split("$1").join(e).split("$2").join(g||i.$2||"")+"__.push('"})+"');}return __;")}function n(c,b){c._wrap=j(c,true,a.isArray(b)?b:[q.test(b)?b:a(b).html()]).join("")}function h(a){return a?a.replace(/\\'/g,"'").replace(/\\\\/g,"\\"):null}function s(b){var a=document.createElement("div");a.appendChild(b.cloneNode(true));return a.innerHTML}function m(o){var n="_"+c,k,j,l={},e,p,h;for(e=0,p=o.length;e<p;e++){if((k=o[e]).nodeType!==1)continue;j=k.getElementsByTagName("*");for(h=j.length-1;h>=0;h--)m(j[h]);m(k)}function m(j){var p,h=j,k,e,m;if(m=j.getAttribute(d)){while(h.parentNode&&(h=h.parentNode).nodeType===1&&!(p=h.getAttribute(d)));if(p!==m){h=h.parentNode?h.nodeType===11?0:h.getAttribute(d)||0:0;if(!(e=b[m])){e=f[m];e=g(e,b[h]||f[h]);e.key=++i;b[i]=e}c&&o(m)}j.removeAttribute(d)}else if(c&&(e=a.data(j,"tmplItem"))){o(e.key);b[e.key]=e;h=a.data(j.parentNode,"tmplItem");h=h?h.key:0}if(e){k=e;while(k&&k.key!=h){k.nodes.push(j);k=k.parent}delete e._ctnt;delete e._wrap;a.data(j,"tmplItem",e)}function o(a){a=a+n;e=l[a]=l[a]||g(e,b[e.parent.key+n]||e.parent)}}}function u(a,d,c,b){if(!a)return l.pop();l.push({_:a,tmpl:d,item:this,data:c,options:b})}function w(d,c,b){return a.tmpl(a.template(d),c,b,this)}function x(b,d){var c=b.options||{};c.wrapped=d;return a.tmpl(a.template(b.tmpl),b.data,c,b.item)}function v(d,c){var b=this._wrap;return a.map(a(a.isArray(b)?b.join(""):b).filter(d||"*"),function(a){return c?a.innerText||a.textContent:a.outerHTML||s(a)})}function t(){var b=this.nodes;a.tmpl(null,null,null,this).insertBefore(b[0]);a(b).remove()}})(jQuery);

