// On document load initialize the suggest search.
addLoadListener(InitSuggest);

function InitSuggest()
{
  	// Set input field's autocomplete off and add required event listeners.
	var suggestField = document.getElementById(GetScriptParameter( "inputId" ));
	var suggestFieldSecond = document.getElementById(GetScriptParameter( "inputId2" ));
	
  	if (suggestField != null)
  	{
		suggestField.setAttribute( "autocomplete", "off" );
	 	attachEventListener(suggestField, "keydown", HandleKeyDown, false);
		attachEventListener(suggestField, "blur", BlurSuggest, false);
	}
	
  	if (suggestFieldSecond != null)
  	{
		suggestFieldSecond.setAttribute( "autocomplete", "off" );
	 	attachEventListener(suggestFieldSecond, "keydown", HandleKeyDown, false);
		attachEventListener(suggestFieldSecond, "blur", BlurSuggest, false);
	}
	
	return true;
}


// Handle key presses in input field.
function HandleKeyDown(event)
{
	// Get the event type.
	if (typeof event == "undefined")
	{
		event = window.event;
	}
	
	// Get target
	var target = GetEventTarget(event);
	var target_id = target.id;

	// Handle key presses.
	switch(event.keyCode)
  	{
		case 13:    // enter
		case 27:    // esc
			//StopDefaultAction(event);
			CloseDropdown();
			break;
  		
		case 9:     // tab
		case 16:    // shift
		case 17:    // ctrl
		case 18:    // alt
		case 20:    // caps lock
		case 33:    // page up
		case 34:    // page down
		case 35:    // end
		case 36:    // home
		case 37:    // left arrow
		case 39:    // right arrow
			// Textfield content haven't been changed, so do nothing.
			break;

		case 38:    // up arrow

			var suggestDropdown = document.getElementById("suggestDropdown");
			var suggestDropdownSecond = document.getElementById("suggestDropdownSecond");
	
			// If suggest-box exists...
			if (suggestDropdown != null || suggestDropdownSecond != null)
			{
				if (suggestDropdown != null) {
					var childLis = suggestDropdown.childNodes;
				} else if (suggestDropdownSecond != null) {
					var childLis = suggestDropdownSecond.childNodes;
				}
				var selected = false;
	
				// ...go trough the suggestions...
				for (var i = 0; i < childLis.length; i++)
				{
					// ...when the selected suggestion is found...
					if( childLis[i].className.split(" ")[0] == "suggest_link_over" )
					{
						selected = true;
	
						if (i > 0)
						{
						    UpdateHighlighted(target, childLis, i, i -1);
						}
						
						// Top of the list, move to the end of list.
						else if (i == 0)
						{
						    UpdateHighlighted(target, childLis, 0, childLis.length - 1);
						}
	
						break;
					}
				}

				// If no suggestion was previously selected..
				if (!selected)
				{
				    UpdateHighlighted(target, childLis, -1, childLis.length - 1);
				}
			}

      		StopDefaultAction(event);
			break;

		case 40:    // down arrow
		
			var suggestDropdown = document.getElementById("suggestDropdown");
			var suggestDropdownSecond = document.getElementById("suggestDropdownSecond");
	
			// If suggest-box exists...
			if (suggestDropdown != null || suggestDropdownSecond != null)
			{
				if (suggestDropdown != null) {
					var childLis = suggestDropdown.childNodes;
				} else if (suggestDropdownSecond != null) {
					var childLis = suggestDropdownSecond.childNodes;
				}
				var selected = false;

				// ...go trough the suggestions...
				for (var i = 0; i < childLis.length; i++)
				{

					// ...when the selected suggestion is found...
					if( childLis[i].className.split(" ")[0] == "suggest_link_over" )
					{
						selected = true;

						if (i < childLis.length - 1)
						{
						    UpdateHighlighted(target, childLis, i, i + 1);
						}
						// End of list, move to the top of list.
						else if (i == childLis.length -1)
						{
						    UpdateHighlighted(target, childLis, i, 0);
						}

            			break;
          			}
        		}

				// If no suggestion was previously selected..
				if (!selected)
				{
				    UpdateHighlighted(target, childLis, -1, 0);
				}
			}

			StopDefaultAction(event);
			break;

		case 8:     // backspace
		case 46:    // delete

			if (typeof SuggestTimer != "undefined")
			{
				clearTimeout(SuggestTimer);
			}

			// Get the suggestions.
			SuggestTimer = setTimeout("SearchSuggest('"+target_id+"')", 5); //5ms
			break;

    	// Some other key was pressed.
    	default:

			if (typeof SuggestTimer != "undefined")
			{
				clearTimeout(SuggestTimer);
			}
			
			// Get the suggestions.
			SuggestTimer = setTimeout("SearchSuggest('"+target_id+"')", 5); //5ms
	}

 	return true;
}


// Starts the AJAX request when called by HandleKeyUp().
function SearchSuggest(target_id)
{
	// Create XML-query object.
	var xmlHttpRequest = GetXmlHttpRequestObject();

	// If request is finished (4) or uninitialized (0).
	if( xmlHttpRequest.readyState == 4 || xmlHttpRequest.readyState == 0 )
	{
		
		// Parse the user input.		
		var strQuery = document.getElementById(GetScriptParameter( "inputId" )).value;
		var strQuerySecond = '';
		
		if (GetScriptParameter( "inputId2" ) != "" && document.getElementById(GetScriptParameter( "inputId2" )))
		{
			strQuerySecond = document.getElementById(GetScriptParameter( "inputId2" )).value;
		}
		
		// Send the request if input is not empty after trim.
		if ( strQuery.trim().length > 0 && target_id == GetScriptParameter("inputId"))
		{
			// Encode
			strQuery = Encode( strQuery );
			
			// Send the request.
			var strQuery = "http://" +	GetScriptParameter( "sitePrefix" ) +
  						   "suggest/" + GetScriptParameter( "suggestType" ) + "/" + 
  						   strQuery + "/";
			if( GetScriptParameter( "restriction" ) != "" )
			{
				strQuery += GetScriptParameter( "restriction" ) + "/";
			}
			xmlHttpRequest.open("GET", strQuery, true);

			// Handle the result.
			xmlHttpRequest.onreadystatechange = function() { GenerateDropdown( xmlHttpRequest, null ) }; 
			xmlHttpRequest.send(null); // Using GET, send null.
		}
		else if ( strQuerySecond.trim().length > 0 && target_id == GetScriptParameter("inputId2"))
		{
			// Encode
			strQuery = Encode( strQuerySecond );
			
			// Send the request.
			var strQuery = "http://" +	GetScriptParameter( "sitePrefix" ) +
  						   "suggest/" + GetScriptParameter( "suggestType2" ) + "/" + 
  						   strQuery + "/";
			if( GetScriptParameter( "restriction" ) != "" )
			{
				strQuery += GetScriptParameter( "restriction" ) + "/";
			}
			xmlHttpRequest.open("GET", strQuery, true);

			// Handle the result.
			xmlHttpRequest.onreadystatechange = function() { GenerateDropdown( xmlHttpRequest, '2' ) }; 
			xmlHttpRequest.send(null); // Using GET, send null.
		} else {
			CloseDropdown();
		}
	}
    return true;
}


// Create the box containing the suggestions.
function GenerateDropdown(xmlHttpRequest, ordinal)
{
	// If request is finished (4) succesfully (200).
	if( xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200)
    {
	  	CloseDropdown();
	  	
	  	// Input field
	  	var input = document.getElementById( GetScriptParameter( "inputId" ) );
	  	var input_second = document.getElementById( GetScriptParameter( "inputId2" ) );
		
	  	// Results of the XML-query.
		strResponse = xmlHttpRequest.responseText.split("\n");
		
		// Check what suggest field are we generating
		if (!ordinal)
		{
			// Create suggestion list (ul).
			var newUl = document.createElement("ul");
			newUl.setAttribute("id", "suggestDropdown");
			newUl.autoCompleteInput = input;
			newUl.style.position = "absolute";
			newUl.style.left = GetPosition(input)[0] + 1 + "px";
			newUl.style.top = GetPosition(input)[1] + input.offsetHeight - 1 + "px";
			newUl.style.width = input.offsetWidth + "px";
		}
		else if (ordinal == '2')
		{
			// Create second suggestion list (ul).
			var newUl = document.createElement("ul");
			newUl.setAttribute("id", "suggestDropdownSecond");
			newUl.autoCompleteInput = input_second;
			newUl.style.position = "absolute";
			newUl.style.left = GetPosition(input_second)[0] + 1 + "px";
			newUl.style.top = GetPosition(input_second)[1] + input_second.offsetHeight - 1 + "px";
			newUl.style.width = input_second.offsetWidth + "px";
		}
		
		// Create list contents (li).
		for (var i = 0; i < strResponse.length -1; i++)
 		{
			// Split the response string to obtain class-names for this div.
			var str_inner = strResponse[i].split(":");
			
			// Create new li.
			var newLi = document.createElement("li");
			
			// Set the text value into li.
			//newLi.appendChild( document.createTextNode( str_inner[0] ) );
			var newP = document.createElement("span");
			newP.innerHTML = str_inner[0];
			newLi.appendChild(newP);
			
			// Detect the browser.
			var browserDetected = IdentifyBrowser();
			
			// Attach event listeners if the browser supports them.
			if (browserDetected != "ie5mac")
			{
				attachEventListener(newLi, "mouseover", MouseoverDropdown, false);
				attachEventListener(newLi, "mouseout", MouseoutDropdown, false);
				attachEventListener(newLi, "mousedown", MousedownDropdown, false);
			}
			
			// Set the title of the li.
			// Remember to strip HTML-tags from the title of li-element
			newLi.setAttribute( "title", "" );
			if (str_inner[1] != 'overflow' || str_inner[2] != '')
			{				
				newLi.title = str_inner[2].replace(/(<([^>]+)>)/ig, "") + ': ' + str_inner[0].replace(/(<([^>]+)>)/ig, "");
			} 
			else
			{
				newLi.title = str_inner[0].replace(/(<([^>]+)>)/ig, "");
			}
			
			// Set the class of the li.
			newLi.className = 'suggest_link ' + str_inner[1];
			
		    // Insert li into ul.
		    newUl.appendChild(newLi);
		}

		// Inject the ul into the page.
		if (newUl.firstChild != null)
		{
			document.getElementsByTagName("body")[0].appendChild(newUl);
		}
	}

	return true;
}


// Update the highlighted list item and do all the required hidden magic under the hood.
// Usage:
// 		target = object which event listener was raised
// 		list = list of suggestions
// 		old = index of old highlighted item (-1 for no previous selection)
// 		new = index of new highlighted item
//
function UpdateHighlighted(target, list, oldIndex, newIndex)
{
	// Set the current highlighted list item to normal mode.
	if( oldIndex > -1 )
	{
		list[oldIndex].className = list[oldIndex].className.replace("suggest_link_over", "suggest_link");
	}

    // Highlight the new one.
    list[newIndex].className = list[newIndex].className.replace("suggest_link", "suggest_link_over");
							    			
	// Make the selected suggestion the target unless it's the overflow-message.
	if (list[newIndex].className.split(" ")[1] != 'overflow')
	{
		// Remember to strip HTML-tags from the span element
		//target.value = list[newIndex].firstChild.nodeValue.split(" [")[0];
	  	target.value = list[newIndex].firstChild.innerHTML.split(" [")[0].replace(/(<([^>]+)>)/ig, "").replace(/&amp;/ig, "&");
	}

	// Update the value of the hidden fields required for redirecting.
    if( list[newIndex].className.split(" ")[1] != 'overflow' && document.getElementById("searchobject") )
    {
    	document.getElementById("searchobject").value = list[newIndex].className.split(" ")[1];
    	
	    if( list[newIndex].className.split(" ")[2] != undefined && document.getElementById("parentobject") )
	    {
    		document.getElementById("parentobject").value = list[newIndex].className.split(" ")[2];
	    }
    }
    
    return true;    
}

function MouseoverDropdown(event)
{
	// Get the event.
	if (typeof event == "undefined")
	{
		event = window.event;
	}

  	var target = GetEventTarget(event);

	while (target.nodeName.toLowerCase() != "li")
	{
		target = target.parentNode;
	}

	var childLis = target.parentNode.childNodes;

	// Set class of all the other list items to "suggest_link".
	for (var i = 0; i < childLis.length; i++)
	{
    	childLis[i].className = childLis[i].className.replace("suggest_link_over", "suggest_link");
	}

	// Set class of the target list item to "suggest_link_over".
	target.className = target.className.replace("suggest_link", "suggest_link_over");
  	return true;
}


function MouseoutDropdown(event)
{
	if (typeof event == "undefined")
  	{
    	event = window.event;
  	}

  	var target = GetEventTarget(event);

  	while (target.nodeName.toLowerCase() != "li")
  	{
    	target = target.parentNode;
  	}

  	target.className = target.className.replace("suggest_link_over", "suggest_link");
  	return true;
}


function MousedownDropdown(event)
{
	if (typeof event == "undefined")
	{
    	event = window.event;
	}

	var target = GetEventTarget(event);

	while (target.nodeName.toLowerCase() != "li")
	{
    	target = target.parentNode;
	}

    // Update the values for hidden field (if present).
    var classes = target.className.split(" ");
    if( document.getElementById("searchobject") )
    {
    	document.getElementById("searchobject").value = classes[1];
    	if( document.getElementById("parentobject") && classes[2] )
	    {
    		document.getElementById("parentobject").value = classes[2];
	    }
    }

    // If class == 'overflow', don't add anything...
    if (classes[1] != 'overflow')
    {
	  	// ...else set the value of the list item into the input field.
	  	// Remember to strip HTML-tags from the span element
	  	target.parentNode.autoCompleteInput.value = target.firstChild.innerHTML.split(" [")[0].replace(/(<([^>]+)>)/ig, "").replace(/&amp;/ig, "&"); //target.firstChild.nodeValue.split(" [")[0];
    }

  	CloseDropdown();
  	return true;
}


function BlurSuggest()
{
	if (typeof SuggestTimer != "undefined")
	{
    	clearTimeout(SuggestTimer);
	}

	CloseDropdown();
	return true;
}


function CloseDropdown()
{
	var suggestDropdown = document.getElementById("suggestDropdown");

	if (suggestDropdown != null)
	{
    	suggestDropdown.parentNode.removeChild(suggestDropdown);
	}
	
	var suggestDropdownSecond = document.getElementById("suggestDropdownSecond");

	if (suggestDropdownSecond != null)
	{
    	suggestDropdownSecond.parentNode.removeChild(suggestDropdownSecond);
	}

	return true;
}


function GetEventTarget(event)
{
	var targetElement = null;

	if (typeof event.target != "undefined")
	{
		targetElement = event.target;
	}
	else
	{
		targetElement = event.srcElement;
	}

	while (targetElement.nodeType == 3 && targetElement.parentNode != null)
	{
		targetElement = targetElement.parentNode;
	}

	return targetElement;
}


function StopDefaultAction(event)
{
	event.returnValue = false;

	if (typeof event.preventDefault != "undefined")
	{
		event.preventDefault();
	}

	return true;
}


function GetPosition(theElement)
{
	var positionX = 0;
	var positionY = 0;

	while (theElement != null)
	{
		positionX += theElement.offsetLeft;
		positionY += theElement.offsetTop;
		theElement = theElement.offsetParent;
	}
	return [positionX, positionY];
}


function IdentifyBrowser()
{
	var agent = navigator.userAgent.toLowerCase();

	if (typeof navigator.vendor != "undefined" && navigator.vendor == "KDE" && typeof window.sidebar != "undefined")
	{
		return "kde";
	}
	else if (typeof window.opera != "undefined")
	{
		var version = parseFloat(agent.replace(/.*opera[\/ ]([^ $]+).*/, "$1"));

		if (version >= 7)
		{
			return "opera7";
		}
		else if (version >= 5)
		{
			return "opera5";
		}

    	return false;
	}
	else if (typeof document.all != "undefined")
	{
		if (typeof document.getElementById != "undefined")
		{
			var browser = agent.replace(/.*ms(ie[\/ ][^ $]+).*/, "$1").replace(/ /, "");

			if (typeof document.uniqueID != "undefined")
			{
				if (browser.indexOf("5.5") != -1)
				{
					return browser.replace(/(.*5\.5).*/, "$1");
				}
				else
				{
					return browser.replace(/(.*)\..*/, "$1");
				}
			}
			else
			{
				return "ie5mac";
			}
		}
		return false;
	}
	else if (typeof document.getElementById != "undefined")
	{
    	if (navigator.vendor.indexOf("Apple Computer, Inc.") != -1)
		{
			if (typeof window.XMLHttpRequest != "undefined")
			{
				return "safari1.2";
			}

      		return "safari1";
		}
		else if (agent.indexOf("gecko") != -1)
		{
			return "mozilla";
		}
  	}

	return false;
}


function GetScriptParameter( parameter )
{
	var elementArray = document.getElementsByTagName("meta");

 	for (var i = 0; i < elementArray.length; i++)
	{
		if( elementArray[i].getAttribute( "name" ) && elementArray[i].name.toLowerCase() == parameter.toLowerCase() )
		{
			
			if( elementArray[i].getAttribute( "content" ) )
			{
				return elementArray[i].getAttribute( "content" );
			}
		}
	}

	return "";
}

// Get the browser specific XmlHttpRequest Object
function GetXmlHttpRequestObject()
{
	if( window.XMLHttpRequest )
	{
		return new XMLHttpRequest();
	}
	else if( window.ActiveXObject )
	{
		return new ActiveXObject( "Microsoft.XMLHTTP" );
	}
	else
	{
		return "";
	}
}


// Escapes the string containing the user input.
function Encode( str ) 
{
    if( encodeURIComponent ) 
    {
        return encodeURIComponent( str );
    }

    if( escape ) 
    {
        return escape( str );
    }
    
    return "";
}

