function loadKeywordSearch(surface)
{
	new KeywordSearch(surface);	
}

var KeywordSearch = Class.create();

KeywordSearch.prototype = {
	surface: null,
	searchbox: null,
	submitbtn: null,
	itemcount: null,
	itemcount_surface: null,
	input_timeout: null,
	items: new Array(),
		
	initialize: function(surface)
	{
		this.surface = $(surface);
		
		this.itemcount = 0;

		var closebtn = Builder.node('a', {id: 'close-quick-search'}, 'close');
		var form = Builder.node('div', {id: 'SearchItemContainer'});
														
		this.itemcount_surface = Builder.node('span', {id: 'KeywordSearchItemCount'}, ''+this.itemcount);

		var header = Builder.node('div', {id: 'KeywordSearchHeader'},
													[
														Builder.node('h1', {}, 'Search'),
														Builder.node('h2', {}, 
																			[
																				Builder.node('span', {}, 'Tracks found: '),
																				this.itemcount_surface
																			]),
														Builder.node('h2', {id: 'SearchShowItems'}, '(Show tracks)')
													]);
		
		
		this.surface.appendChild(header);
		this.surface.appendChild(form);
		this.surface.appendChild(closebtn);
		
		// Add an item
		var item = new SearchItem(this);
		this.items.push(item);
		
		$('KeywordSearch').hide();
		$('search').observe('click', function( event ) 
																	{ 
																		$('KeywordSearch').toggle(); 
																		$('ColumnBrowser').hide();
																		
																		if($('KeywordSearch').visible())
																		{
																			$('main-body').fade({ duration: 0.3, to:0.1});
																		}
																		else
																		{
																			$('main-body').fade({ duration: 0.3, to:1});
																		}
																		event.stop();
																	}
												);
		
		// Setup event listeners
		Event.observe(this.surface, 'mouseup', this.click.bindAsEventListener(this));
		Event.observe(this.surface, 'mouseover', this.mouseOver.bindAsEventListener(this));
		Event.observe(this.surface, 'mouseout', this.mouseOut.bindAsEventListener(this));
		Event.observe($('SearchShowItems'), 'click', this.showItems.bindAsEventListener(this));
		Event.observe(closebtn, 'click', this.hideSurface.bindAsEventListener(this));
		
		//this.ajaxRequest();
	},
	
	showItems: function(e)
	{
		
		// DOM Test
		if($('ItemsList') == null)
		{
			alert("Config Error - Missing Columns module!");
			return	
		}
		
		var searchterms = this.getSearchTerms();
		var params = '';
		
		for(var i=0; i < searchterms.length; i++)
		{
			if(i > 0)
				params += ', ';
				
			params += searchterms[i];
		}
		
		$('main-body').update( '' );
		$('KeywordSearch').hide();
		$('main-body').fade({ duration: 0.3, to:1});
		
		// Make the request
		new Ajax.Updater('main-body', '/columns/search_items', {
			  method: 'post',
			  parameters: 'input='+params,
			  evalScripts: true,
			onComplete: function() { document.fire('Search:Complete'); }
		});
	},
	
	click: function(e)
	{
		if(e.target == this.surface)
			this.items[this.items.length-1].focus();	
	},
	
	mouseOver: function(e)
	{
		if(e.originalTarget == this.surface)
			document.body.style.cursor = 'text';
	},
	
	mouseOut: function(e)
	{
		if(e.originalTarget == this.surface)
			document.body.style.cursor = 'default';	
	},
	
	addSearchTerm: function(item)
	{
		if(this.items[this.items.length - 1] != item)
		{
			// this is an edit action so we should throw away all items to the right in the array
			var found = false;
			for(var i=0; i < this.items.length; i++)
			{
				if(found)
					this.items[i].remove();
				
				if(this.items[i] == item)
					found = true;
			}
		}
		
		var item = new SearchItem(this);
		this.items.push(item);
		item.focus();
		
		this.ajaxRequest();
	},
	
	ajaxRequest: function()
	{
		// Update the count
		var url = '/columns/search';
		
		var searchterms = this.getSearchTerms();
		var params = '';
		
		for(var i=0; i < searchterms.length; i++)
		{
			if(i > 0)
				params += ', ';
				
			params += searchterms[i];
		}
		
		new Ajax.Request(url, {
		  method: 'post',
		  parameters: 'input='+params,
		  onSuccess: this.ajaxResponse.bind(this)
		});
	},
	
	ajaxResponse: function(transport)
	{
		var json = transport.responseText.evalJSON();
		$('KeywordSearchItemCount').update(json.itemcount);
	},
	
	getSearchTerms: function(item)
	{
		var searchterms = new Array();
		
		var found = false;
		
		for(var i=0; i < this.items.length; i++)
		{
			if(this.items[i] == item)
				found = true;
				
			if(!found)
				searchterms.push(this.items[i].getSearchTerm());	
		}
		
		return searchterms;
	},
	
	remove: function(item)
	{
		var olditems = this.items;
		
		this.items = new Array();
		
		for(var i=0; i < olditems.length; i++)
		{
			if(olditems[i] != item)
				this.items.push(olditems[i]);	
		}
		
		this.ajaxRequest();
	},

	hideSurface: function(e)
	{
		$('KeywordSearch').hide(); 
		$('ColumnBrowser').hide();
		
		$('main-body').fade({ duration: 0.3, to:1});
		e.stop();
	}
}

//////// SEARCH ITEM //////////

var SearchItem = Class.create();

SearchItem.prototype = {
	surface: null,
	inputbox: null,
	suggestions: null,
	delete_surface: null,
	myParent: null,
	currentindex: null,
	
	initialize: function(p)
	{
		this.myParent = p;
		
		this.currentindex = 0;
		
		this.inputbox = Builder.node('input', {className: 'searchiteminput', type: 'text'});
		this.label = Builder.node('div', {className: 'searchitemlabel'});
		this.suggestions = Builder.node('ul', {className: 'searchitemsuggestion'});
		this.delete_surface = Builder.node('div', {className: 'searchitemdelete'}, '[x]');
		this.surface = Builder.node('div', {className: 'searchitem'},
																			[
																				this.delete_surface,
																				Builder.node('div', {className: 'searchitembody'},
																									[
																										this.inputbox,
																										this.label,
																										Builder.node('div', {className: 'searchsuggestionscontainer'},
																																		[
																																			this.suggestions
																																		])
																									])
																			]
																);

		$('SearchItemContainer').appendChild(this.surface);
		
		Event.observe(this.inputbox, 'keyup', this.keyboardInput.bindAsEventListener(this));
		Event.observe(this.delete_surface, 'click', this.deleteClick.bindAsEventListener(this));
		Event.observe(this.label, 'click', this.labelClick.bindAsEventListener(this));
	},
	
	labelClick: function(e)
	{
		this.inputbox.show();
		this.label.hide();
		this.suggestions.show();
	},

	deleteClick: function(e)
	{
		this.remove();
	},
	
	remove: function()
	{
		var thisObj = this;
		
		new Effect.Opacity	(this.surface, 
												{
													from: 1.0, 
													to: 0.0, 
													duration: 0.5,
													afterFinish: function() {
														this.surface.remove();
														this.myParent.remove(this);
													}.bind(this)
												});
	},

	keyboardInput: function(e)
	{
		if(e.keyCode == 38 || e.keyCode == 40)
		{
			// Handle UP/DOWN actions
			
			if(e.keyCode == 38)
			{
				this.currentindex--;
				
				if(this.currentindex < 0)
					this.currentindex = 0;
			}
			else if(e.keyCode == 40)
			{
				this.currentindex++;
				
				if(this.currentindex >= $(this.suggestions).childElements().length)
					this.currentindex = $(this.suggestions).childElements().length - 1;	
			}
			
			this.update();
			
			return;
		}
		
		if(e.keyCode == 13)
		{
			// Handle Enter action
			if($(this.suggestions).childElements().length > 0)
				this.suggestionSelected($(this.suggestions).childElements()[this.currentindex].innerHTML);
				
			return;
		}
		
		if(e.keyCode == 27)
		{
			// Handle escape action
			this.inputbox.value = '';
			this.clearSuggestions();
			
			return;	
		}
		
		// Cancel the time as the user has started typing again
		clearTimeout(this.input_timeout);
		
		// Restart the timeout as the user has stopped typing
		this.input_timeout = setTimeout(this.ajaxRequest.bind(this), 200);
	},
	
	ajaxRequest: function()
	{
		var url = '/columns/suggest';
		
		var searchterms = this.myParent.getSearchTerms(this);
		var params = '';
		
		for(var i=0; i < searchterms.length; i++)
		{
			if(i > 0)
				params += ', ';
				
			params += searchterms[i].replace(' ', '+');
		}
		
		new Ajax.Request(url, {
		  method: 'post',
		  parameters: 'tokens='+params+'&input='+this.inputbox.value.replace(/\s+/g, '+'),
		  onSuccess: this.ajaxResponse.bind(this)
		});
	},
	
	ajaxResponse: function(response)
	{
		var input = response.responseText;
		
		// Add each item as a suggestion to the suggestions div
		var json = input.evalJSON();
		
		this.clearSuggestions();
		
		if(json.length > 0)
		{		
			for(var i=0; i < json.length; i++)
			{
				var li = Builder.node('li', {id: 'suggestion_'+i}, json[i].replace(/\+/g, ' '));
				
				this.suggestions.appendChild(li);
				
				if(i == this.currentindex)
					$(li).addClassName('selected');
				
				// Add an event handler
				Event.observe(li, 'click', this.suggestionSelectedByClick.bindAsEventListener(this));
				Event.observe(li, 'mouseover', this.suggestionMouseOver.bindAsEventListener(this));
			}
		}
		else
		{
			var li = Builder.node('li', {}, 'No Suggestions');
				
			this.suggestions.appendChild(li);
		}
	},
	
	suggestionMouseOver: function(e)
	{
		this.currentindex = parseInt(e.target.id.replace('suggestion_', ''));
		this.update();
	},
	
	update: function()
	{
		// Loop through all list items and highlight the correct one
		var nodes = $(this.suggestions).childElements();
		
		for(var i=0; i < nodes.length; i++)
		{
			if(i == this.currentindex)
				nodes[i].addClassName('selected');	
			else
				nodes[i].removeClassName('selected');
		}
	},
	
	clearSuggestions: function()
	{
		this.currentindex = 0;
		
		// Empty the element
		if ( $(this.suggestions).hasChildNodes() )
		{
	    while ( $(this.suggestions).childNodes.length >= 1 )
        $(this.suggestions).removeChild( $(this.suggestions).firstChild );       
		}
	},
	
	suggestionSelectedByClick: function(e)
	{
		this.suggestionSelected(e.target.innerHTML);
	},
	
	suggestionSelected: function(string)
	{
		this.clearSuggestions();
		this.label.innerHTML = string;
		this.inputbox.value = this.label.innerHTML;
		$(this.surface).addClassName('saved');
		
		this.label.show();
		this.inputbox.hide();
		this.suggestions.hide();
		
		this.myParent.addSearchTerm(this);
	},
	
	getSearchTerm: function()
	{
		return this.inputbox.value;	
	},
	
	focus: function()
	{
		this.inputbox.focus();	
	}
}
