/*******************************************************************************
 * Execute jQuery commands on document ready
 ******************************************************************************/

$(function(){

	/**
	 * Use JavaScipt to hide/show the view cart table in IE6 since it doesn't
	 * support :hover on non-a elements.
	 */
	if (MSIE && MSIE == 6)
	{
		$(".cartFrame")
			.bind("mouseenter",function(){
			
				$("#cartDisplay").attr('style','display:block;');
				
			})
			.bind("mouseleave",function(){
			
				$("#cartDisplay").attr('style','display:none;');
				
			})
	}
	
	/**
	 * Add the autocomplete attribute to the field via unobtrusive to avoid
	 * invalid XHTML code and the keyup function at load time to keep clean code
	 * 
	 * ## 2008-06-29
	 * Taken this out for All IE versions as I am not happy with it's styling 
	 * and it's functionality. Will re-implement this later.
	 */
	if (!MSIE) {
		
		$("#search")
			.attr('autocomplete','off')
			.bind("keyup",function(e){
			
				$Search.start(e);
				
			})
			.bind("blur",function(e){
			
				setTimeout(function(){
					$Search.blur(true);
					$Search.hasFocus = 0;
				}, 100);
				
			})
			.bind("focus",function(e){
			
				$Search.hasFocus = 1;
				if ($(this).val() && $Search.results.length)
					$("#searchResults").attr('style','display:block;');
					
			});
			
		// Make the search results disappear on form submit.
		$("#Item_Search")
			.bind("submit",function(){
			
				$Search.blur(true);
				
			});
			
	}

});
/*******************************************************************************
 * Execute jQuery commands on document unload to clear active timouts
 ******************************************************************************/
$().unload(function(){
	
	for (var i = 0; i < $Search.tOut.length; i++)
		clearTimeout($Search.tOut[i]);
		
});

/*******************************************************************************
 * SEARCH QUERY - AJAX LIST
 ******************************************************************************/
$Search = {
	
	// Search Field has focus?
	hasFocus: 0,
	
	// Timeout Events
	tOut: [],
	
	// Last Timeout Event
	lastOut: -1,
	
	// Search Results
	results: [],
	
	// Selected result
	selected: -1,
	
	/**
	* start
	* 
	* Sets a function to execute in X seconds at which point it will find
	* the best matches to the text provided in the search textbox.
	* @param    event	e		Element Event
	* @return   nil
	*/
	start: function (e) {
	
		// Make sure that the keyCode is an accepted key, ignoring keys
		// like CTRL, ALT, etc.
		var validKC = false;
		var keyCode = (window.event) ? e.keyCode : e.which;
		switch (keyCode)
		{
			case 27:	// Escape
				return $Search.blur(true);
			
			case 40:	// Down Arrow
				return $Search.next();
			
			case 38:	// Up Arrow
				return $Search.next(true);
			
			case 36:	// Home
				/**
				* ## 2008-06-29
				* Removed these Home and End keys as it is pissing me off and I 
				* imagine it would do others too.
				*/
				return false;
				//return $Search.first();
			
			case 35:	// End
				return false;
				//return $Search.first(true);
			
			case 8:		// Backspace
			case 109:	// Numpad Subtract
			case 110:	// Numpad Decimal
			case 111:	// Numpad Divide
			case 188:	// Comma
			case 189:	// Dash
			case 190:	// Period
			case 191:	// Forward Slash
			case 220:	// Backward Slash
				validKC = true;
		}
		
		// if the keyCode is still invalid, check agains all 0-9, a-z chars
		if (!validKC)
		{
			if ((keyCode >= 48 && keyCode <= 57) ||
				(keyCode >= 65 && keyCode <= 90)) validKC = true;
		}
		
		// If the keyCode is still invalid, abort the function
		if (!validKC) return false;
		
		// If another timeout has been issued, clear it before starting the new one.
		if ($Search.lastOut > -1)
			clearTimeout($Search.tOut[$Search.lastOut]);

		// Set function to trigger in 1 second unless cancelled
		$Search.lastOut = $Search.tOut.length;
		$Search.tOut.push(setTimeout(function(){
			
			$Search.fetch($System.eTarget(e).value);
			
		}, 250));
	},

	/**
	* blur
	* 
	* Function called when the focus leaves the search results textbox to hide
	* the AJAX results list.
	* @param    bool	keepResults		Hide the search results list?
	* @return   nil
	*/
	blur: function (keepResults)
	{
		// Clear the innerHTML
		if (!keepResults && $("#searchResults").html)
			$("#searchResults").html("");
		
		// Set the list to hidden
		$("#searchResults").attr('style','display:none;');
	},

	/**
	* fetch
	* 
	* Used to fetch all search results via an AJAX call
	* @param    str		dataCheck	String of keywords to search for
	* @return   nil
	*/
	fetch: function (dataCheck)
	{
		if (!dataCheck) return false;
		
		// Convert dataCheck to an array for keyword highlighting
		var dCheckArray = dataCheck.split(" ");
		
		// Process
		$.ajax({
			url: baseDir+"search.php",
			data: {
			    "search": $('#search').val()
			},
			success: function(data) {
		    	
		    	// Process Response
		    	//console.log($(data.records));
				//var root = data.records;
				$Search.blur();
				
				// Clear the old results array
				$Search.results = [];
				$Search.selected = -1;
				
				$(data.records)
					.each(function(){
						
						// Prepare Information
						var id = $(this)[0].id;
						var code = $(this)[0].code;
						var title = $(this)[0].title + " - " + $(this)[0].vTitle;
						
						// Add the result to the results array
		        		$Search.results.push(title);
		        		
		        		// Highlight the search term
		        		for (var dCA = 0; dCA < dCheckArray.length; dCA++) {
		        			var regEx = new RegExp("("+dCheckArray[dCA]+")", "gi");
		        			title = title.replace(regEx,"<strong>$1</strong>");
		        			code = code.replace(regEx,"<strong>$1</strong>");
						}
						
						// Add result to the innerHTML
						$("#searchResults").html(
							$("#searchResults").html()
							+ '<a href="details.php?id='+id+'">'
							+ "<span class='code'>&lt;"+code
							+ "&gt;</span><span class='title'>"
							+ title+"</span>"
							+ '</a>');
							
						$("#searchResults").attr('style',($Search.results.length)
							? 'display:block;'
							: 'display:none;'
						);
						
					});
					
				// If the search field has lost focus, auto blur after 1 second
				if (!$Search.hasFocus)
				{
					$Search.tOut.push(
						setTimeout(function(){
						
							if (!$Search.hasFocus) $Search.blur(true);
						
						}, 500)
					);
					$("#search").focus();
				}
			}
		});
	},

	/**
	* next
	* 
	* Selects the next search result in the list
	* @param    bool	reverse		Select up or down the result list
	* @return   nil
	*/
	next: function (reverse)
	{
		if (!reverse)
		{
			// Select the next result
			$Search.selected++;
			if ($Search.selected >= $Search.results.length)
				$Search.selected = 0;
		}
		else
		{
			// Select the previous result
			$Search.selected--;
			if ($Search.selected < 0)
				$Search.selected = $Search.results.length - 1;
		}
		
		if ($Search.results[$Search.selected])
			$("#search").val($Search.results[$Search.selected]);
			
		$("#searchResults a")
			.each(function(index){
				
				if ($(this).hasClass('selected'))
					$(this).removeClass('selected');
				
				if (index == $Search.selected)
					$(this).addClass('selected');
					
			});
	},

	/**
	* first
	* 
	* Selects the first result in the search results list
	* @param    bool	reverse		Select the first or last result?
	* @return   nil
	*/
	first: function (reverse)
	{
		$Search.selected = (!reverse) ? 0 : $Search.results.length - 1;
		
		if ($Search.results[$Search.selected])
			$("#search").val($Search.results[$Search.selected]);
			
		$("#searchResults a")
			.each(function(index){
				
				if ($(this).hasClass('selected'))
					$(this).removeClass('selected');
				
				if (index == $Search.selected)
					$(this).addClass('selected');
					
			});
	}
}