/*
 * All java script logic for the search suggestions.
 *
 * The code relies on the jQuery JS library to
 * be also loaded.
 *
 * The logic extends the JS namespace app.*
 */


function SearchSuggest() {
	this.acListTotal   =  0;
	this.acListCurrent = -1;
	this.acDelay       = 300;
	this.acURL         = null;
	this.acFormId      = null;
	this.acSearchId	  = null;
	this.acResultsId = null;
	this.acSearchField = null;
	this.acResultsDiv  = null;
	this.fieldDefault  = null;
	
	this.init = function(formId, fieldId, resultsId, url, hideSuggestions) {
		// initialize vars
		this.acFormId = "#" + formId;
		this.acSearchId = "#" + fieldId;
		this.acResultsId = "#" + resultsId;
		this.acURL = url;
		this.fieldDefault = $('#defaultsimplesearch').val();
		this.hideSuggestions = hideSuggestions != null ? hideSuggestions : false;
		var _this = this;
		// disable browser auto comlete
		app.util.disableAutoComplete(fieldId);
		
		// create the results div
		if(resultsId == 'suggestions') {
			jQuery("#hd").append("<div id=\"" + resultsId + "\"></div>");	
		} else {
			jQuery("#"+formId).append("<div id=\"" + resultsId + "\"></div>");
		}				
	
		// register mostly used vars (jQuery object)
		this.acSearchField = jQuery(this.acSearchId);
		this.acResultsDiv = jQuery(this.acResultsId);
		
		// reposition div
		this.repositionResultsDiv();
	
		// on blur listener
		this.acSearchField.blur(function(){ setTimeout("_this.clear()", 200) });
	
		// on key up listener
		this.acSearchField.keyup(function(e) {
			// get keyCode (window.event is for IE)
			var keyCode = e.keyCode || window.event.keyCode;
			var lastVal = _this.acSearchField.val();
			// check an treat up and down arrows
			if(_this.updownArrow(keyCode)){
				return;
			}
			// check for an ENTER or ESC
			if(keyCode == 13 || keyCode == 27) {
				_this.clear();
				return;
			}
			
			if(!hideSuggestions) {
				// if is text, call with delay
				setTimeout(function() { _this.suggest(lastVal) }, _this.acDelay);				
			}
		});
		
		// on focus listener (clear default value)
		this.acSearchField.focus(function() {
			var val = _this.acSearchField.val();
			if(val == _this.fieldDefault)
			{
				_this.acSearchField.removeClass('redtext');
				_this.acSearchField.val("");
			}		
		});
		
		// on submit we do not submit the form, but change the window location
		// in order to avoid https to http warnings in the browser
		jQuery(this.acFormId).submit(function() {
			var searchUrl = jQuery(_this.acFormId).attr("action");
			var searchTerm = _this.acSearchField.val();
			
			if(searchTerm != '' && searchTerm != _this.fieldDefault){
				window.location = app.util.appendParamToURL(searchUrl, "q", searchTerm);
			}else{
				_this.acSearchField.addClass('redtext');
				_this.acSearchField.val(_this.fieldDefault);
				return false;
			}
		});		
	}
	
	this.suggest = function(lastValue)
	{
		var _this = this;
		// get the field value
		var part = this.acSearchField.val();
	
		// if it's empty clear the resuts box and return
		if(part == "") {
			this.clear();
			return;
		}
	
		// if it's equal the value from the time of the call, allow
		if(lastValue != part) {
			return;
		}
		
		// build the request url
		var reqUrl = app.util.appendParamToURL(this.acURL, "q", part);
		
		// get remote data as JSON
		jQuery.getJSON(reqUrl, function(json) {
			// get the total of results
			var ansLength = _this.acListTotal = json.suggestions.length;
	
			// if there are results populate the results div
			if(ansLength > 0) {
	
				var newData = "";
				// create a div for each result
				for(i=0; i < ansLength; i++) {
					newData += "<div class=\"unselected\"><div class=\"suggestionterm\">" + json.suggestions[i].suggestion + "</div>";
					newData += "<span class=\"hits\">" + json.suggestions[i].hits + "</span></div>";
				}
				// update the results div
				_this.acResultsDiv.html(newData);
				_this.acResultsDiv.css("display","block");
				// reposition in case user resizes browser between searches
				_this.repositionResultsDiv();
				
				// for all divs in results
				var divs = jQuery(_this.acResultsId + " > div");
				
				// on mouse over clean previous selected and set a new one
				divs.mouseover( function() {
					divs.each(function(){ this.className = "unselected"; });
					this.className = "selected";
				});
				
				// on click copy suggestion to search field, hide the list and submit the search
				divs.click( function() {
					_this.acSearchField.val(jQuery(this).children(".suggestionterm").first().text());
					_this.clear();
					jQuery(_this.acFormId).submit();
				});
			} else {
				this.clear();
			}
		});
	}	
	
	this.clear = function()	{
		this.acResultsDiv.html("");
		this.acResultsDiv.css("display","none");
	}
	
	this.repositionResultsDiv = function()
	{
		// get the input position
		var inPos = this.acSearchField.offset();
		var inTop = inPos.top;
		var inLeft = inPos.left;
		
		// get the field size
		var inHeight = this.acSearchField.height();
		var inWidth = this.acSearchField.width();
		
		// apply the css styles
		this.acResultsDiv.addClass("suggestions");
	}	
	
	this.updownArrow = function(keyCode) {
		var _this = this;
		if(keyCode == 40 || keyCode == 38) {
			if(keyCode == 38) { // keyUp
				if(this.acListCurrent == 0 || this.acListCurrent == -1) {
					this.acListCurrent = this.acListTotal-1;
				} else {
					this.acListCurrent--;
				}
			} else { // keyDown
				if(this.acListCurrent == this.acListTotal-1) {
					this.acListCurrent = 0;
				} else {
					this.acListCurrent++;
				}
			}
			
			// loop through each result div applying the correct style
			this.acResultsDiv.children().each(function(i) {
				if(i == _this.acListCurrent) {
					_this.acSearchField.val($(this).find('.suggestionterm').text());
					this.className = "selected";
				} else {
					this.className = "unselected";
				}
			});
			return true;
		} else {
			// reset
			_this.acListCurrent = -1;
			return false;
		}
	}
}

(function(app){
	if (app) {
		// add searchsuggest to namespace
		app.searchsuggest = {
			// configuration parameters and required object instances
			acListTotal   :  0,
			acListCurrent : -1,
			acDelay       : 300,
			acURL         : null,
			acFormId      : null,
			acSearchId	  : null,
			acResultsId	  : null,
			acSearchField : null,
			acResultsDiv  : null,
			fieldDefault  : null,
			
			init : function(formId, fieldId, resultsId, url) {
				// initialize vars
				app.searchsuggest.acFormId = "#" + formId;
				app.searchsuggest.acSearchId = "#" + fieldId;
				app.searchsuggest.acResultsId = "#" + resultsId;
				app.searchsuggest.acURL = url;
				app.searchsuggest.fieldDefault = $('#defaultsimplesearch').val();
				
				// disable browser auto comlete
				app.util.disableAutoComplete(fieldId);
				
				// create the results div
				if(resultsId == 'suggestions') {
					jQuery("#hd").append("<div id=\"" + resultsId + "\"></div>");	
				} else {
					jQuery("#"+formId).append("<div id=\"" + resultsId + "\"></div>");
				}				
			
				// register mostly used vars (jQuery object)
				app.searchsuggest.acSearchField = jQuery(app.searchsuggest.acSearchId);
				app.searchsuggest.acResultsDiv = jQuery(app.searchsuggest.acResultsId);
			
				// reposition div
				app.searchsuggest.repositionResultsDiv();
			
				// on blur listener
				app.searchsuggest.acSearchField.blur(function(){ setTimeout("app.searchsuggest.clear()", 200) });
			
				// on key up listener
				app.searchsuggest.acSearchField.keyup(function(e) {
					// get keyCode (window.event is for IE)
					var keyCode = e.keyCode || window.event.keyCode;
					var lastVal = app.searchsuggest.acSearchField.val();
					// check an treat up and down arrows
					if(app.searchsuggest.updownArrow(keyCode)){
						return;
					}
					// check for an ENTER or ESC
					if(keyCode == 13 || keyCode == 27) {
						app.searchsuggest.clear();
						return;
					}
					
					// if is text, call with delay
					setTimeout(function() { app.searchsuggest.suggest(lastVal) }, app.searchsuggest.acDelay);
				});
				
				// on focus listener (clear default value)
				app.searchsuggest.acSearchField.focus(function() {
					var val = app.searchsuggest.acSearchField.val();
					if(val == app.searchsuggest.fieldDefault)
					{
						app.searchsuggest.acSearchField.removeClass('redtext');
						app.searchsuggest.acSearchField.val("");
					}
				});
				
				// on submit we do not submit the form, but change the window location
				// in order to avoid https to http warnings in the browser
				jQuery(app.searchsuggest.acFormId).submit(function() {
					var searchUrl = jQuery(app.searchsuggest.acFormId).attr("action");
					var searchTerm = app.searchsuggest.acSearchField.val();
					
					if(searchTerm != '' && searchTerm != app.searchsuggest.fieldDefault){
						window.location = app.util.appendParamToURL(searchUrl, "q", searchTerm);
					}else{
						app.searchsuggest.acSearchField.addClass('redtext');
						app.searchsuggest.acSearchField.val(app.searchsuggest.fieldDefault);
						return false;
					}
				});
			},
			
			// trigger suggest action
			suggest : function(lastValue)
			{
				// get the field value
				var part = app.searchsuggest.acSearchField.val();
			
				// if it's empty clear the resuts box and return
				if(part == "") {
					app.searchsuggest.clear();
					return;
				}
			
				// if it's equal the value from the time of the call, allow
				if(lastValue != part) {
					return;
				}
				
				// build the request url
				var reqUrl = app.util.appendParamToURL(app.searchsuggest.acURL, "q", part);
				
				// get remote data as JSON
				jQuery.getJSON(reqUrl, function(json) {
					// get the total of results
					var ansLength = app.searchsuggest.acListTotal = json.suggestions.length;
			
					// if there are results populate the results div
					if(ansLength > 0) {
			
						var newData = "";
						// create a div for each result
						for(i=0; i < ansLength; i++) {
							newData += "<div class=\"unselected\"><div class=\"suggestionterm\">" + json.suggestions[i].suggestion + "</div>";
							newData += "<span class=\"hits\">" + json.suggestions[i].hits + "</span></div>";
						}
						// update the results div
						app.searchsuggest.acResultsDiv.html(newData);
						app.searchsuggest.acResultsDiv.css("display","block");
						// reposition in case user resizes browser between searches
						app.searchsuggest.repositionResultsDiv();
						
						// for all divs in results
						var divs = jQuery(app.searchsuggest.acResultsId + " > div");
						
						// on mouse over clean previous selected and set a new one
						divs.mouseover( function() {
							divs.each(function(){ this.className = "unselected"; });
							this.className = "selected";
						});
						
						// on click copy suggestion to search field, hide the list and submit the search
						divs.click( function() {
							app.searchsuggest.acSearchField.val(jQuery(this).children(".suggestionterm").first().text());
							app.searchsuggest.clear();
							jQuery(app.searchsuggest.acFormId).submit();
						});
					} else {
						app.searchsuggest.clear();
					}
				});
			},
			
			// clear suggestions
			clear : function()
			{
				app.searchsuggest.acResultsDiv.html("");
				app.searchsuggest.acResultsDiv.css("display","none");
			},
			
			// reposition the results div accordingly to the search field
			repositionResultsDiv : function()
			{
				// get the input position
				var inPos = app.searchsuggest.acSearchField.offset();
				var inTop = inPos.top;
				var inLeft = inPos.left;
				
				// get the field size
				var inHeight = app.searchsuggest.acSearchField.height();
				var inWidth = app.searchsuggest.acSearchField.width();
				
				// apply the css styles
				app.searchsuggest.acResultsDiv.addClass("suggestions");
			},
			
			// treat up and down key strokes defining the next selected element
			updownArrow : function(keyCode) {
				if(keyCode == 40 || keyCode == 38) {
					if(keyCode == 38) { // keyUp
						if(app.searchsuggest.acListCurrent == 0 || app.searchsuggest.acListCurrent == -1) {
							app.searchsuggest.acListCurrent = app.searchsuggest.acListTotal-1;
						} else {
							app.searchsuggest.acListCurrent--;
						}
					} else { // keyDown
						if(app.searchsuggest.acListCurrent == app.searchsuggest.acListTotal-1) {
							app.searchsuggest.acListCurrent = 0;
						} else {
							app.searchsuggest.acListCurrent++;
						}
					}
					
					// loop through each result div applying the correct style
					app.searchsuggest.acResultsDiv.children().each(function(i) {
						if(i == app.searchsuggest.acListCurrent) {
							app.searchsuggest.acSearchField.val($(this).find('.suggestionterm').text());
							this.className = "selected";
						} else {
							this.className = "unselected";
						}
					});
					return true;
				} else {
					// reset
					app.searchsuggest.acListCurrent = -1;
					return false;
				}
			}
		} // end searchsuggest
	} else {
		// namespace has not been defined yet
		alert("app namespace is not loaded yet!");
	}
})(app);
