﻿$j.Avaya.PredictiveQuery = function(options){
	var self = this,
		presets = {
			container : null,
			
			input : '.search-box',
			list_container : '.suggest-list-container',
			list : '.suggest-list',
			active : '.active',
			
			height_limit : 200,
			char_limit : 30,
			char_trigger : 2,
			
			filter : false,
			url : null,
			data : {
				source : null
			},
			
			searchable : true,
			
			initCallback : function(){ },
			focusCallback : function(){ },
			blurCallback : function(){ },
			showCallback : function(){ },
			hideCallback : function(){ }
		};
	
	this.s = $j.extend(true, presets, options);
	this.open = false;
	this.tabable = false;
};

$j.Avaya.PredictiveQuery.prototype = {
	
	init : function(){
		var self = this,
			input = $j(this.s.container).find(this.s.input);
		
		this.request = { current : null, ongoing : false, processes : [], working : null };
		
		
		input.click(function(){ self.hide(); });
		
		input.focus(function(){
			if($j(this).val() == $j(this).attr('title')) $j(this).val('');
			self.s.focusCallback.call(self);
		});
		
		input.keydown(function(e){
			if(e.keyCode == 13 && !self.s.searchable || e.keyCode == 13 && $j(this).val() == '')
				e.preventDefault();
			
			if(e.keyCode == 9 || e.keyCode == 38 || e.keyCode == 40) {
				if(self.open)
					self.tabable = true;
			}
		});
		
		input.keyup(function(e){
			if(e.keyCode == 9 || e.keyCode == 38){
				return;
			} else if(e.keyCode == 13 && !self.s.searchable || e.keyCode == 13 && $j(this).val() == ''){
				e.preventDefault();
			} else if(e.keyCode == 40){
				self.getFocus(self.getLinks().eq(0));
			} else {
				if($j(this).val().length >= self.s.char_trigger) {
					self.query($j(this).val());
				} else {
					self.empty();
					self.hide();
				}
			}
		});
		
		input.blur(function(){
			if(!self.tabable) if($j(this).val() == ''){
				$j(this).val($j(this).attr('title'));
				self.s.blurCallback.call(self);
			} else {
				self.tabable = false;
			}
		});
		
		
		$j(document).keydown(function(e){
			if(self.open){
				var active = self.getActive(self.getLinks()),
					links = $j(self.s.container).find(self.s.list_container + ' a');
				
				if(e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 9){
					links.unbind('keydown').keydown(function(evt){
						evt.preventDefault();
						self.setArrowNavigation(evt, $j(this));
					});
				}
				
				if(e.keyCode == 9){
					links.unbind('keydown').keydown(function(evt){ self.setArrowNavigation(evt, $j(this)); });
					links.eq(links.size()-1).unbind('blur').blur(function(){ self.resetFocus(true); });
				}
			}
		});
		
		$j(document).click(function(e){
			if(self.open){
				if($j(e.target).parents(self.s.container).size() == 0) self.hide();
			}
		});
		
		$j(document).bind('PredictiveSearch.showRecentResults', function(){
			self.empty();
			if(typeof self.request.processes[0] != 'undefined') self.request.processes.pop()();
		});
		
		
		$j(this.s.container).find(this.s.list).height(this.s.height_limit);
		
		
		this.s.initCallback.call(this);
	},
	
	
	
	show : function(){
		this.open = true;
		$j(this.s.container).find(this.s.list_container).show().find(this.s.list).jScrollPane();
	},
	
	hide : function(){
		this.open = false;
		$j(this.s.container).find(this.s.list_container).empty().hide();
	},
	
	empty : function(){
		$j(this.s.container).find(this.s.list).empty();
	},
	
	getLinks : function(){
		return $j(this.s.container).find(this.s.list).find('a');
	},
	
	getActive : function(collection){
		return collection.filter(this.s.active);
	},
	
	getFocus : function(el){
		el.focus().addClass(this.s.active.substr(1));
		if(typeof el.position() != 'undefined' && typeof $j(this.s.container).find(this.s.list)[0] != 'undefined'
			&& typeof $j(this.s.container).find(this.s.list)[0].scrollTo != 'undefined'){
			$j(this.s.container).find(this.s.list)[0].scrollTo(el.position().top - 40);
		}
	},
	
	loseFocus : function(el){
		el.removeClass(this.s.active.substr(1));
	},
	
	resetFocus : function(hide){
		$j(this.s.container).find(this.s.input).focus();
		this.loseFocus(this.getLinks().eq(0));
		if(typeof hide != 'undefined' && hide) this.hide();
	},
	
	highlight : function(query){
		var highlight_func = function(result){
			var re = new RegExp(query, "ig"),
				snippet = re.exec(result);
			
			return result.replace(re, '<b>'+snippet+'</b>');
		};
		
		return highlight_func;
	},
	
	setArrowNavigation : function(e, el){
		if(e.keyCode == 38){
			if(el.prev().size() > 0) {
				this.loseFocus(el);
				this.getFocus(el.prev());
			} else {
				this.resetFocus();
			}
		} else if(e.keyCode == 40){
			if(el.next().size() > 0) {
				this.loseFocus(el);
				this.getFocus(el.next());
			}
		}
	},
	
	query : function(query){
		var self = this;
		
		query = $j.trim(query);
		
		if(this.s.filter && typeof this.filter_rsp != 'undefined'){
			var filter = this.filterByQuery(query);
			if(filter.length > 0){
				this.request.processes.push(function(){ self.showResults(self.filterByQuery(query), query); });
				if(!this.request.working){
					this.request.working = setTimeout(function(){
						$j(document).trigger('PredictiveSearch.showRecentResults');
						self.resetQueryTimer();
					}, 50);
				} else {
					this.resetQueryTimer();
					this.request.working = setTimeout(function(){
						$j(document).trigger('PredictiveSearch.showRecentResults');
						self.resetQueryTimer();
					}, 50);
				}
			} else {
				self.hide();
			}
			return;
		}
		
		if(this.request.ongoing) this.clearRequest();
		
		this.request.ongoing = true;
		this.request.current = $j.ajax({
			type: 'GET',
			//url: self.s.data.source,
			//data: 'SITE='+$j(this.s.container).find('input.sitevar').val()+'&query='+query,
			url: '/usa/PredictiveSearch.aspx',
			data:'query='+query,
			dataType: 'json',
			
			success: function(rsp){
			    if(rsp[1].length > 0){
			        if(self.s.filter){
						self.filter_rsp = rsp.results;
						if(rsp.results.length > 0) self.request.processes.push(function(){ self.showResults(self.filterByQuery(query), query); });
						else self.hide();
					} else {
						if(rsp[1].length > 0) self.request.processes.push(function(){ self.showResults(rsp[1], query); });
						else self.hide();
					}
				}
			    /*
				if(rsp.status == 200){
				    if(self.s.filter){
						self.filter_rsp = rsp.results;
						if(rsp.results.length > 0) self.request.processes.push(function(){ self.showResults(self.filterByQuery(query), query); });
						else self.hide();
					} else {
						if(rsp.results.length > 0) self.request.processes.push(function(){ self.showResults(rsp.results, query); });
						else self.hide();
					}
				}*/
			},
			error : function(){ self.clearRequest(); },
			complete : function(){
				self.clearRequest();
				$j(document).trigger('PredictiveSearch.showRecentResults');
			}
		});
	},
	
	resetQueryTimer : function(){
		clearTimeout(this.request.working);
		this.request.working = null;
	},
	
	filterByQuery : function(query){
		var collection = [],
			re = new RegExp(query, "i");
		
		for(var i=0,len=this.filter_rsp.length; i<len; i++){
			var result = this.filter_rsp[i],
				q = result['query'].replace(/[^\w\s]/gi, '');
			
			if(re.test(q)) collection.push(result);
		}
		
		return collection;
	},
	
	showResults : function(results, query){
		var height = 0, list;
		
		//this.empty();
		
		$j(this.s.container).find(this.s.list_container).html('<div class="' + this.s.list.substr(1) + '" />');
		list = $j(this.s.container).find(this.s.list);
		
		for(var i=0,len=results.length; i<len; i++) {
		    var siteParam = document.forms['base'].site.value;
	        var siteurl = document.forms['base'].action.value;
	        var client = document.forms['base'].client.value;
	        var proxystylesheet = document.forms['base'].proxystylesheet.value;
	        var resultitem = [{"link":'http://searchext.avaya.com/search?q=' + results[i] + '&site=' + siteParam + '&btnG=Search&access=p&client=' + client + '&output=xml_no_dtd&proxystylesheet=' + proxystylesheet + '&oe=UTF-8&ie=UTF-8&ud=1&sort=date%3AD%3AL%3Ad1&exclude_apps=1',"query":results[i]}];
		    list.append(this.formatResult(resultitem[0], query));
		    //list.append(this.formatResult(results[i], query));
		}
		
		this.show();
			list.find('a').each(function(){ height += $j(this).height(); });
			list.height(height);
	},
	
	formatResult : function(result, query){
		var self = this,
			highlighter = this.highlight(query),
			input = $j(this.s.container).find(this.s.input),
			output = $j('<a href="" />'),
			name;
		
		if(result['query'].length > this.s.char_limit) name = result['query'].substr(0, this.s.char_limit) + '...';
		else name = result['query'];
		
		output.html(highlighter(name)).attr('data-fullname', result['query']);
		
		if(typeof result['link'] != 'undefined'){
			if(this.s.dest_url_base != null) output.attr('href', this.s.dest_url_base + result['link']);
			else output.attr('href', result['link']);
			
			output.bind('keyup', function(e){
				if(e.keyCode == 13) document.location.href = $j(this).attr('href');
			});
		} else {
			output.bind('keyup click', function(e){
				e.preventDefault();
				
				if(typeof e.keyCode != 'undefined'){
					if(e.keyCode == 13) self.submitResult(output.attr('data-fullname'), input);
					return;
				}
				
				self.submitResult(output.attr('data-fullname'), input);
				return false;
			});
		}
		
		return output;
	},
	
	submitResult : function(text, input){
		this.hide();
		input.val(text).parent().submit();
	},
	
	clearRequest : function(){
		if(typeof this.request.current.abort != 'undefined' && this.request.current != null) this.request.current.abort();
		this.request.current = null;
		this.request.ongoing = false;
	}

};
