/*******************************
 *
 *	Search Class
 *
 *  Version: 1.0
 *
 *	Author: 
 *	The Roundhouse
 *
 *  © The Roundhouse 2007 -
 * 	ALL RIGHTS RESERVED
 */

var Search = new Class({
	
	// create any variables
	// that we need
	iMode: 			0,
	arrFilters: 	null,
	arrHistory: 	null,
	objOutput: 		null,
	iResultSize: 	null,
	iPageSize:		6,
	iDelay: 		250,
	strSearchTerm: 	null,

	// initialize the search
	initialize: function()
	{
		// create an array for the filters
		this.arrFilters 	= new Array(2);
		this.arrFilters[0] 	= new Array();
		this.arrFilters[1] 	= new Array();
		
		// create an array for the search history
		this.arrHistory 	= new Array();
	},
	
	setMode: function(iMode, bNoSearch)
	{
		this.iMode 			= iMode;
		this.objOutput.setMode(iMode, this.strSearchTerm);
		
		if(!bNoSearch)
		{
			this.doSearch(this.strSearchTerm, true, true);
			
			// store a cookie so we know
			// what the mode is later on
			Cookie.set("prSearchMode", iMode, {duration:3650, domain:document.domain, path:'/'});
		}
	},
	
	getMode: function()
	{
		return this.iMode;
	},

	// do the search
	doSearch: function(strSearchTerm, bNow, bForce)
	{
		// if the term we're searching
		// on has changed
    	if(strSearchTerm != this.strSearchTerm || bForce)
		{
			// set the timestamp
			// and the search term
			// so we can verify later on
			this.strTimeStamp 	= (new Date()).getTime().toString();
			this.strSearchTerm 	= strSearchTerm;
			
			if(bNow) // do it immediately
				this.activateSearch(this.strSearchTerm, this.strTimeStamp);
			else // have the search start in 250 ms
				this.activateSearch.delay(1000, this, new Array(this.strSearchTerm, this.strTimeStamp));
		}
	},
	
	getLastSearch: function()
	{
		if(Cookie.get("prLastSearch"))
		{
			this.objOutput.setSearchBox(Cookie.get("prLastSearch"));
			this.doSearch(Cookie.get("prLastSearch"), true);
		}
		else
		{
			this.doSearch("", true);
		}
	},
	
	// add a search term to the
	// search history
	addToHistory: function(strSearchTerm)
	{
		// if the search term is empty
		// then populate it with the current
		if(!strSearchTerm)
			strSearchTerm = this.strSearchTerm;
		
		if(strSearchTerm != "")
		{
			this.arrHistory[strSearchTerm.toLowerCase()] = {bHist:true, strSearchTerm:strSearchTerm};
			this.objOutput.outputHistory(this.arrHistory);
			
			var objRequest = {
				bAddToHistory: true,
				bGetHistory: true,
				strSearchTerm: strSearchTerm
			};
			
			(new Ajax("/z_ajax/ajax_handler_history.php", {onComplete: this.ajax_handleHistory.bind(this), postBody: objRequest})).request();
		}
	},
	
	// remove a search term from the history
	removeFromHistory: function(strSearchTerm)
	{
		delete this.arrHistory[strSearchTerm.toLowerCase()];
		this.objOutput.outputHistory(this.arrHistory);
		
		var objRequest = {
			bRemoveFromHistory: true,
			bGetHistory: true,
			strSearchTerm: strSearchTerm
		};
		
		(new Ajax("/z_ajax/ajax_handler_history.php", {onComplete: this.ajax_handleHistory.bind(this), postBody: objRequest})).request();
	},
	
	// pull the data for the user's search history
	getHistory: function()
	{
		var objRequest = {
			bGetHistory: true 
		};
		
		// dispatch the request
		(new Ajax("/z_ajax/ajax_handler_history.php", {onComplete: this.ajax_handleHistory.bind(this), postBody: objRequest})).request();
	},
	
	// handle the history
	ajax_handleHistory: function(objResponseText, objResponseXML)
	{
		if(objResponseXML)
		{
			// go through each child of the response.
			// IE regards the xml header as a child node
			// so we have to go through each one
			for(var i = 0; i < objResponseXML.childNodes.length; i++)
			{
				// if we have a response
				if(objResponseXML.childNodes[i].nodeName == "response")
				{
					var arrChildren = objResponseXML.childNodes[i].childNodes;
					
					for(var c = 0; c < arrChildren.length; c++)
					{
						if(arrChildren[c].firstChild)
						{
							var strNodeValue = arrChildren[c].firstChild.nodeValue;
							this.arrHistory[strNodeValue.toLowerCase()] = {bHist:true, strSearchTerm:strNodeValue};
						}
					}
				}
			}
		}
		
		// output the history
		this.objOutput.outputHistory(this.arrHistory);				
	},

	// actually do a search
	activateSearch: function(strSearchTerm, strTimeStamp)
	{
		// if we have undefined or null search term
		// do an empty search
		if(!strSearchTerm)
			strSearchTerm = "";
		
		// if the timestamp still matches,
		// i.e. if we've not typed something
		// since we initially dispatched this
		// request for the data
		if(this.strTimeStamp == strTimeStamp)
		{
		
			// show the swirly
			if($('search_loader'))
				$('search_loader').setStyle('opacity',100);
		   
		    if($('search_field'))
				$('search_field').addClass('active');
			
			// store a cookie so we know
			// what the last search was
			Cookie.set("prLastSearch", strSearchTerm, {duration:3650, domain:document.domain, path:'/'});
			
			// kill off any results we had
			this.arrResults = new Array();
			
			// create a new request
			this.objRequest = {
				iMode: 			this.iMode,
				strPageStart: 	"0",
				strPageEnd: 	this.iPageSize.toString(),
				strSearchTerm: 	strSearchTerm,
				strTimeStamp: 	strTimeStamp,
				bRowCount: 		true
			}
			
			// go through each filter
			// and add it into the request
			for(var i in this.arrFilters[this.iMode])
			{
				var filter = this.arrFilters[this.iMode][i];
				if(filter.getFilter)
					this.objRequest["FL_" + filter.getFilter()] = filter.getValue();
			}
			
			// dispatch the request
			(new Ajax("/z_ajax/ajax_handler_search.php", {onComplete: this.ajax_handleResults.bind(this), postBody: this.objRequest})).request();
		}
		
		if(strSearchTerm == "")
			this.objOutput.isLatest(this.iMode);
		else
			this.objOutput.isSearch(this.iMode);
		
	},

	// handle whatever comes back from the ajax request
	ajax_handleResults: function(objResponseText, objResponseXML)
	{
		// hide the swirly
		if($('search_loader'))
		{
			$('search_loader').setStyle('opacity',0);
			$('search_loader').setStyle('visibility','visible');
		}
		
		if($('search_field'))
			$('search_field').removeClass('active');
			
		var iStartIndex 	= 0;
		var iEndIndex 		= 0;
		var iCount 			= 0;
		var bValidInput 	= false;
		var bCount 			= false;
		var strVal 			= "";
		if(objResponseXML)
		{
			// go through each child of the response.
			// IE regards the xml header as a child node
			// so we have to go through each one
			for(var i = 0; i < objResponseXML.childNodes.length; i++)
			{
				//if(objResponseXML.childNodes[i].nodeName == "parsererror")
				//{
					//alert(objResponseXML.childNodes[i].firstChild.nodeValue.toString());
				//}
				// if we have a response
				if(objResponseXML.childNodes[i].nodeName == "response")
				{
					// make sure we keep
					// a track of the number
					// of results processed
					var iTempLoc 	= 0;
					var arrChildren = objResponseXML.childNodes[i].childNodes;
					
					for(var c = 0; c < arrChildren.length; c++)
					{
						var strNodeValue = arrChildren[c].firstChild.nodeValue;
						switch(arrChildren[c].nodeName)
						{
							case "timestamp":	// check that the timestamp matches the most
												// recent request. If it does, this data is valid
												// for showing
												if (strNodeValue == this.objRequest.strTimeStamp)
													bValidInput = true;
												break;
							case "pagestart":	iStartIndex = parseInt(strNodeValue);
												break;
							case "pageend":		iEndIndex = parseInt(strNodeValue);
												break;
							case "job":
							case "candidate":	// put the result into the array
												this.arrResults[iStartIndex + iTempLoc++] = Json.evaluate(strNodeValue);
												break;
							case "count":		this.iResultSize = strNodeValue;
												break;
						}
					}
					
				}
			}
		}
		
		// if we had no results say as much
		if(this.iResultSize == 0)
		{
			this.objOutput.noResults(this.iMode);
		}
		else if(bValidInput)
		{
			// if we have a valid response (timestamps match)
			// we should show the results. Try and use the cookie
			// for the start index
			if(Cookie.get('prSearchPage'))
			{
				// attempt to assign the start index
				iStartIndex = parseInt(Cookie.get('prSearchPage'));
				
				// if it's not a number (tampered) etc
				// then set it to zero
				if(isNaN(iStartIndex))
					iStartIndex = 0;
			}
			
			this.getResults(iStartIndex / this.iPageSize);
		}
		
	},

	// check that we have the results that we wish
	// to show and, if not, issue a request for them
	getResults: function(iPage)
	{
		var bMustGetResults 	= false;
		
		// Get the start point. Make sure that we're never past the last page
		var iStart 				= iPage * this.iPageSize;
		var iEnd 				= Math.min((iPage + 1) * this.iPageSize, this.iResultSize);
		
		// set the cookie for next time
		Cookie.set('prSearchPage', iStart, {domain:document.domain, path: '/', duration:3650});	
		
		// go through the array of results and
		// check for the existence of the range
		// of results we want to see
		for (var i = iStart; i < iEnd; i++)
		{
			if (!this.arrResults[i])
			{
				bMustGetResults = true;
				break;
			}
		}
		
		// if we need results head off and
		// get them by dispatching an AJAX request
		if (bMustGetResults)
		{
			// create a request
			var objRequestMore =
			{
				iMode: 			this.iMode,
				strPageStart: 	iStart.toString(),
				strPageEnd: 	iEnd.toString(),
				strSearchTerm: 	this.objRequest.strSearchTerm,
				strTimeStamp: 	this.objRequest.strTimeStamp
			}
			
			// add in any filters
			for (var i in this.arrFilters[this.iMode])
			{
				var filter = this.arrFilters[this.iMode][i];
				if(filter.getFilter)
					objRequestMore["FL_" + filter.getFilter()] = filter.getValue();
				
			}
			
			// dispatch the new request
			(new Ajax("/z_ajax/ajax_handler_search.php", {onComplete: this.ajax_handleResults.bind(this),postBody: objRequestMore})).request();
		} 
		else // output the results
			this.objOutput.outputResults(this.arrResults, iStart, iEnd, this.iResultSize, this.iPageSize);
			
		// return false to
		// stop the browser
		// from actioning the href
		return false;
	},

	// set the output module
	setOutputModule: function (objOutput) 
	{
		this.objOutput = objOutput;
	},

	// a filter in
	addFilter: function(iMode, strFilter, mxValue, elSource, bActivateNow)
	{
		if(iMode == null)
			iMode = this.iMode;
			
		// check that we have a source for
		// the value (which will overwrite any existing value)
		if(elSource && $(elSource))
			mxValue = $(elSource).getValue();
		
		// if we now have a value
		if(mxValue && mxValue != "")
		{
			// create a filter
			var filter = new Filter(iMode, strFilter, mxValue);
			this.arrFilters[iMode][strFilter] = filter;
			
			// check if we want this activated now
			if(bActivateNow)
			{
				this.strTimeStamp = (new Date()).getTime().toString();
				this.activateSearch(this.strSearchTerm, this.strTimeStamp);
			}
		}
	},

	// add a variable that can vary in its
	// value. If the value is an empty value
	// then remove it as a filter
	addVariableFilter: function(strFilter, mxValue, elRequired)
	{
		var bChanged = false;
		if (!mxValue || mxValue == null || mxValue == 0 || mxValue == "")
		{
			this.removeFilter(this.iMode, strFilter);
			bChanged = true;
		}
		else if(!elRequired || $(elRequired).checked)
		{
			var filter = new Filter(this.iMode, strFilter, mxValue);
			this.arrFilters[this.iMode][strFilter] = filter;
			bChanged = true;
		}
		
		if(bChanged)
		{
			this.strTimeStamp = (new Date()).getTime().toString();
			this.doSearch(this.strSearchTerm, false, true);
		}
	},

	// remove a filter
	removeFilter: function(iMode, strFilter, bActivateNow)
	{
		// delete the filter from the array
		delete this.arrFilters[iMode][strFilter];
		
		// check if we want this activated now
		if(bActivateNow)
		{
			this.strTimeStamp = (new Date()).getTime().toString();
			this.activateSearch(this.strSearchTerm, this.strTimeStamp);
		}
	},

	// switch a filter on and off
	toggleFilter: function(strFilter, mxValue, iMode)
	{
		// use the mode if it's set, otherwise
		// default to the current mode
		var iModeSet = (iMode ? iMode : this.iMode);
		
		if(this.arrFilters[iModeSet][strFilter])
			this.removeFilter(iModeSet, strFilter);
		else
		{
			this.addFilter(iModeSet, strFilter, mxValue);
		}
		
		this.strTimeStamp = (new Date()).getTime().toString();
		this.activateSearch(this.strSearchTerm, this.strTimeStamp);
	}
});

// instantiate the search for the document
// along with its output module.
var prSearch = new Search();
var prOutput = new Output();
prSearch.setOutputModule(prOutput);

window.addEvent('domready', function()
{
	if(!document.FIN)
	{
		var bSearchExists = $('search_ajax_field');
		
		if(bSearchExists)
		{
			$('search_loader').setStyle('display', 'block');
		
			if($('add_to_history'))
			{
				$('add_to_history').addEvent('click', function()
													  {
														  prSearch.addToHistory($('search_ajax_field').getValue());
													  });
			}
			
			if($('jobseeker'))
			{
				$('jobseeker').addEvent('click', 	  function()
													  {
														  // clear the paging
														  Cookie.set('prSearchPage', 0, {domain:document.domain, path: '/', duration:3650});
														  prSearch.setMode(0);
													  });
			}
			
			if($('employer'))
			{
				$('employer').addEvent('click', 	  function()
													  {
														  // clear the paging
														  Cookie.set('prSearchPage', 0, {domain:document.domain, path: '/', duration:3650});
														  prSearch.setMode(1);
													  });
			}
			
			if($('search_ajax_field'))
			{
				$('search_ajax_field').addEvent('keyup', function()
													  {
														  // clear the paging
														  Cookie.set('prSearchPage', 0, {domain:document.domain, path: '/', duration:3650});
				
														  prSearch.doSearch(this.value);
													  });
			}
			
			if($('postcode'))
			{
				$('postcode').addEvent('keyup', function()
													  {
														  prSearch.addVariableFilter('postcode', this.value, 'filter_area_postcode');
														  Cookie.set('filter_postcode_value', this.value, {domain:document.domain, path: '/', duration:3650});
													  });
			}
			
			if($('filter_area_postcode'))
			{
				$('filter_area_postcode').addEvent('click', function()
													  {
														  this.bActive = this.checked;
														  if(this.bActive)
														  {
															  prSearch.addFilter(0, 'postcode', null, 'postcode', true);
															  Cookie.set('filter_postcode', '1', {domain:document.domain, path: '/', duration:3650});
															  Cookie.set('filter_postcode_value', $('postcode').getValue(), {domain:document.domain, path: '/', duration:3650});
														  }
														  else
														  {
															  prSearch.removeFilter(0, 'postcode', true);
															  Cookie.set('filter_postcode', '-1', {domain:document.domain, path: '/', duration:-1});
														  }
													  });
			}
			
			if($('filter_salary_all'))
			{
				$('filter_salary_all').addEvent('click', function()
													  {
														  prSearch.removeFilter(0, 'salary', true);
														  Cookie.set('filter_salary', '-1', {domain:document.domain, path: '/', duration:-1});
													  });
			}
			
			if($('filter_salary_0'))
			{
				$('filter_salary_0').addEvent('click', function()
													  {
														  prSearch.addFilter(0, 'salary', 1, null, true);
														  Cookie.set('filter_salary', '1', {domain:document.domain, path: '/', duration:3650});
													  });
			}
			
			if($('filter_salary_1'))
			{
				$('filter_salary_1').addEvent('click', function()
													  {
														  prSearch.addFilter(0, 'salary', 2, null, true);
														  Cookie.set('filter_salary', '2', {domain:document.domain, path: '/', duration:3650});
													  });
			}
			
			if($('filter_salary_2'))
			{
				$('filter_salary_2').addEvent('click', function()
													  {
														  prSearch.addFilter(0, 'salary', 3, null, true);
														  Cookie.set('filter_salary', '3', {domain:document.domain, path: '/', duration:3650});
													  });
			}
			
			// if we have set a cookie
			// for the search mode
			// switch to that mode
			if(Cookie.get("prSearchMode"))
				prSearch.setMode(parseInt(Cookie.get("prSearchMode")), true);
				
			// now we need to check out
			// whether we have set cookies
			// for the various filters
			var arrFilterCookies 						= new Array();
			
			// MODE 0: JOBS
			arrFilterCookies['filter_hot_job']			= {bFilter:true, strLabel:'hot_job', iMode:0, bButton:true};
			arrFilterCookies['filter_perm_job']			= {bFilter:true, strLabel:'permanent_job', iMode:0, bButton:true};
			arrFilterCookies['filter_temp_job']			= {bFilter:true, strLabel:'temporary_job', iMode:0, bButton:true};
			arrFilterCookies['filter_new_week']			= {bFilter:true, strLabel:'new_week', iMode:0, bButton:true};
			arrFilterCookies['filter_new_month']		= {bFilter:true, strLabel:'new_month', iMode:0, bButton:true};
			arrFilterCookies['filter_synergy']			= {bFilter:true, strLabel:'synergy', iMode:0, bButton:true};
			
			// MODE 1: CANDIDATES
			arrFilterCookies['filter_hot_candidate']	= {bFilter:true, strLabel:'hot_candidate', iMode:1, bButton:true};
			arrFilterCookies['filter_perm_candidate']	= {bFilter:true, strLabel:'permanent_candidate', iMode:1, bButton:true};
			arrFilterCookies['filter_temp_candidate']	= {bFilter:true, strLabel:'temporary_candidate', iMode:1, bButton:true};
			arrFilterCookies['filter_grad']				= {bFilter:true, strLabel:'graduate', iMode:1, bButton:true};
			
			// ADVANCED SEARCH
			arrFilterCookies['filter_salary']			= {bFilter:true, strLabel:'salary', iMode:0, bSalary:true};
			arrFilterCookies['filter_postcode']			= {bFilter:true, strLabel:'postcode', iMode:0, bPostcode:true};
			arrFilterCookies['filter_postcode_value']	= {bFilter:true, strLabel:'postcode_value', iMode:0, bPostcodeValue:true};
			
			var bApplyPostcode 							= false;
			
			// apply the click event
			// which will set a cookie
			for(var i in arrFilterCookies)
			{
				if(arrFilterCookies[i].bFilter)
				{
					// if it is a normal filter
					if(arrFilterCookies[i].bButton)
					{
						$(i).iMode 		= arrFilterCookies[i].iMode;
						$(i).strLabel 	= arrFilterCookies[i].strLabel;
						$(i).addEvent('click',function()
											  {
												  this.bActive = this.bActive ? false : true;
												  if(this.bActive)
												  {
													  this.addClass('active');
													  Cookie.set('filter_'+this.strLabel, '1', {domain:document.domain, path: '/', duration:0});
												  }
												  else
												  {
													  this.removeClass('active');
													  Cookie.set('filter_'+this.strLabel, '1', {domain:document.domain, path: '/', duration:-1});
												  }
												  prSearch.toggleFilter(this.strLabel, '1', this.iMode);
											  });
					}
					
					// grab the value from the cookie
					var strValue = Cookie.get('filter_'+arrFilterCookies[i].strLabel);
						
					// if the cookie is set add it as a filter
					if(strValue)
					{
						// if this filter is for the salary
						if(arrFilterCookies[i].bSalary)
						{
							// locate the appropriate
							// radio button and set it to 'on'
							var strTarget = 'filter_'+arrFilterCookies[i].strLabel + '_' + (parseInt(strValue) - 1);
							if($(strTarget))
								$(strTarget).checked = true;
								
							prSearch.addFilter(0, 'salary', strValue);
						}
						else if(arrFilterCookies[i].bPostcode)
						{
							bApplyPostcode 	= true;
							var strTarget 	= 'filter_area_postcode';
							if($(strTarget))
								$(strTarget).checked = true;
								
							prSearch.addFilter(0, 'postcode', '');
						}
						else if(arrFilterCookies[i].bPostcodeValue)
						{
							var strTarget = 'postcode';
							if($(strTarget))
								$(strTarget).value = strValue;
							
							if(bApplyPostcode)
								prSearch.addFilter(0, 'postcode', strValue);
						}
						else
						{
							// activate the button
							$(i).addClass('active');
							$(i).bActive = true;
						
							prSearch.addFilter($(i).iMode, $(i).strLabel, 1);
						}
					}
				}
			}
					
			// attempt to get the search history
			prSearch.getHistory();
			
			// now check for the last search
			prSearch.getLastSearch();
		}
		else // Microsite sans search term
		{
			// attempt to get the search history
			prSearch.getHistory();
			
			// do an empty search
			prSearch.doSearch("", true);
		}
		
		
		//$('wrapper_inner').setStyle('zIndex',-400);
		//$('column_left').setStyle('zIndex',0);
		//$('login').setStyle('zIndex',0);
	}
});