/*******************************************************************/
/* carquery.0.1.js 						   */
/* javascript object for interacting with the CarQuery JSON API    */
/* Copyright (C) 2011  Daniel Mancusi (dan@carqueryapi.com)   	   */
/* http://www.carqueryapi.com					   */
/* 								   */
/* This program is free software; you can redistribute it and/or   */
/* modify it under the terms of the GNU General Public License     */
/* as published by the Free Software Foundation; either version 2  */
/* of the License, or (at your option) any later version.          */
/* 								   */
/* This code is distributed in the hope that it will be useful,    */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of  */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   */
/* GNU General Public License for more details.			   */
/*******************************************************************/

var carquery = {

    base_url: "http://www.carqueryapi.com/api/0.1/",
    
    cur_make: "",
        
    cur_model: "",
        
    cur_trim: "",
    
    cur_year: "",
    
    empty_option_html: "<option value=''>---</option>",
    
    make_select_id: "",
    
    make_list_id: "",
    
    model_list_id: "",
    
    trim_data_list_id: "",
    
    trim_list_id: "",
    
    model_data_id: "",
    
    model_select_id: "",
    
    trim_select_id: "",
    
    version: "0.1",
    
    year_select_id: "",
    
    search_input_id: "",
    
    init: function()
    {
	$.ajaxSetup({
	  "error":function() {   
	    alert('Bad Response from CarQuery API.\nThe service may not be avilable at this time.');
	}});
    },
    
    initSearchInterface: function(search_input_id, search_input_text)
    {
    	//Set ids for the search elements
    	this.search_input_id 	= search_input_id;
    	
    	//Set default search box text
    	$("#"+this.search_input_id).val(search_input_text);
    	
    	//Clear the input when the user clicks
    	$("#"+this.search_input_id).focus(function() {
		$(this).css("color", "#333");
		if(this.value == search_input_text) this.value = "";
	});
	
	$("#"+this.search_input_id).keyup(function() {
	
		var q = $(this).val();
		//TO DO: do the search...
	});
    },
    
    initMakeModelTrimList: function(make_list_id, model_list_id, trim_list_id, trim_data_list_id)
    {
        //Set the ids for the list elements
    	this.make_list_id  	=  make_list_id;
    	this.model_list_id 	=  model_list_id;
    	this.trim_list_id 	=  trim_list_id;
    	this.trim_data_list_id  =  trim_data_list_id;
    	
    	//Populate the make-list
    	carquery.populateMakeList();
    },
    
    initYearMakeModel: function(year_select_id, make_select_id, model_select_id)
    {
    	//Set the ids for the select elements
	this.year_select_id =  year_select_id;
	this.make_select_id =  make_select_id;
	this.model_select_id = model_select_id;
	
	//Populate the car-years select element
	carquery.populateYearSelect();
	
	//Set the changed event for the years dropdown to populate the makes select
	$("select#"+year_select_id).bind('change', function(){carquery.yearSelectChange();});
	
	//Set the changed event for the makes dropdown to populate the models select
	$("select#"+make_select_id).bind('change', function(){carquery.makeSelectChange();});
    },
    
    initYearMakeModelTrim: function(year_select_id, make_select_id, model_select_id, trim_select_id)
    {
        //Set the ids for the select elements
    	this.year_select_id =  year_select_id;
    	this.make_select_id =  make_select_id;
    	this.model_select_id = model_select_id;
    	this.trim_select_id = trim_select_id;    	
    	
    	//Populate the car-years select element
    	carquery.populateYearSelect();
    	
    	//Set the changed event for the years dropdown to populate the makes select
    	$("select#"+year_select_id).bind('change', function(){carquery.yearSelectChange();});
    	
    	//Set the changed event for the makes dropdown to populate the models select
    	$("select#"+make_select_id).bind('change', function(){carquery.makeSelectChange();});
    	
    	//Set the changed event for the models dropdown to populate the trims select
    	$("select#"+model_select_id).bind('change', function(){carquery.modelSelectChange();});
    },
    
    initModelData: function(model_data_id)
    {
    	this.model_data_id = model_data_id;
    },
    
    populateTrimList: function(make_id, model_name)
    {
    	//Show the trim data
        $("#"+this.trim_list_id).show();
    
    	//Set a loading message while we retrieve the data
        $("#"+this.trim_list_id).html("<p>Model Years / Trims:</p><div class='scrollable'><p>Loading Model Data...</p></div>");
        
        //Clear Active Model
        $("#"+this.model_list_id + " a").removeClass('active');

    	//Get Car Model JSON for the selected make
	$.getJSON(this.base_url+"?callback=?", {cmd:"getTrims", make:make_id, year:-1, model:model_name}, function(data) {
		
		if(!carquery.responseError(data))
		{		
	    		var trims = data.Trims;			    
			var out = '<p>Model Years / Trims:</p><div class="scrollable">';
			var js = '';
			
			for (var i = 0; i < trims.length; i++)
			{
			     js = "carquery.populateCarDataList("+trims[i].model_id+")";
			     out += '<a href="javascript:void(0)"  onclick="'+js+'">'+trims[i].model_year+' '+trims[i].model_name+' '+trims[i].model_trim+'</a><br/>';
			}
			out += '</div>';
			    
      			$("#"+carquery.trim_list_id).html(out);
	        }
    	});
    },
    
    populateModelList: function(make_id)
    {
    	//Make sure list is visible
    	$("#"+carquery.model_list_id).show();
    	$("#"+carquery.make_list_id).show();
    
    	//Hide other lists
    	$("#"+carquery.trim_data_list_id).hide();
    	$("#"+carquery.trim_list_id).hide();
    	
    
    	//Set a loading message while we retrieve the data
        $("#"+this.model_list_id).html("<p>Models:</p><div class='scrollable'><p>Loading Models...</p></div>");
        
        //Clear Active Make
        $("#"+this.make_list_id + " a").removeClass('active');

    	//Get Car Model JSON for the selected make
	$.getJSON(this.base_url+"?callback=?", {cmd:"getModels", make:make_id}, function(data) {
		
		if(!carquery.responseError(data))
		{		
	    		var models = data.Models;			    
			var out = '<p>Models:</p><div class="scrollable">';
			
			for (var i = 0; i < models.length; i++)
			{
			     out += '<a href="javascript:void(0)" onclick="carquery.populateTrimList(\''+models[i].model_make_id+'\',\''+models[i].model_name+'\');$(this).addClass(\'active\')" >'+models[i].model_name + '</a><br/>';
			}
			out += '</div>';
			    
      			$("#"+carquery.model_list_id).html(out);
	        }
    	});
    },
    
    
    populateMakeList: function()
    {    
    	//Make sure list is visible
    	$("#"+carquery.make_list_id).show();
    
    	//Hide other lists
    	$("#"+carquery.trim_data_list_id).hide();
    	$("#"+carquery.trim_list_id).hide();
    	$("#"+carquery.model_list_id).hide();
    	
    
	//Set a loading message while we retrieve the data
        $("#"+this.make_list_id).html("<p>Makes:</p><div class='scrollable'><p>Loading Makes...</p></div>");
            
   	//Retrieve All Makes
      	$.getJSON(this.base_url+"?callback=?", {cmd:"getMakes"}, function(data) {
      	
      		if(!carquery.responseError(data))
      		{
      			var makes = data.Makes;
      			var out = '<p>Makes:</p><div class="scrollable">';
      			var js = '';
      			
			for (var key in makes)
			{
			   if (makes.hasOwnProperty(key))
			      out += '<a href="javascript:void(0)" onclick="carquery.populateModelList(\''+makes[key].make_id+'\');$(this).addClass(\'active\')" >' + makes[key].make_display + '</a><br/>';
			}
			out += '</div>';
				
			
			$("#"+carquery.make_list_id).html(out);
        	}
        });
    },
    
    populateYearSelect: function()
    {    
    	//Set a loading message while we retrieve the data
    	$("select#"+this.year_select_id).html("<option value=''>Loading Years...</option>");
        
        $.getJSON(this.base_url+"?callback=?", {cmd:"getYears"}, function(data) {
    
    	if(!carquery.responseError(data))
    	{
        	var options = carquery.empty_option_html;
        	
        	for (var i = data.Years.max_year; i >= data.Years.min_year; i--)
        	{
          	 	options += '<option value="' + i + '">' + i + '</option>';
        	}
    	
    		$("select#"+carquery.year_select_id).html(options);
    		
    		$("select#"+carquery.make_select_id).html(carquery.empty_option_html);
		$("select#"+carquery.model_select_id).html(carquery.empty_option_html);
    	}
    	
    	});
    },
    
    populateMakeSelect: function(data)
    {
	if(!carquery.responseError(data))
	{
    	   	var options = '<option value="">Please choose a make</option>';
		var makes = data.Makes;
		for (var key in makes)
		{
	   	   if (makes.hasOwnProperty(key))
			options += '<option value="' + makes[key].make_id + '">' + makes[key].make_display + '</option>';
		}
	
		$("select#"+this.make_select_id).html(options);
	}
    },
    
    populateModelSelect: function(data)
    {    
    	var models = data.Models;
    
        var options = '';
        for (var i = 0; i < models.length; i++)
        {
           options += '<option value="' + models[i].model_name + '">' + models[i].model_name + '</option>';
        }
    
      	$("select#"+this.model_select_id).html(options);
    },
    
    populateTrimSelect: function(data)
    {    
        var trims = data.Trims;
        var display;
        
        var options = '';
        for (var i = 0; i < trims.length; i++)
        {
        	trim_display = trims[i].model_trim;
        	if(trim_display == "")
        		trim_display = "None";
        		
         	options += '<option value="' + trims[i].model_id + '">' +  trim_display + '</option>';
        }
        
      	$("select#"+this.trim_select_id).html(options);
    },
    
    carDataHTML : function(data)
    {
    
	var out = '<table class="model-data">';
    		
    	out += '<tr><th colspan="2">'+data.model_year+' '+data.make_display+' '+data.model_name+' '+data.model_trim+'</th></tr>';
    		
    	out += '<tr><td>Country of Origin:</td><td>'+data.make_country+'</td></tr>';
    		
    	out += '<tr><td colspan="2"><hr/></td></tr>';
    	out += '<tr><td>Engine Location:</td><td>'+data.model_engine_position+'</td></tr>';
    	out += '<tr><td>Engine Type:</td><td>'+data.model_engine_type+'</td></tr>';
    	out += '<tr><td>Engine Cylinders:</td><td>'+data.model_engine_cyl+'</td></tr>';
    	out += '<tr><td>Engine Displacement (cc):</td><td>'+data.model_engine_cc+'</td></tr>';
    	out += '<tr><td>Engine Displacement (l):</td><td>'+data.model_engine_l+'</td></tr>';
    	out += '<tr><td>Engine Displacement (cubic inches):</td><td>'+data.model_engine_ci+'</td></tr>';
    	out += '<tr><td>Engine Valves Per Cylinder:</td><td>'+data.model_engine_valves_per_cyl+'</td></tr>';
    	out += '<tr><td>Engine Valves:</td><td>'+data.model_engine_valves+'</td></tr>';
    	out += '<tr><td>Engine Max Power (HP):</td><td>'+data.model_engine_power_hp+'</td></tr>';
    	out += '<tr><td>Engine Max Power (PS):</td><td>'+data.model_engine_power_ps+'</td></tr>';
    	out += '<tr><td>Engine Max Power (kW):</td><td>'+data.model_engine_power_kw+'</td></tr>';
    	out += '<tr><td>Engine Max Power RPM:</td><td>'+data.model_engine_power_rpm+'</td></tr>';
    	out += '<tr><td>Engine Max Torque (Nm):</td><td>'+data.model_engine_torque_nm+'</td></tr>';
    	out += '<tr><td>Engine Max Torque (Lb-Ft):</td><td>'+data.model_engine_torque_lbft+'</td></tr>';
    	out += '<tr><td>Engine Max Torque (kgf-m):</td><td>'+data.model_engine_torque_kgm+'</td></tr>';
    	out += '<tr><td>Engine Max Torque RPM:</td><td>'+data.model_engine_torque_rpm+'</td></tr>';
    	out += '<tr><td>Engine Compression Ratio:</td><td>'+data.model_engine_compression+'</td></tr>';
    	out += '<tr><td>Engine Fuel Type:</td><td>'+data.model_engine_fuel+'</td></tr>';
    		
    	out += '<tr><td colspan="2"><hr/></td></tr>';
    	out += '<tr><td>Drive:</td><td>'+data.model_drive+'</td></tr>';
    	out += '<tr><td>Transmission Type:</td><td>'+data.model_transmission_type+'</td></tr>';
    	out += '<tr><td>Top Speed (KPH):</td><td>'+data.model_top_speed_kph+'</td></tr>';
    	out += '<tr><td>Top Speed (MPH):</td><td>'+data.model_top_speed_mph+'</td></tr>';
    	out += '<tr><td>0-100 kph (0-62mph):</td><td>'+data.model_0_to_100_kph+'</td></tr>';
    		
    	out += '<tr><td colspan="2"><hr/></td></tr>';
    	out += '<tr><td>Doors:</td><td>'+data.model_doors+'</td></tr>';
    	out += '<tr><td>Seats:</td><td>'+data.model_seats+'</td></tr>';
    	out += '<tr><td>Weight (kg):</td><td>'+data.model_weight_kg+'</td></tr>';
    	out += '<tr><td>Weight (lbs):</td><td>'+data.model_weight_lbs+'</td></tr>';
    	out += '<tr><td>Length (mm):</td><td>'+data.model_length_mm+'</td></tr>';
    	out += '<tr><td>Length (in):</td><td>'+data.model_length_in+'</td></tr>';
    	out += '<tr><td>Width (mm):</td><td>'+data.model_width_mm+'</td></tr>';
    	out += '<tr><td>Width (in):</td><td>'+data.model_width_in+'</td></tr>';
    	out += '<tr><td>Height (mm):</td><td>'+data.model_height_mm+'</td></tr>';
    	out += '<tr><td>Height (in):</td><td>'+data.model_height_in+'</td></tr>';
    	out += '<tr><td>Wheelbase (mm):</td><td>'+data.model_wheelbase_mm+'</td></tr>';
    	out += '<tr><td>Wheelbase (in):</td><td>'+data.model_wheelbase_in+'</td></tr>';
    	out += '<tr><td>Fuel Economy City(l/100km):</td><td>'+data.model_lkm_city+'</td></tr>';
    	out += '<tr><td>Fuel Economy City(mpg):</td><td>'+data.model_mpg_city+'</td></tr>';
    	out += '<tr><td>Fuel Economy HWY(l/100km):</td><td>'+data.model_lkm_hwy+'</td></tr>';
    	out += '<tr><td>Fuel Economy HWY(mpg):</td><td>'+data.model_mpg_hwy+'</td></tr>';
    	out += '<tr><td>Fuel Economy Mixed(l/100km):</td><td>'+data.model_lkm_mixed+'</td></tr>';
    	out += '<tr><td>Fuel Economy Mixed(mpg):</td><td>'+data.model_mpg_mixed+'</td></tr>';
    	out += '<tr><td>Fuel Capacity(l):</td><td>'+data.model_fuel_cap_l+'</td></tr>';
    	out += '<tr><td>Fuel Capacity(g):</td><td>'+data.model_fuel_cap_g+'</td></tr>';
    		
    	out += '</table>';
    		
    	out = out.replace(/>null</g, ">Not Available<");
    		
    	return out;
    },
   
    populateCarDataList : function(model_id)
    {
    	//Show this list
    	$("#"+this.trim_data_list_id).show();
    
    	//Hide the lists
    	$("#"+this.trim_list_id).hide();
    	$("#"+this.model_list_id).hide();
    	$("#"+this.make_list_id).hide();
    
    	//Set loading message
    	$("#"+this.trim_data_list_id).html('Loading Model Data...');
    	 
    	//Get Car Model JSON for the selected make
	$.getJSON(this.base_url+"?callback=?", {cmd:"getModel", model:model_id}, function(data) {
	
	    if(!carquery.responseError(data))
	    {
	        var out = '<div class="car_data_breadcrumbs"><a href="javascript:void()" onclick="$(\'#'+carquery.trim_data_list_id+'\').hide();$(\'#'+carquery.make_list_id+'\').show();$(\'#'+carquery.model_list_id+'\').show();">'+data[0].make_display+'</a> > ';
	        out +=	  '<a href="javascript:void()"  onclick="$(\'#'+carquery.trim_data_list_id+'\').hide();$(\'#'+carquery.make_list_id+'\').show();$(\'#'+carquery.model_list_id+'\').show();$(\'#'+carquery.trim_list_id+'\').show();">'+data[0].model_name+'</a></div><fieldset>';
	    
	   	out += carquery.carDataHTML(data[0]) + '</fieldset>';
	   
	       	$("#"+carquery.trim_data_list_id).html(out);
	    }
        });
    },
    
    
    populateCarData : function(model_data_id)
    {
    	this.model_data_id = model_data_id;
	this.cur_trim = $("select#"+this.trim_select_id).val();
	
	//Make sure there is a trim selected
	if(this.cur_trim == null || this.cur_trim == "")
	{
		$("#"+this.model_data_id).html("");
		alert('Please select a year, make, and model.');
		return;
	}
    	
 	//Set a loading message while we retrieve the data
        $("#"+this.model_data_id).html("Loading Model Data...");

        
        //Get Car Model JSON for the selected make
    	$.getJSON(this.base_url+"?callback=?", {cmd:"getModel", model:this.cur_trim}, function(data) {
 
    	
    	if(!carquery.responseError(data))
    	{
    		var out = carquery.carDataHTML(data[0]);
        	
        	$("#"+carquery.model_data_id).html(out);
        }
        });
    },
    
    yearSelectChange: function ()
    {        
        this.cur_year = $("select#"+this.year_select_id).val();
        
         //if no year supplied, clear makes, models, return;
	if(this.cur_year == "")
	{
		$("select#"+this.make_select_id).html(this.empty_option_html);
		$("select#"+this.model_select_id).html(this.empty_option_html);
	    	return;
    	}
    	
    	 //Set a loading message while we retrieve the data
        $("select#"+this.make_select_id).html("<option value=''>Loading Makes...</option>");
        
        //Get Car Model JSON for the selected make
    	$.getJSON(this.base_url+"?callback=?", {cmd:"getMakes", year:this.cur_year}, function(data) {
    	
    	if(!carquery.responseError(data))
    	{
    	
    		var temp_make = carquery.cur_make;
    		
        	carquery.populateMakeSelect(data);
        	
        	 //Re-select the make, if it is still in the options
        	$('select#'+carquery.make_select_id).val(temp_make);
        	
        	carquery.cur_make = temp_make;
        	
        	//Re-populate the models, perist option if possible
        	var temp_model_text = $("select#"+carquery.model_select_id+" option:selected").text();
        	
        	carquery.makeSelectChange(temp_model_text);
        	
        	//Re-populate the trim select
        	carquery.modelSelectChange();
        }
        });
    },
    
    makeSelectChange: function (modelText)
    {
    	this.cur_make = $("select#"+this.make_select_id).val();
    	
    	//if no make supplied, clear models, return;
    	if(this.cur_make == "")
    	{
    		$("select#"+this.model_select_id).html(this.empty_option_html);
    		return;
    	}
    
    	//Set a loading message while we retrieve the data
    	$("select#"+this.model_select_id).html("<option value=''>Loading Models...</option>");
    
    	//Get Car Model JSON for the selected make
	$.getJSON(this.base_url+"?callback=?", {cmd:"getModels", make:this.cur_make, year:this.cur_year }, function(data) {
	
		if(!carquery.responseError(data))
		{
    			carquery.populateModelSelect(data);

		
			//Reset the model option if specified
			if(modelText)
				$('select#'+carquery.model_select_id+' option').each(function() { this.selected = (this.text == modelText); });
			
        		carquery.cur_model = $('select#'+carquery.model_select_id).val();
        		
        		//Re-populate the trim select
        		carquery.modelSelectChange();
        	}
    	});
    },
    
    modelSelectChange: function ()
    {
        this.cur_model = $("select#"+this.model_select_id).val();
        	
        //if no model supplied, clear models, return;
        if(this.cur_model == "")
        {
        	$("select#"+this.trim_select_id).html(this.empty_option_html);
        	return;
        }
        
        //Set a loading message while we retrieve the data
        $("select#"+this.trim_select_id).html("<option value=''>Loading Trims...</option>");
        
        //Get Car Model JSON for the selected make
    	$.getJSON(this.base_url+"?callback=?", {cmd:"getTrims", make:this.cur_make, year:this.cur_year, model:this.cur_model }, function(data) {
    	
    		if(!carquery.responseError(data))
        		carquery.populateTrimSelect(data);
    		
            	carquery.cur_trim = $('select#'+carquery.trim_select_id).val();
        });
    },
    
    responseError: function (data)
    {
    	if(typeof data.error != 'undefined' && data.error != '')
	{
	 	alert(data.error);
		return true;
	}
	else
		return false;
    }
}
