/**
 * @author Zach
 */
 
 Array.prototype.inArray = function ( obj ) {
	for ( var x = 0 ; x <= this.length ; x++ ) 
	{
		if ( this[x] == obj ) 
			return true;
	}
	return false;
}


var Search = new Class.create({
	initialize: function(container , data) 
	{
		this.data = data;
		this.fullData = data;
		
		this.displayCount = 18;
		this.currentCount = 0;
		this.currentSort = {field:'' , direction:''}
		this.rowsLoading = false;
		
		var makeNames = Array();
		var makeModels = Array();
		this.killObserver = Array();
		this.loadObserver = Array();
		
		this.fields =['stockno',
				      'make',
			          'model',
				      'year',
				      'askingprice',
				      'engine',
				      'transmission',
				      'mileage',
					    'image',
						  'color'];
		
		var sort = $$("#sortLinks .sort");
		for(var i = 0; i < sort.length; i++)
		{
			Event.observe(sort[i] , 'click' , this.changeSort.bindAsEventListener(this , sort[i].id ));
		}
		
		for (var i = 0; i < this.data.length; i++) 
		{	
			this.data[i].price = Number(this.data[i].askingprice.sub(',' , '' ));
			this.data[i].year = Number(this.data[i].year);
			this.data[i].miles = Number(this.data[i].mileage.sub(',' , '' ));
			this.data[i].makeEqual = true;
			this.data[i].modelEqual = true;
			this.data[i].isBetweenPrice = true;
			this.data[i].isCertified = true;
			this.data[i].isResult = true;
			makeNames.push(this.data[i].make);
			
			if(!makeModels[this.data[i].make])
				makeModels[this.data[i].make] = Array();
			
			makeModels[this.data[i].make].push(this.data[i].model);
			
			if(hashRegistry.readHash("page") == "vehicle" && Number(hashRegistry.readHash("stockno")) == Number(this.data[i].stockno))
				this.showResult(null , this.data[i]);
			
		}
		
		this.makes = makeNames.uniq();
		this.models = Array();
		
		for(var i = 0; i < this.makes.length; i++)
		{
			this.models[this.makes[i]] = makeModels[this.makes[i]].uniq();
			this.models[this.makes[i]].sort();
		}	
		this.makes.sort();
		this.generateMakesSelect();
		
		this.cert = false;
		
	},

	start: function(initialValue) {

		this.priceSlider = 	new Control.Slider( $$("#priceSlider > div")[0], "priceSlider", {
									range: $R(5000, 40000),
							        values: [5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000, 16000, 17000, 18000, 19000, 20000, 21000, 22000, 23000, 24000, 25000, 30000, 35000, 40000],
									onChange: function(v) {
										$('priceDisplay').update('Under $' + v);

										if (v == 40000) {
											$('priceDisplay').update('Any Price');
										}
										this.priceBetween(0, v);
										
										this.display();
									}.bind(this),
								onSlide: 
								function(v)
								{
									$('priceDisplay').update('Under $' + v);
									if (v == 40000)
										$('priceDisplay').update('Any Price');
								}.bind(this)
		});
								

		var scrollBar = new ScrollBar($('vScroll'), $('preownedResults') , 'vertical');
		scrollBar.scroller.setValue(0);
		scrollBar.bottomHandler = this.showRows.bind(this , 9);
		scrollBar.scrollHandler = this.updateCount.bind(this);
		
		this.scrollBar = scrollBar;
		
		var certified = hashRegistry.readHash("certified");
		if(certified == "true")
		{
			this.certified();
			$("certified").setValue(true);
		}
		
		this.priceSlider.setValue(initialValue);	
		this.display();
	},
	
	updateCount: function(top)
	{
		top = Math.abs(top);
		var firstResult = (Math.floor((top/223)+.25) * 3)+1;
		
		var secondResult = (Math.floor((top/223)+.25) * 3) + 6;
		
		if(secondResult > this.total)
			secondResult = this.total;
		
		$("resultCount").update("Viewing ("+ firstResult + "-"+ secondResult +") of "+ this.total);
		
	},
	
	
	clearSearch: function()
	{
		for (var i = 0; i < this.data.length; i++) 
			this.data[i].isResult = true;
			
		this.display();
	},
	
	
	keywordSearch: function()
	{
		var keyword = $F("searchForm");
		var temp = (isNew) ? 'N' : 'U';
		new Ajax.Request('/preownedVehicles/search/' + escape(keyword) + '/' + temp, {
			
  			onSuccess: function(transport) 
			{
    			var results = transport.headerJSON;
				if (results == null)
					results = Array();
					for (var i = 0; i < this.data.length; i++) 
					{	
						this.data[i].makeEqual = true;
						this.data[i].modelEqual = true;
						this.data[i].isBetweenPrice = true;
						this.data[i].isCertified = true;
						this.data[i].isResult = true;
						
						if(results.inArray(this.data[i].stockno))
						{
							this.data[i].isResult = true;
						}
						else 
							this.data[i].isResult = false;
					}
				this.display();
				}.bind(this)
		});
	},
	
	changeSort: function(event , field)
	{
		event.stop();
		if (this.currentSort.field == field && this.currentSort.direction == "desc") 
		{
			this.sort(field, "asc");
			this.currentSort.direction = "asc";
			$(field).addClassName('asc');
			$(field).removeClassName('desc');
		}	
		else if (this.currentSort.field == field && this.currentSort.direction == "asc") 
		{
			this.sort(field, "desc");
			this.currentSort.direction = "desc";
			$(field).addClassName('desc');
			$(field).removeClassName('asc');
		}
			
		if (this.currentSort.field != field)
		{
			if(this.currentSort.field)
				$(this.currentSort.field).removeClassName('desc').removeClassName('asc');
				
			this.currentSort.field = field;
			$(field).addClassName('desc');
			this.currentSort.direction = "desc";
			this.sort(field, "desc");
			this.currentSort.field = field;
		}
			
		
	},
	
	generateMakesSelect: function()
	{
		$("PreownedMakes").update();
		var element = new Element("option" , {'value' : 'all'}).update('All Makes');

		$("PreownedMakes").appendChild(element);
		for(var i = 0 ; i < this.makes.length ; i++)
		{	
			if(this.makes[i])
			{
				element = new Element("option" , {'value' : this.makes[i]});
				element.innerHTML = this.makes[i];
				$("PreownedMakes").appendChild(element);
			}
		}
			
		Event.observe($("PreownedMakes") , 'change' , function() {  this.display(); this.generateModelsSelect();}.bind(this));
		Event.observe($("PreownedModels") , 'change' , function() {this.modelEquals(); this.display();}.bind(this));
	},
	generateModelsSelect: function(make)
	{
		if(!make) {
			var make = $("PreownedMakes").getValue();
		}
		
		this.makeEquals(make);
		$("PreownedModels").update("");
		element = new Element("option" , {'value' : 'all'});
		element.innerHTML = 'All Models';
		$("PreownedModels").appendChild(element);

		for(var i = 0 ; i < this.models[make].length ; i++)
		{
			
			if(this.models[make][i])
			{
				element = new Element("option" , {'value' : this.models[make][i]});
				element.innerHTML = this.models[make][i];
				$("PreownedModels").appendChild(element);	
			}
		}
		
		this.scrollBar.scroller.setValue(0);
	},
	
	/**
	 * Sorts the data by field in direction asc or desc
	 * 
	 * @param {Object} field
	 * @param {Object} direction
	 */
	sort: function(field , direction)
	{
		var tmp;
		var value1 = '';
		var value2 = '';
		for (var i = 0; i < this.data.length; i++) 
		{
			for (var j = this.data.length - 1; j > i; j--) 
			{
				value1 = this.data[j][field];
				value2 = this.data[j - 1][field];
				
				if (typeof(value1) == 'string' || typeof(value2) == 'string') 
				{
					value1 = value1.toLowerCase();
					value2 = value2.toLowerCase();
				}
				
				if (value1 < value2 && direction == "asc") 
				{
					tmp = this.data[j];
					this.data[j] = this.data[j - 1];
					this.data[j - 1] = tmp;
				}
				else 
				if (value1 > value2 && direction == "desc")
				{
					tmp = this.data[j];
					this.data[j] = this.data[j - 1];
					this.data[j - 1] = tmp;
				}
			}
			if(field == 'price' && this.data[i].askingprice == 0)
				this.data[i].isBetweenPrice = false;
		}
		this.display();
	},
	
	certified: function(field , direction)
	{
		for (var i = 0 ; i < this.data.length ; i++) 
		{
			if(this.cert == false)
			{
				if(this.data[i].certified == "Yes")
					this.data[i].isCertified = true;
				else
					this.data[i].isCertified = false;
			}
			else
			{
				this.data[i].isCertified = true;

			}
		}
		this.cert = (!this.cert);
		

		this.scrollBar.scroller.setValue(0);
		this.display();
	},

	
	/**
	 * Only shows rows where field is between min and max
	 * 
	 * @param {Object} field
	 * @param {Object} min
	 * @param {Object} max
	 */
	priceBetween: function(min , max)
	{
		var price = 0;
		for (var i = 0 ; i < this.data.length ; i++) 
		{
			price = this.data[i].askingprice.sub("," , "").strip();
			
			if(price >= min && price <= max && price)
				this.data[i].isBetweenPrice = true;
			else
				this.data[i].isBetweenPrice = false;
				
			if(this.currentSort.field == 'price' && this.data[i].askingprice == 0)
				this.data[i].isBetweenPrice = false;	
		}

		this.scrollBar.scroller.setValue(0);
	},
	/**
	 * Only shows rows where field is equal to value
	 * @param {Object} field
	 * @param {Object} value
	 */
	makeEquals: function(value)
	{
		this.priceSlider.setValue(40000);
		
		for (var i = 0 ; i < this.data.length ; i++) 
		{
			if(value == 'all')
				this.data[i].makeEqual = true;
			else
			{	
				if(this.data[i].make == value)
				{
					this.data[i].makeEqual = true;
					this.data[i].modelEqual = true; //if we change the make we need to reset the model :-)
				}
				else
					this.data[i].makeEqual = false;
					this.data[i].modelEqual = true;
			}
			if(this.currentSort.field == 'price' && this.data[i].askingprice == 0)
				this.data[i].isBetweenPrice = false;
		}
		this.priceSlider.setValue(40000);
		this.rowsLoading = false;
		this.display();
	},

	modelEquals: function()
	{
		value = $("PreownedModels").getValue();
		
		for (var i = 0 ; i < this.data.length ; i++) 
		{
			if (value == 'all') 
				this.data[i].modelEqual = true;
			else 
			{
				if (this.data[i].model == value) 
					this.data[i].modelEqual = true;
				else 
					this.data[i].modelEqual = false;
			}
			if(this.currentSort.field == 'price' && this.data[i].askingprice == 0)
				this.data[i].isBetweenPrice = false;
		}
		this.scrollBar.scroller.setValue(0);
		this.priceSlider.setValue(40000);
	},
	
	generateResult: function(result)
	{		
			var newResults = "";
	
			if(result.askingprice.strip() == '0')
				price = 'Call Now!';
			else
				price = '$' + result.askingprice;
			
			    newResults += '<div class = "preownedResult" id = "result_'+ result.stockno +'" >';
				if(!result.image) {
				newResults += 	'<img id = "result_image_'+ result.stockno +'" src = "/media/images/'+ result.stockno +'/140x105_1.jpg" onerror="this.src=\'/img/no_image.png\'" />';
				} else {
				newResults += 	'<img id = "result_image_'+ result.stockno +'" src = "/media/new_vehicles/'+ result.image +'" onerror="this.src=\'/img/no_image.png\'" />';	
				}
				newResults +=     '<div id = "result_title_'+ result.stockno +'" class = "title">' + result.year + ' ' + result.make + ' ' + result.model + '</div>';
				newResults +=     '<div class = "price">MSRP: '+ price +'</div>';
				if(parseInt(result.mileage.replace(",", "")) > 200) {
					newResults +=     '<div class = "mileage"><strong>'+ result.mileage +'</strong> Miles</div>';
				} else {
					newResults +=     '<div class = "mileage"><strong>'+ result.color +'</strong></div>';
				}
				if(result.engine.strip() != '')
					newResults +=     '<div class = "engine"><strong>'+ result.engine +'</strong> Engine</div>';
				if(result.transmission.strip() != '')
					newResults +=    '<div class = "transmission"><strong>'+ result.transmission +'</strong> Transmission</div>';
				if(result.image) {
				newResults += '<div class = "disclaimer">Stock image pictured</div>';
				}
				newResults += '</div>';
				
				var observer = this.showResult.bindAsEventListener(this , result);
				
				this.loadObserver.push(Event.observe.curry('result_title_' + result.stockno , 'click' , observer));
				this.loadObserver.push(Event.observe.curry('result_image_' + result.stockno , 'click' , observer));
				this.killObserver.push(Event.observe.curry('result_title_' + result.stockno , 'click' , observer));
				this.killObserver.push(Event.observe.curry('result_image_' + result.stockno , 'click' , observer));
				
				return newResults;
	},
	
	showResult: function(event , result)
	{
		hashRegistry.writeHash("stockno" , result.stockno); //we let the page switcher call below commit the changes to the hash, 
		//otherwise two history objects would be generated
		switcher.switcher(event , $('vehicleTab'));
		$('vehiclePage').update("<div id = 'loading'><div></div></div>");
		
		new Ajax.Updater('vehiclePage', '/preownedVehicles/view/' + result.stockno, { evalScripts:true ,
			onComplete: function()
			{
				var boundNext = this.nextResult.bindAsEventListener(this , result);
				var boundPrev = this.prevResult.bindAsEventListener(this , result);
				var boundBack =this.hideResult.bindAsEventListener(this);
				
				if(this.nextObserve)
				{
					this.nextUnobserve();
					this.prevUnobserve();
					this.backUnobserve();
				}
				
				Event.observe($('nextResult') , 'click' , boundNext);
				Event.observe($('prevResult') , 'click' , boundPrev);
				Event.observe($('backResults') , 'click' , boundBack);
				
				this.nextUnobserve = Event.observe.curry($('nextResult') , 'click' , boundNext);
				this.prevUnobserve = Event.observe.curry($('prevResult') , 'click' , boundPrev);
				this.backUnobserve = Event.observe.curry($('backResults') , 'click' , boundBack);
				
			}.bind(this)
		});

	},
	
	nextResult: function(event , result)
	{

		var index = this.data.indexOf(result);
		for(var i = index + 1 ; i < this.data.length ; i++)
		{
			if (this.data[i].isBetweenPrice == true && this.data[i].isCertified == true && this.data[i].makeEqual == true && this.data[i].modelEqual == true) 			
				break;

		}
		this.showResult(event , this.data[i])
	},
	
	prevResult: function(event , result)
	{	
		var index = this.data.indexOf(result);
		for(var i = index - 1 ; i > 0 ; i--)
		{
			if (this.data[i].isBetweenPrice == true && this.data[i].isCertified == true && this.data[i].makeEqual == true && this.data[i].modelEqual == true) 
				break;
		}
		
		this.showResult(event , this.data[i])
	},
	
	hideResult: function(event)
	{
		hashRegistry.removeHash("stockno");
		hashRegistry.commit();
		switcher.switcher(event , $('listingTab'));
	},
	/**
	 * Outputs count DOM elements
	 */
	display: function()
	{
		var newResults = "";
		var count = 18;
		this.total = 0;
		this.numResultsLoaded = 0;
		
		for (var i = 0; i < this.killObserver.length; i++)
		{
			this.killObserver[i]();
		}
		this.killObserver = Array();

		for (var i = 0; i < this.data.length ; i++) 
		{	
			if ( this.data[i].isCertified == true && this.data[i].isBetweenPrice == true && this.data[i].makeEqual == true && this.data[i].modelEqual == true && this.data[i].isResult == true) 
			{
				if(i < count)
				{
					newResults += this.generateResult(this.data[i]);
					this.numResultsLoaded++;
				}
					
				this.total++;
			}
			else if(i < count)
				count++;
		}
		this.currentCount = count;
		
		$$('#preownedResults > div')[0].update(newResults);
		
		for (var i = 0; i < this.loadObserver.length; i++) 
		{
			this.loadObserver[i]();
		}
		this.loadObserver = Array();
		
		this.updateCount();
		this.scrollBar.scroller.setValue(0);
		
	},
	/**
	 * Inserts count more rows at the bottom of the containing div
	 */
	showRows: function(lines)
	{
		if (this.rowsLoading == false)
		{
			var newResults = "";
			
			if(this.numResultsLoaded == this.total)
			{
				
				$("bottomNotify").update("You have reached the end of the results.");
				return;
			}
			
			var count = this.currentCount + lines;
			for (var i = this.currentCount; i < count && i < this.data.length; i++) 
			{
				if(this.numResultsLoaded == this.total)
				{
					break;
				}
					
				if (this.data[i].isBetweenPrice == true && this.data[i].makeEqual == true && this.data[i].modelEqual == true && this.data[i].isCertified == true)
				{	
					this.numResultsLoaded++;
					newResults += this.generateResult(this.data[i]);
				}
				else 
					count++;
					
			}

			this.currentCount = count;
			function loadResults(newResults)
			{
				$$('#preownedResults > div')[0].insert(newResults);
				this.rowsLoading = false;
				$("bottomNotify").update("Scroll to the bottom to load more results.");
				this.scrollBar.resetPosition();
				for (var i = 0; i < this.loadObserver.length; i++)
				{
					this.loadObserver[i]();
				}
				this.loadObserver = Array();
			}
			
			loadResults = loadResults.bind(this);
			$("bottomNotify").update("loading...");
			loadResults.delay(.5, newResults);
			this.rowsLoading = true;
			

		}
	},
	
	loadQueue: function()
	{
		this.queueData;
	}
	
	
});
