// URLs
var baseUrl  =              '/intellisearch.html?q=';
var seminarDetailsBaseUrl = '/user/seminar/details.html?id=';
var searchSeminarUrl      = '/suchergebnisse.html?searchq=';

// The XMLHTTPRequest object
var xHttpObj = GetXHttpObject();

// Timer for starting the request
var startTimer   = null;
var startTimeout = 150;

// old query is saved for checking if anything has changed
var oldQuery = null;

// cache for elements that are need all the time
var formInput;
var divOutput;

// Maximum lenght of title in characters
var maxTitleLen = 40;

// The result cache
var resultCache = new Object();

// Global flag used to disable IntelliSearch :-(
var disable = false;

//
// Trigger the search (start timeout until search begins).
// Useful for very fast typers...
//
function StartIntelliSearch()
{
	// If xHttpObj is null or we've been disabled, no need to go on.
	if(xHttpObj != null && !disable)
	{
		if(startTimer != null)
			window.clearTimeout(startTimer);
		startTimer = window.setTimeout("DoIntelliSearch();", startTimeout);
	}
}

//
// Start the actual search,
//
function DoIntelliSearch()
{
	// First time: Get elements and install div
	if(formInput == null || divOutput == null)
	{
		formInput = document.getElementById('intellisearch_input');
		divOutput = document.getElementById('intellisearch_output');

		if(formInput == null || divOutput == null)
			return;

		// Disable autocompletition for the input field
		formInput.autoComplete = 'off';

		// Set CSS properties
		SetStyleForDiv(divOutput);
	}

	// Create query
	query = Trim(formInput.value);
	if(oldQuery == null || query != oldQuery)
	{
		oldQuery = query;
		if(resultCache[query] != null)
		{
			var idArr    = resultCache[query][0];
			var simArr   = resultCache[query][1];
			var titleArr = resultCache[query][2];
			var linkArr  = resultCache[query][3];

			UpdateResultDiv(idArr, simArr, titleArr, linkArr);
			ShowElement(divOutput);
			return;
		}

		// Abort pending old query and start
		xHttpObj.abort();
		xHttpObj.open('GET', baseUrl + escape(query), true);
		xHttpObj.onreadystatechange = ProcessServerResponse;
		xHttpObj.send(null);
	}
}

//
// Called when query has succeeded. Fills the div with the query
// results.
//
function ProcessServerResponse()
{
	if(xHttpObj.readyState == 4)
	{
		var responseText = Trim(xHttpObj.responseText);
		if(responseText.length > 0)
		{
			var lines = xHttpObj.responseText.split('\n');

			// Create Arrays for cache
			var idArr    = new Array();
			var simArr   = new Array();
			var titleArr = new Array();
			var linkArr  = new Array();

			for(var i=0; i<lines.length-1; i++)
			{
				var record = lines[i].split('\t');
				if(record.length == 4)
				{
					idArr.push(record[0]);
					simArr.push(record[1]);
					titleArr.push(record[2]);
					linkArr.push(record[3]);
				}
			}

			if(idArr.length > 0)
			{
				// Fill cache and update view
				resultCache[query] = new Array(idArr, simArr, titleArr, linkArr);
				UpdateResultDiv(idArr, simArr, titleArr, linkArr);
				ShowElement(divOutput);
			}
		}
		else
			HideElement(divOutput);
	}
}

//
// Update the result div with new results, either from server
// obtained through the cache.
//
function UpdateResultDiv(idArr, simArr, titleArr, linkArr)
{
	if(idArr.length     != simArr.length   ||
		simArr.length   != titleArr.length ||
		titleArr.length != linkArr.length)
		return;

	RemoveAllChildNodes(divOutput);

	// Add images
	var imgNode1 = document.createElement('img');
	imgNode1.setAttribute('src', '/images/Intellisearch_Bar.gif');
	imgNode1.setAttribute('width',  '224');
	imgNode1.setAttribute('height', '13');
	divOutput.appendChild(imgNode1);


	var	aCloseNode = document.createElement('a');
	aCloseNode.setAttribute('href', 'javascript:DisableIntelliSearch()');

	var imgNode2 = document.createElement('img');
	imgNode2.setAttribute('src', '/images/Intellisearch_Close.gif');
	imgNode2.setAttribute('width',  '13');
	imgNode2.setAttribute('height', '13');
	imgNode2.setAttribute('border',  '0');
	aCloseNode.appendChild(imgNode2);
	divOutput.appendChild(aCloseNode);

	divOutput.appendChild(document.createElement('br'));

	var ulEl = document.createElement('ul');
	SetStyleForUl(ulEl);
	divOutput.appendChild(ulEl);

	for(var i=0; i<idArr.length; i++)
	{
		var liEl = document.createElement('li');
		ulEl.appendChild(liEl);
		liEl.appendChild(CreateStyledLinkNode(idArr[i], simArr[i], titleArr[i], linkArr[i]));
	}
}

//
// Disable the search completely. Will be available on next page
// reload.
//
function DisableIntelliSearch()
{
	disable = true;
	HideElement(divOutput);
}

//
// Set up CSS dynamically
//
function SetStyleForDiv(divNode)
{
	var s = divNode.style;
	var x = FindPosX(formInput);
	var y = FindPosY(formInput) + formInput.offsetHeight + 2;

	s.top             = y + 'px';
	s.left            = x + 'px';

	if(navigator.userAgent.toLowerCase().indexOf('msie') > -1)
		s.width           = '245px';

	s.padding         = '0px';
	s.border          = 'solid #ff9900 1px';
	s.backgroundColor = '#ffffff';
	s.filter          = 'alpha(opacity=90)';
	s.opacity         = '0.9';
}

//
// Set up CSS dynamically
//
function SetStyleForA(aNode)
{
	var s = aNode.style;

	s.color          = '#990000';
	s.textDecoration = 'underline';
	s.fontFamily     = 'arial';
	s.fontSize       = '10px';
}

//
// Set up CSS dynamically
//
function SetStyleForUl(ulNode)
{
	var s = ulNode.style;

	s.color         = '#990000';
	s.margin        = '0px';
	s.paddingLeft   = '20px';
	s.paddingRight  = '2px';
	s.paddingTop    = '2px';
	s.paddingBottom = '2px';
	s.listStyleType = 'square';
}

//
// Set up CSS dynamically
//
function SetStyleForQueryText(textNode)
{
	var s = textNode.style;

	s.backgroundColor = 'yellow';
}

//
// Utility function to create a link element (pointing to seminar
// detail page). Some other features as cutting the title to
// correct length, emphasizing the search query etc.
//
function CreateStyledLinkNode(id, numSimilar, title, link)
{
	var divNode      = document.createElement('div');
	var aNodeTitle   = document.createElement('a');
	var aNodeSimilar = document.createElement('a');

	SetStyleForA(aNodeTitle);
	SetStyleForA(aNodeSimilar);

	var hrefAttrTitle   = document.createAttribute('href');
	var hrefAttrSimilar = document.createAttribute('href');

	var hrefAttrTitleValue   = link;
	var hrefAttrSimilarValue = searchSeminarUrl + escape(title);

	hrefAttrTitle.nodeValue   = hrefAttrTitleValue;
	hrefAttrSimilar.nodeValue = hrefAttrSimilarValue;

	aNodeTitle.setAttributeNode(hrefAttrTitle);
	aNodeSimilar.setAttributeNode(hrefAttrSimilar);
	aNodeTitle.appendChild(GetTitleTextDiv(title));

	var bNode = document.createElement('div');
	bNode.style.color = '#666666';
	bNode.appendChild(document.createTextNode('[' + numSimilar + ' weitere]'));
	aNodeSimilar.appendChild(bNode);

	divNode.appendChild(aNodeTitle);
	if(numSimilar > 1)
	{
		divNode.appendChild(document.createElement('br'));
		divNode.appendChild(aNodeSimilar);
	}

	return divNode;
}

//
// Do the string fiddling for the title link element.
//
function GetTitleTextDiv(title)
{
	var spanNode = document.createElement('span');

	if(title.length > maxTitleLen)
	{
		var queryIndex = title.toLowerCase().indexOf(oldQuery.toLowerCase());

		if(queryIndex + oldQuery.length <= maxTitleLen)
			title = title.substr(0, maxTitleLen) + '...';
		else
		{
			var remain = maxTitleLen - oldQuery.length;
			var start  = Math.max(0, queryIndex - Math.round(remain/2));

			title     = title.substr(start, title.length-start);
			if(start != 0)
				title = '...' + title;

			if(title.length-3 > maxTitleLen)
				title = title.substr(0, maxTitleLen) + '...';
		}
	}

	var queryIndex = title.toLowerCase().indexOf(oldQuery.toLowerCase());
	if(queryIndex >= 0)
	{
		var strBefore = title.substr(0, queryIndex);
		var str       = title.substr(queryIndex, oldQuery.length);
		var strAfter  = title.substr(queryIndex+oldQuery.length, title.length-1);

		if(strBefore.length > 0)
			spanNode.appendChild(document.createTextNode(strBefore));

		var queryNode = document.createElement('span');
		SetStyleForQueryText(queryNode);
		queryNode.appendChild(document.createTextNode(str));
		spanNode.appendChild(queryNode);

		if(strAfter.length > 0)
			spanNode.appendChild(document.createTextNode(strAfter));
	}
	else
		spanNode.appendChild(document.createTextNode(title));


	return spanNode;
}

//
// Remove all child nodes of given element using DOM.
//
function RemoveAllChildNodes(node)
{
	while(node.hasChildNodes())
		node.removeChild(node.firstChild);
}

//
// Get the XMLHttpRequest.
//
function GetXHttpObject()
{
	var xmlhttp = null;
    if(window.XMLHttpRequest)
    {
		try {
			xmlhttp = new XMLHttpRequest();
		} catch(e) {
			xmlhttp = false;
		}
    }
    else if(window.ActiveXObject)
    {
		try {
			xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
      	} catch(e) {
			try {
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e) {
				xmlhttp = false;
			}
		}
	}
  	return xmlhttp;
}

//
// Find the absolute X position of a given element.
//
function FindPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj      = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

//
// Hide div. Used several times.
//
function HideElement(e)
{
	if(e != null)
		e.style.visibility = 'hidden';
}

//
// Show div. Used several times.
//
function ShowElement(e)
{
	if(e != null)
		e.style.visibility = 'visible';
}

//
// Find the absolute Y position of a given element.
//
function FindPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj     = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}

//
// Trim a string
//
function Trim(s)
{
	s = s.replace(/^\s+/g, '');
 	s = s.replace(/\s+$/g, '');

 	return s;
}