// this file contains functions for a search preview
// author:    Dominik Scholz, schlotzz@go4u.de
// changed:   2010-01-14


var SEARCH = {

	// private vars
	url: 'items/objectsearch/ajax.preview.php',
	http: null,
	loading: false,
	lastSearch: null,
	object: null,
	results: [],
	highlight: '',
	selected: -1,
	maxResults: 11,


	// create result field, if not present
	create: function()
	{
		if (!document.getElementById('searchresult'))
		{
			var mydiv = document.createElement('div');
			var myid  = document.createAttribute('id');
			myid.nodeValue = 'searchresult';
			mydiv.setAttributeNode(myid);
			document.body.insertBefore(mydiv, document.body.firstChild);
		}
	},


	// set position of result list
	position: function()
	{
		var o = document.getElementById('searchresult');
		var pos = this.absolutePosition(this.object);
		o.style.left = pos[0]+'px';
		o.style.top =  (pos[1]+this.object.offsetHeight)+'px';
		o.style.width = (this.object.offsetWidth-2)+'px';
	},


	// handle click on result list item
	click: function(value)
	{
		this.object.value = decodeURIComponent(value);
		this.object.parentNode.parentNode.submit();
	},


	// handle key down event
	keyDown: function(evt, obj)
	{
		var keycode = this.keyCode(evt);

		if (keycode == 38)
		{
			this.up();
			return false;
		}

		if (keycode == 40)
		{
			this.down();
			return false;
		}

		return true;
	},


	// handle key up event
	keyUp: function(evt, obj)
	{
		var keycode = this.keyCode(evt);

		if (keycode == 38 || keycode == 40)
			return false;

		this.preview(obj);
		return true;
	},


	// scroll item up
	up: function()
	{
		if (this.selected < 0)
			return;

		this.selected--;
		this.resultsShow();

		if (this.selected >= 0)
			this.object.value = this.results[this.selected];
		else
			this.object.value = this.lastSearch;
	},


	// scroll down
	down: function()
	{
		if (this.selected+1 == this.results.length)
			return;

		this.selected++;
		this.resultsShow();
		this.object.value = this.results[this.selected];
	},


	// user pressed enter key
	enter: function()
	{
		if (this.selected >= 0)
		{
			this.click(this.results[this.selected]);
			return;
		}

		this.click(this.highlight);
	},


	// show preview of search
	preview: function(o)
	{
		this.create();

		if (o.value.length < 3)
		{
			this.resultsHide();
			return;
		}

		if (this.selected >= 0)
		{
			if (o.value == this.results[this.selected])
				return true;
		}
		else
		{
			if (o.value == this.lastSearch)
				return true;
		}

		if (this.loading)
			return;

		this.object = o;
		this.resultsLookUp(o.value);
	},


	// hide results
	resultsHide: function()
	{
		this.lastSearch = null;
		var o = document.getElementById('searchresult');
		o.style.display = 'none';
	},


	// get keycode of event
	keyCode: function(evt)
	{
		if (window.event)
			return window.event.keyCode;
		else if (evt)
			return evt.which;
		return null;
	},


	// do ajax call to look up search results
	resultsLookUp: function(value)
	{
		if (value == this.lastSearch)
			return;

		this.loading = true;
		this.lastSearch = value;

		this.object.className = 'searchformloading';

		this.http = this.createRequestObject();
		this.http.open('POST', this.url, true);
		this.http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		this.http.onreadystatechange = new Function('fx', 'SEARCH.receive("'+encodeURIComponent(value)+'")');
		this.http.send('query='+encodeURIComponent(value));
	},


	// receive ajax call data
	receive: function(highlight)
	{
		highlight = decodeURIComponent(highlight);

		if(this.http.readyState != 4)
			return;

		var response = unescape(this.http.responseText);
		var results = new Array();
		results = response.split("\n");
		results.pop();
		results.sort(this.sort);

		this.loading = false;

		if (this.object.value != highlight)
			this.preview(this.object);

		this.object.className = '';

		this.selected = -1;
		this.results = results;
		this.highlight = highlight;

		this.resultsShow();
	},


	// render result list
	resultsShow: function()
	{
		highlight = this.highlight;
		highlight = highlight.replace(/\&/g, '&amp;');
		highlight = highlight.replace(/\</g, '&lt;');
		highlight = highlight.replace(/\>/g, '&gt;');

		var html = '';

		if (this.results.length <= 0)
			html += '<span class="searchNoResults">keine Ergebnisse</span>';

		var anzahl = this.results.length;

		var start = this.selected-Math.floor(this.maxResults/2);
		if (start+this.maxResults>anzahl)
			start = anzahl-this.maxResults;
		if (start < 0)
			start = 0;

		var ende = start+this.maxResults-1;
		if (start+this.maxResults==anzahl)
			ende++;
		if (ende > anzahl)
			ende = anzahl;

		if ((this.selected-Math.floor(this.maxResults/2) >= 0) && (this.maxResults<anzahl))
		{
			html += '<span class="searchUp">&nbsp;</span>';
			start++;
		}

		for (var i=start; i<ende; i++)
		{
			value = this.results[i];

			if (i == this.selected)
				html += '<span class="searchSelected">';

			html += '<a href="javascript:;" onMouseDown="SEARCH.click(\''+encodeURIComponent(value)+'\');">'
			value = value.replace(/\&/g, '&amp;');
			value = value.replace(/\</g, '&lt;');
			value = value.replace(/\>/g, '&gt;');
			value = this.replaceIt(value, highlight);
			html += value;
			html += '</a>';

			if (i == this.selected)
				html += '</span>';
		}

		if (i<anzahl)
			html += '<span class="searchDown">&nbsp;</span>';

		var o = document.getElementById('searchresult');
		o.innerHTML = html;

		this.position();

		if (this.object.value.length >= 3)
			o.style.display = 'block';
	},


	// create ajax object
	createRequestObject: function()
	{
		if (navigator.appName == "Microsoft Internet Explorer")
		{
			try
			{
				return new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch (e)
			{
				return new ActiveXObject("Microsoft.XMLHTTP");
			}
		}
		else
		{
			return new XMLHttpRequest();
		}
	},


	// own replace function
	replaceIt: function(string, suchen)
	{
		oldpos = 0;
		ausgabe = "" + string;
		while (ausgabe.toLowerCase().indexOf(suchen.toLowerCase(), oldpos)>-1)
		{
			pos= ausgabe.toLowerCase().indexOf(suchen.toLowerCase(), oldpos);
			oldpos = pos + suchen.length+7;
			ausgabe = "" + (ausgabe.substring(0, pos) + '<b>' + ausgabe.substring(pos,pos+suchen.length) + '</b>' + ausgabe.substring((pos + suchen.length), ausgabe.length));
		}
		return ausgabe;
	},


	// sort function for keywords
	sort: function(a, b)
	{
		var a = a.toLowerCase();
		var b = b.toLowerCase();
		return (a==b)? 0:(a>b)? 1:-1;
	},
	

	// get absolute position of html node
	absolutePosition: function(element)
	{
		var valueT = 0;
		var valueL = 0;
		do
		{
			valueT += element.offsetTop  || 0;
			valueL += element.offsetLeft || 0;
			element = element.offsetParent;
			if (!element)
				continue;
			if(element.tagName == 'BODY')
				break;
			var p = element.style.position;
			if (p == 'relative' || p == 'absolute')
				break;
		}
		while (element);
		return [valueL, valueT];
	}

	
};




