﻿// Globals:

var max_results_per_page = 6;
var results = [];
var sortier = [];
var results_remainder = 0;
var current_page = 0;
var total_number_of_pages = 0;

var enable_animation = true;
var startWithSearch = 0;



// Setup:

window.addEvent('domready', function(){

	populateFormElements();

	// start with a search?
	if (startWithSearch > 0) {
		pollSearch();
	}

	// setup clear functionality
	$('clear').addEvent('click', function(e) {
  	new Event(e).stop();
		location.hash = "";

		if (enable_animation) {
			new Fx.Morph('results', {
				duration: 500,
				onComplete: function() {
					$('output').empty();
				}
			}).start({'opacity': 0});
		} else {
			$('results').setStyle('visibility', 'hidden');
			$('output').empty();
		}

  });

	// override form submit functionality
	$('search_form').addEvent('submit', function(e) {
		new Event(e).stop();
		pollSearch();
	});

});



function pollSearch() {

	if (validate()) {

		var url = $('search_form').getProperty('action');
		var query = new Array();
		var french = new RegExp().compile('\/fr\/','i');

		var l = (french.test(window.location.pathname) ? 'fr' : 'en');
		var parameters = {
			model:        $('model').get('value'),
			transmission: $('transmission').get('value'),
			minModelYear: $('model_year_low').get('value'),
			maxModelYear: $('model_year_high').get('value'),
			postalCode:   $('postal_code').get('value'),
			minPrice:     removeDollarSign($('price_low')),
			maxPrice:     removeDollarSign($('price_high')),
			certified:    $('certified_used').get('value')
		};

		query.push("language=" + l);
		for(var parameter in parameters) {
			if(parameters[parameter]!='') {
				query.push(parameter + "=" + escape(parameters[parameter]));
			}
		}
		url += '?'+query.join("&");

		var request = new Request({
			url: url,
			method: 'get',
			onRequest: function() {
				$('loading').addClass('animate');
			},
			onSuccess: function(txt, xml) {
			  render(xml);
			},
			onFailure: function() {
				modal(messages.httperror);
			}
		}).send();
	}

}



function populateFormElements() {
	// Parse up query string parameters (hash and GET parameters)
	var search = {};
	parseQueryString(location.hash,search);
	parseQueryString(location.search,search);

	// Setup select boxes
	for (var box in select_boxes) {
		var thisBox = select_boxes[box];
		var itemCount = thisBox.length;
		var cleanName = unescape(search[box]).toLowerCase();
		for (var j = 0; j < itemCount; j++) {
			var option = new Element('option',{value: thisBox[j].value});
			option.set('text', thisBox[j].name);

			if(cleanName == thisBox[j].name.toLowerCase()) {
				option.setProperty('selected', '1');
				startWithSearch++;
			}

			option.inject($(box));
		}
	}

	// Setup the other form elements
	$$('input').each(function(e){ // $$('input[text]').each(function(e){
		var id = e.getProperty('id');
		if (id != "submitter" && id != "clear") {
			if(search[id] && e.get('tag') != 'select') {
				e.setProperty('value', search[id]);
				startWithSearch++;
			} else {
				e.setProperty('value', '');
			}
		}
	});
}



function parseQueryString(qs,search){
	if (qs) {
		qs = qs.replace(/^[?#]/g, '');
		var values = qs.split('&');

		for (var i=0; i < values.length; i++) {
			var result = values[i].split('=');
			search[result[0]] = result[1];
		}
	}
}



function validate() {

	var model = $('model').get('value');
	var transmission = $('transmission').get('value');
	var model_year_low = $('model_year_low').get('value');
	var model_year_high = $('model_year_high').get('value');
	var postal_code = $('postal_code').get('value');
	var price_low = $('price_low').get('value');
	var price_high = $('price_high').get('value');
	var certified_used = $('certified_used').get('value');

	// year / price mismatches:
	if (model_year_low != '' &&
			model_year_high != '' &&
			new Number(model_year_low) > new Number(model_year_high)) {
		modal(messages.yearerror);
		return false;
	}

	if (price_low != '' &&
			price_high != '' &&
			new Number(price_low) > new Number(price_high)) {
		modal(messages.priceerror);
		return false;
	}

	return true;
}



function check (str, kind, length) {
		var valid;

		if (kind == "numeric") {
			valid = "0123456789";
		} else if (kind == "alphabetic") {
			valid = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		} else if (kind == "dollar") {
			valid = "0123456789.,$";
		}

		if (length) {
			if (str.length != length) {
				return false;
			}
		}

    for (i=0;i<str.length;i++) {
    	if (valid.indexOf(str.charAt(i)) == -1) {
				return false;
			}
    }
		return true;
}



function removeDollarSign (element) {
	var value = $(element).get('value');
	return value.replace(/\$/g, '');
}



function modal(caption,level) {

	var lvl = (level&&level!='' ? level : 'error');

	$('output').empty();

	var p = new Element('p', {'class': lvl});
	p.set('text', caption);
	p.inject('output');

	// hide sorter and pagination
	$('sorter').setStyle('display', 'none');
	$('pagination').setStyle('display', 'none');
	$('title_results').addClass('title_'+lvl);

	if (enable_animation) {
		$('results').setOpacity(0);
		new Fx.Morph('results', {
			duration: 500
		}).start({'opacity': 1});
	} else {
		$('results').setStyle('visibility', 'visible');
	}

}



function render(obj) { //call each time new results are required.

	// Serverside XML Error Encountered
	if (obj.getElementsByTagName('error').length > 0) {
		$('loading').removeClass('animate');
		var message = obj.getElementsByTagName('message')[0].firstChild.nodeValue;
		modal(message);
		return;

	// Search produced at least one VEHICLE
	} else if (obj.getElementsByTagName('vehicle').length > 0) {

		// show sorter and pagination
		$('sorter').setStyle('display', 'block');
		$('pagination').setStyle('display', 'block');
		$('title_results').removeClass('title_sorry');
		$('title_results').removeClass('title_error');

		$('output').empty(); // clear output's contents

		var sort_condition = "model";//"model";
		results = [];
		var rawResults = obj.getElementsByTagName('vehicle');
		for(var i=0; i<rawResults.length; i++) {
			results.push(rawResults[i]);
		}
		var sorted = [];

		// setup pagination (max_results_per_page)
		if (results.length <= max_results_per_page) {

			$('pagination').setStyle('visibility', 'hidden');

			// sort
			sortResults(sort_condition);

		} else {

			var results_remainder = results.length % max_results_per_page;

			if (results_remainder > 0) {
				total_number_of_pages = Math.floor(results.length / max_results_per_page) + 1;
			} else {
				total_number_of_pages = results.length / max_results_per_page;
			}

			$('pagination').setStyle('visibility', 'visible');

			// sort
			sortResults(sort_condition);

		}

		// construct page:
		drawPage(0);

		$('loading').removeClass('animate');

		if (enable_animation) {
			$('results').setOpacity(0);
			new Fx.Morph('results', {
				duration: 500
			}).start({'opacity': 1});
		} else {
			$('results').setStyle('visibility', 'visible');
		}

	// Search produced NO VEHICLES:
	} else if (obj.getElementsByTagName('vehicle').length == 0) {
		$('loading').removeClass('animate');
		modal(messages.noresults,'sorry');

	// Search produced an ERROR
	} else {
		$('loading').removeClass('animate');
		modal(messages.error);
	}

}



function drawPage (index) {
	current_page = index;

	// update pagination display;
	$('page-current').set('text', current_page + 1);
	$('page-total').set('text', total_number_of_pages);

	// empty existing results:
	$('output').empty();

	// start fresh page
	var ul = new Element('ul');
	var start = index*max_results_per_page;
	var limit = (index+1) * max_results_per_page;

	for (var i=start; i < limit; i++) {

		if (i < sortier.length) {

			var li = new Element('li');
			var vehicle = {
					id : 							sortier[i].getAttribute("id"),
					image :           getXmlValue(sortier[i],'image'),
		    	model :         	getXmlValue(sortier[i],'model'),
					transmission :  	getXmlValue(sortier[i],'transmission'),
		    	year :          	getXmlValue(sortier[i],'year'),
					kilometres : 			getXmlValue(sortier[i],'kilometres'),
					price :         	getXmlValue(sortier[i],'price'),
					dealerCode : 			getXmlValue(sortier[i],'dealerCode'),
					dealerName : 			getXmlValue(sortier[i],'dealerName'),
					dealerDistance : 	getXmlValue(sortier[i],'dealerDistance'),
					certified :	 			getXmlValue(sortier[i],'certified')
			};

			li.setProperty("id", vehicle.id);
			li.setProperty("class", "sort id");

			li.addEvent('click', function() { // vehicle click through
				popWindow("product.html#id=" + this.id,"product",800,600,true,false,true);
			});

			var odd = i % 2; // row shading
			if (odd != 1) {
				li.setProperty("class", "odd");
			}

			// draw out elements here + validate content of each while we're at it...
			var properties = [
				"image",
				"year",
				"model",
				"kilometres",
				"price",
				"transmission",
				"dealerName",
				"dealerDistance",
				"certified"
			];

			for (var j=0; j < properties.length; j++) {

				if (properties[j] == "image") {
					if(vehicle.image != ''){
						var span = new Element('span', {'class': properties[j]});
						var img = new Element('img', {'src': "/files/preowned/" + vehicle.image});
						img.inject(span);
					} else {
						var span = new Element('span', {'class': properties[j]});
						span.set('text', '');
					}
				} else if (properties[j] == "dealerName") {
					var span = new Element('span', {'class': 'dealerName'});
					span.set('text', vehicle.dealerName);
					span.setProperty('rel', vehicle.dealerCode); // add dealerCode for later retrieval
				} else if (properties[j] == "certified") { // draw in the check boxes
					var span = new Element('span', {'class': properties[j]});
					if (vehicle.certified == "true") {
						span.setProperty('class', 'check');
						span.set('text', "true");
					}
				} else {
					var span = new Element('span', {'class': properties[j]});
					span.set('text', eval("vehicle." + properties[j]));
				}

				span.inject(li);
			}

	    li.inject(ul);

		}

	}

	ul.inject('output');

}



function getXmlValue(obj,element) {
	var val = '';
	if(obj.getElementsByTagName(element).length>0){
		if(obj.getElementsByTagName(element)[0].childNodes.length>0){
			val = obj.getElementsByTagName(element)[0].firstChild.nodeValue;
		}
	}
	return val;
}



function prev() {
	if (current_page == 0) {
		current_page = total_number_of_pages - 1;
	} else {
		current_page--;
	}
	drawPage(current_page);
}



function next() {
	if (current_page < total_number_of_pages - 1) {
		current_page++;
	} else {
		current_page = 0;
	}
	drawPage(current_page);
}



function sortMe(sortBy) {
	$('output').empty();
	sortResults(sortBy);
	drawPage(current_page);
}

var lastOrder = -1;
var lastField = '';

function sortResults (sortBy) {
	var ordering = {
		image:          'image',
		model:          'ascii',
		transmission:   'ascii',
		year:           'numeric',
		kilometres:     'numeric',
		price:          'numeric',
		dealerName:     'ascii',
		dealerDistance: 'numeric',
		certified:      'boolean'
	};
	var unsorted = new Array();
	var sorter;

	lastOrder = (lastOrder==-1 ? 1 : -1);
	if(sortBy != lastField)
			lastOrder = 1;
	lastField = sortBy;

	switch(ordering[sortBy]) {
		case 'ascii':
			sorter = function(a,b) {
				var _a = getXmlValue(a,sortBy);
				var _b = getXmlValue(b,sortBy);
				if(_a>_b)
						return lastOrder*1;
				if(_a<_b)
						return lastOrder*-1;
				return lastOrder*(0+a.getAttribute('id')-b.getAttribute('id'));
			};
			break;
		case 'boolean':
			sorter = function(a,b) {
				var _a = getXmlValue(a,sortBy);
				var _b = getXmlValue(b,sortBy);
				if(_a<_b)
						return lastOrder*1;
				if(_a>_b)
						return lastOrder*-1;
				return lastOrder*(0+a.getAttribute('id')-b.getAttribute('id'));
			};
			break;
		case 'image':
			sorter = function(a,b) {
				var _a = (getXmlValue(a,sortBy) != '');
				var _b = (getXmlValue(b,sortBy) != '');
				if(!_a&&_b)
						return lastOrder*1;
				if(_a&&!_b)
						return lastOrder*-1;
				return lastOrder*(0+a.getAttribute('id')-b.getAttribute('id'));
			};
			break;
		case 'numeric':
			sorter = function(a,b) {
				var _a = getXmlValue(a,sortBy).replace(/[^0-9.]/g,'');
				var _b = getXmlValue(b,sortBy).replace(/[^0-9.]/g,'');
				var cmp = (0+_a-_b);
				if(cmp) {
					return lastOrder*cmp;
				} else {
					return lastOrder*(0+a.getAttribute('id')-b.getAttribute('id'));
				}
			};
			break;
		default:
			alert('Error, unknown sort type, '+ordering[sortBy]+', for '+sortBy);
			break;
	}

	sortier = results.sort(sorter);

	draw_sort_order_arrows(ordering, sortBy, lastOrder);
}

function draw_sort_order_arrows (fields, field, order){
	for(var offField in fields){
		//alert("clearing #sort_"+offField);
		var span = $("title_"+offField);
		if(span!=null){
			span.removeClass("sort_down");
			span.removeClass("sort_up");
		}else{
			alert("could not find element with id = [title_"+offField+"]");
		}
	}

	var span = $("title_"+field);
	if(span!=null)
		span.addClass((order==1 ? "sort_up" : "sort_down"));
	else
		alert("could not find element with id = [title_"+field+"]");
}

