/*jslint evil: false, regexp: true */
/*
 * 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.*
 * Requires jQuery, SWFAddress
 */
 
(function(app){
	if (app) {
		
		var KEYS = {
				UP: 38,
				DOWN: 40,
				DEL: 46,
				TAB: 9,
				RETURN: 13,
				ESC: 27,
				COMMA: 188,
				PAGEUP: 33,
				PAGEDOWN: 34,
				BACKSPACE: 8
		};
		
		// add searchsuggest to namespace
		app.suggest = {
			// configuration parameters and required object instances
			acListTotal   :  0,
			acListCurrent : -1,
			acDelay       : 100,
			acURL         : null,
			psURL         : null,
			acFormId      : null,
			acSearchId	  : null,
			acResultsId	  : null,
			acSearchField : null,
			acHintField	  : "input#suggested-term",
			acResultsDiv  : null,
			acRowClass	  : "div.suggestionRow",
			fieldDefault  : null,
			currentTerm	  : null,
			suggestions	  : {},
			loaded		  : false,
			hasFocus	  : false,
			
			init : function(formId, fieldId, fieldDefault, resultsId, url, productUrl) {
				// initialize vars
				app.suggest.acFormId = "#" + formId;
				app.suggest.acSearchId = "#" + fieldId;
				app.suggest.acResultsId = "#" + resultsId;
				app.suggest.acURL = url;
				app.suggest.psBaseURL = productUrl;
				app.suggest.psSearchURL = productUrl;
				app.suggest.fieldDefault = fieldDefault;
				
				// disable browser auto comlete
				app.util.disableAutoComplete(fieldId);
			
				// register mostly used vars (jQuery object)
				app.suggest.acSearchField = jQuery(app.suggest.acSearchId);
				app.suggest.acHintField = jQuery(app.suggest.acHintField);
				app.suggest.acResultsDiv = jQuery(app.suggest.acResultsId);
			
				// on key up listener
				app.suggest.acSearchField.keyup(function(e) {
					
					// get keyCode (window.event is for IE)
					var keyCode = e.keyCode || window.event.keyCode;
					
					var lastVal = app.suggest.acSearchField.val();
					if (lastVal === '') {
						app.suggest.acHintField.val('');
					}
					
					// check an treat up and down arrows
					if (app.suggest.updownArrow(keyCode)){
						return;
					}
					
					// check for an ENTER or ESC
					if (keyCode === KEYS.RETURN || keyCode === KEYS.ESC) {
						// prevent ESC close on search page
						if (keyCode === KEYS.ESC && !jQuery('#search-global').hasClass('open')) {
							app.suggest.close();
						}
						return;
					}
					
					// if is text and minimum number of chars have been entered call with delay
					if (lastVal.length >= appSearchsuggestMinChars) {
						// setTimeout(function() { app.suggest.suggest(lastVal, keyCode) }, app.suggest.acDelay);
						setTimeout(function() { app.suggest.suggest(lastVal, keyCode); }, 100);
					}
				});
				
				app.suggest.acSearchField.keydown(function(e) {
					// get keyCode (window.event is for IE)
					var keyCode = e.keyCode || window.event.keyCode;
					
					if (keyCode === KEYS.TAB) {
						var currentTerm = app.suggest.acSearchField.val();
						app.suggest.loadSuggestions(currentTerm, true);
					}
				});
				
				// on focus listener (clear default value)
				app.suggest.acSearchField.focus(function() {
					var val = app.suggest.acSearchField.val();
					if (val === app.suggest.fieldDefault)
					{
						app.suggest.acSearchField.val('');
					}
					app.suggest.hasFocus = true;
					
					// load suggestions once
					if (!app.suggest.loaded) {
						app.suggest.getSuggestions();
						app.suggest.loaded = true;
					}
				});
				
				app.suggest.acSearchField.blur(function() {
					var currentTerm = app.suggest.acSearchField.val();
					if (currentTerm != '') {
						app.suggest.loadSuggestions(currentTerm, true);
					}
					
					var val = app.suggest.acSearchField.val();
					if (val != '')
					{
						SWFAddress.setValue("/search/?q=" + val);
					}
					app.suggest.hasFocus = false;
				});
				
				// 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.suggest.acFormId).submit(function() {
					var searchUrl = jQuery(app.suggest.acFormId).attr("action");
					var searchTerm = app.suggest.acSearchField.val();
					window.location = app.util.appendParamToURL(searchUrl, "q", searchTerm);
					return false;
				});
				
				jQuery('.close-search').live('click', function() {
					app.suggest.close();
				});
				
				/*
				 * Update search term on suggestion click
				 */
				jQuery('a.suggested-term').live('click', function() {
					
					var lastTerm = app.suggest.acSearchField.val();
					SWFAddress.setValue("/search/?q=" + lastTerm);
					
					app.suggest.acSearchField.val('');
					
					var thisTerm = jQuery(this).attr('target');
					app.suggest.acSearchField.val(thisTerm);
					app.suggest.suggest(thisTerm, 65);
					
					SWFAddress.setValue("/search/?q=" + thisTerm);
				});
				
			},
			
			getSuggestions : function() {
				
				// get full list of terms once
				jQuery.getJSON(app.suggest.acURL, function(json) {
					app.suggest.suggestions = json.suggestions;
				});
				
			},
			
			// trigger suggest action
			suggest : function(lastValue, keyCode) {
				
				// get the field value
				var currentTerm = app.suggest.acSearchField.val();
			
				// if it's equal the value from the time of the call, allow
				if (lastValue !== currentTerm) {
					return;
				}
				
				// reset search url
				app.suggest.psSearchURL = app.suggest.psBaseURL;
				app.suggest.psSearchURL = app.util.appendParamToURL(app.suggest.psSearchURL, "format", "suggest");
				
				/*
				 * get search suggests data as JSON, not on left/right keycode
				 */
				if (keyCode !== KEYS.DOWN && keyCode !== KEYS.UP) {
					
					// load suggestions
					app.suggest.loadSuggestions(currentTerm, false);
					
					/*
					 * get product suggests data as HTML, not on left/right keycode,
					 * not on less than 2 characters
					 */
					app.suggest.psSearchURL = app.util.appendParamToURL(app.suggest.psSearchURL, "q", app.suggest.currentTerm);
					
					jQuery.get(app.suggest.psSearchURL, function(data) {
						
						app.suggest.acResultsDiv.html('<div class="page-width">' + data + '</div>').show();
						// set search overlay height
						app.suggest.acResultsDiv.css({ 'height': jQuery(document).height() - app.suggest.acResultsDiv.offset().top})
						
						// get total suggestion rows
						app.suggest.acListTotal = app.suggest.acResultsDiv.find(app.suggest.acRowClass).length;
					});
				}
				
			},
			
			loadSuggestions : function(currentTerm, selectFirst) {

				var suggestedTermFound = false;
				var displaySuggestedTerm = false;
				
				
				// match current term
				var regTerms = new RegExp("^" + currentTerm, "gi");
				var regSynonyms = new RegExp(currentTerm, "gi");
				
				// match exact terms
				jQuery.each(app.suggest.suggestions, function(i,suggestion) {
					if (suggestion.term.match(regTerms)) {
						currentTerm = suggestion.term;
						suggestedTermFound = true;
						displaySuggestedTerm = true;
						return false;
					}
				});
				
				// else match synonyms
				if (!suggestedTermFound) {
					jQuery.each(app.suggest.suggestions, function(i,suggestion) {
						if (suggestion.synonyms.match(regSynonyms)) {
							currentTerm = suggestion.term;
							suggestedTermFound = true;
							displaySuggestedTerm = false;
							return false;
						}
					});
				}
				
				// save current term
				app.suggest.currentTerm = currentTerm;
				
				// use term from suggestion list if match
				if (displaySuggestedTerm && selectFirst) {
					// set input on tab
					app.suggest.acSearchField.val(currentTerm);
					app.suggest.acHintField.val(currentTerm);
					
				} else if (displaySuggestedTerm) {
					app.suggest.acHintField.val(currentTerm);
					
				} else {
					app.suggest.acHintField.val('');
					
				}
			},
			
			display : function() {
				jQuery('#search-global').show();
				jQuery('body').addClass('search-isopen');
				app.suggest.acSearchField.focus();
			},
			
			// clear suggestions
			close : function() {
				jQuery('#search-global').hide();
				jQuery('body').removeClass('search-isopen');
				app.suggest.hasFocus = false;
			},
			
			// treat up and down key strokes defining the next selected element
			updownArrow : function(keyCode) {
				if (keyCode === KEYS.DOWN || keyCode === KEYS.UP) {
					if (keyCode === KEYS.UP) { // keyUp
						if (app.suggest.acListCurrent === 0 || app.suggest.acListCurrent === -1) {
							app.suggest.acListCurrent = app.suggest.acListTotal-1;
						} else {
							app.suggest.acListCurrent--;
						}
					} else { // keyDown
						if (app.suggest.acListCurrent === app.suggest.acListTotal-1) {
							app.suggest.acListCurrent = 0;
						} else {
							app.suggest.acListCurrent++;
						}
					}
					
					// loop through each result div applying the correct style
					app.suggest.acResultsDiv.find(app.suggest.acRowClass).each(function(i) {
						if (i === app.suggest.acListCurrent) {
							jQuery(this).addClass("selected");
						} else {
							jQuery(this).removeClass("selected");
						}
					});
					return true;
				} else {
					// reset
					app.suggest.acListCurrent = -1;
					return false;
				}
			}
		}; // end searchsuggest
	}
}(app));
