$(document).ready(function() {


	// Fix IE from dropping Cleartype rendering on 
	// faded elements.  For full explanation, see
	// http://blog.bmn.name/2008/03/jquery-fadeinfadeout-ie-cleartype-glitch/
	(function($) {
		$.fn.customFadeTo = function(speed, opacity, callback) {
			$(this).fadeTo(speed, opacity, function() {
				if((!jQuery.support.opacity) && (opacity == 1))  {
					$(this).get(0).style.removeAttribute('filter');
				}
				if(callback != undefined)
					callback();
			});
		};
	
	})(jQuery);


    vw.hybrid.addWidget("flashid", "#FFFFFF");
	$('#hybridFooter').vwFooter();
	
	// Some global variables that govern the UI
	var modelOpacity = 0.3 // fade models to this opacity (0.0 to 1.0)
	var fadeSpeed = 200 // fade models this quickly (milliseconds)
	var rolloverFadeSpeed = 100 // fade rollovers this quickly (milliseconds)
	
	
	// sliderDoubleClass: models state of sliders with two sliders.
	// Note that this is now a defunct, unused class.
	var sliderDoubleClass = function() {
	    this.name = "";
	    this.valueLower = 0;
	    this.valueUpper = 1000;
	};
	
	// sliderSingleClass: models the state of sliders with one slider.
	var sliderSingleClass = function() {
	    this.name = "";
	    this.value = 0;
	    this.startingValue = 0;
	}
	
	// Booleans to model the AWD and TDI checkboxes
	var boolSearchAWD = false;
	var boolSearchTDI = false;
	
	// Instantiate the slider models 
	var sliderSeating = new sliderSingleClass;
	sliderSeating.name = "seating";
	sliderSeating.startingValue = 4;
	
	var sliderCargoSpace = new sliderSingleClass;
	sliderCargoSpace.name = "cargo space";
	sliderCargoSpace.startingValue = 4;

	var sliderHorsePower = new sliderSingleClass;
	sliderHorsePower.name = "horse power";
	sliderHorsePower.startingValue = 140;
	
	// Global variable to mark whether we are in reset or not
	var boolReset = false;
	
	// We will be storing all the XML information about each model in 
	// an array.
	var arrModels = [];
	
	// Base class for modeling the trimline data
	var classTrimlineData = function() {
	    this.name = "";
	    this.availableSeating = 0;
	    this.cargoSpace = 0;
	    this.horsePower = 0;
	    this.awd = false;
	    this.currentlyAvailable = true;
	};
	
	// Bit of fancy footwork here.  There are two kinds of models: those with trimlines
	// and those without.  Models without trimlines are basically models that have a single
	// global trimline.  So we will use the trimline data class we made above
	// to create a class for models without trimlines:
	var classModelWithoutTrimline = function() {};
    classModelWithoutTrimline.prototype = new classTrimlineData;
	classModelWithoutTrimline.constructor = classModelWithoutTrimline;
	
	// Further define the class
	classModelWithoutTrimline = function() {
	    this.cssclass = "";
	    this.tdi = false; 
	    this.currentlyAvailableTrims = true;
	    this.UpdateAvailability = function() {
	        var boolTest = true;
	        if (sliderCargoSpace.value > this.cargoSpace) {
	            boolTest = false;
	        }
	        if (sliderHorsePower.value > this.horsePower) {
	            boolTest = false;
	        }
	        if (sliderSeating.value > this.availableSeating) {
	            boolTest = false;
	        }
	        if (boolSearchAWD && !this.awd) {
	            boolTest = false;
	        }
	        if (boolSearchTDI && !this.tdi) {
	            boolTest = false;
	        }
	        
	        // We only need to change things if boolTest does not match this.currentlyAvailable.
	        if (boolTest != this.currentlyAvailable) {
	            // The visible state of the model needs to change.  But which way?
	            if (boolTest) {
	                // boolTest is true, this.currentlyAvaialble is therefore false, 
	                // so we need to make the item available
	                $(this.cssclass).customFadeTo(fadeSpeed, 1);
	            } else {
	                // boolTest is false, so this.currentlyAvailable is therefore true
	                // so we need to make the item unavailable
	                $(this.cssclass).customFadeTo(fadeSpeed, modelOpacity);
	            }
	            // Update the state of the object
	            this.currentlyAvailable = boolTest;
	        }
	    };
	}
	
	// Create a class for models that have trimlines
	var classModelWithTrimline = function() {
	    this.name = "";
	    this.cssclass = "";
	    this.tdi = false;
	    this.availableSeating = 0;
	    this.currentlyAvailable = true;
	    this.currentlyAvailableTrims = true;
	    this.trimlines = new Array;
	    this.UpdateAvailability = function() {
	        // This method does three things:
	        // 1.  It updates the trimlines based on the UI
	        // 2.  It updates the entire model based on seating and trimlines
	        // 3.  It updates the object properties to reflect the results of 1 and 2.
	        
	        // First, Update the trimlines based on the UI
	        var strTrimlines = "";
	        for (var i = 0; i < this.trimlines.length; i++) {
	            var boolTrimlineTest = true;
	            var strComma = ", ";
	            if (i == this.trimlines.length - 1) {
	                strComma = "";
	            }
	            
	            // Cargo space
		        if (sliderCargoSpace.value > this.trimlines[i].cargoSpace) {
		            boolTrimlineTest = false;
		        }
		        
		        // Horsepower
		        if (sliderHorsePower.value > this.trimlines[i].horsePower) {
		            boolTrimlineTest = false;
		        }
		        
		        // AWD checkbox
		        if (boolSearchAWD && !this.trimlines[i].awd) {
	                boolTrimlineTest = false;
		        }
		        
		        // TDI checkbox
		        // Bit more complicated: if we're searching for TDI, what we're interested in
		        // is whether or not this trimline is a TDI, because if it's not we want to fade it out.
		        if (boolSearchTDI) {
					var trimName = this.trimlines[i].name.toLowerCase()
		            if (trimName.indexOf("tdi") < 0) {
		                boolTrimlineTest = false;
		            }
		        }
		        
		        // Assemble the trimlines string
	            if (boolTrimlineTest) {
		            strTrimlines += this.trimlines[i].name + strComma;
	            } else {
	                strTrimlines += "<span>"+ this.trimlines[i].name + strComma + "<\/span>";
	            }
	            
	            // Update the object info for the trimline
	            this.trimlines[i].currentlyAvailable = boolTrimlineTest;
	        }
	        
	        // Update the trimline of the model
	        if (strTrimlines.length > 0) {
		        var strSelector = this.cssclass + " .model-trim";
		        $(strSelector).html(strTrimlines);
	        }
	        
	        // Next, check the seating slider to determine if the entire
	        // model needs to be disabled
	        var boolGlobalTest = true;
	        if ((sliderSeating.value > this.availableSeating)) {
	            boolGlobalTest = false;
	        }
	        
	        // Next, repurpose boolTrimlineTest so that it indicates whether or not all the trimlines
	        // are unavailable (which will affect the state of the entire model)
	        var boolTrimlineTest = false;
	        for (i = 0; i < this.trimlines.length; i++) {
	            if (this.trimlines[i].currentlyAvailable) {
	                boolTrimlineTest = true;
	            }
	        }
	        
	        // Okay, we now need to figure out if we need to disable or enable the entire model.
	        // First, we only need to do anything if or global and trimline tests are different
	        // than the current state of the model:
	        if ((boolGlobalTest != this.currentlyAvailable) || (boolTrimlineTest != this.currentlyAvailableTrims)) {
	            
	            if (this.currentlyAvailable && this.currentlyAvailableTrims) {
	                // Model is currently available.
	                // Does it need to be unavailable?
	                if (!boolGlobalTest || !boolTrimlineTest) {
	                    $(this.cssclass).customFadeTo(fadeSpeed, modelOpacity);
	                }
	            } else {
	                // Model is currently unavailable.
	                // Does it need to be available?
	                if (boolGlobalTest && boolTrimlineTest) {
	                    $(this.cssclass).customFadeTo(fadeSpeed, 1.0);
	                }
	            }
	            // Update the object properties to reflect the new state.
	            this.currentlyAvailable = boolGlobalTest;
	            this.currentlyAvailableTrims = boolTrimlineTest;
	        }
	    }
	}; 
			
	// Now that classes have been made, load in XML, instantiate
	// objects from those classes, and fill them with the XML data
	$.ajax({
	    type: "GET",
	    url: "/lineup/en/us/assets/models-all.xml",
	    dataType: "xml",
	    success: function(loadedXml) {
	        $(loadedXml).find("model").each(function(intCounter) {
	            // First, what kind of model is this?  One with trimlines or without?
	            if ($(this).find("trimlines").text()) {
	                // A model with one or more trimlines. 
	                arrModels[intCounter] = new classModelWithTrimline;
	                $(this).find("trimline").each(function(i) {
	                    strCurrentTrim = $(this).find("name").text();
	                    arrModels[intCounter].trimlines[i] = new classTrimlineData;
	                    arrModels[intCounter].trimlines[i].name = strCurrentTrim;
	                    arrModels[intCounter].trimlines[i].seating = $(this).find("seating").text();
	                    arrModels[intCounter].trimlines[i].cargoSpace = $(this).find("cargoSpace").text();
	                    arrModels[intCounter].trimlines[i].horsePower = $(this).find("horsePower").text();
	                    if ($(this).find("awd").text() == "true") {
	                        arrModels[intCounter].trimlines[i].awd = true;
	                    }
	                });
	            } else {
	                // Not a model with a trimline.
	                arrModels[intCounter] = new classModelWithoutTrimline;
	                arrModels[intCounter].cargoSpace = $(this).find("cargoSpace").text();
	                arrModels[intCounter].horsePower = $(this).find("horsePower").text();
	                if ($(this).find("awd").text() == "true") {
	                    arrModels[intCounter].awd = true;
	                }
	                if ($(this).find("tdi").text() == "true") {
	                    arrModels[intCounter].tdi = true;
	                }
	            }
	            arrModels[intCounter].name = $(this).find("name").text();
	            arrModels[intCounter].cssclass = $(this).find("class").text();
	            arrModels[intCounter].availableSeating = $(this).find("seating").text();
	        });
	        UpdateModels();
	    }
	});
	
	// Rollovers
	// sprites are handled by CSS, but content is handled by JS for
	// progressive enhancement.
	$(".model-items .link").hide();
	$(".model-group > li").hover(
	    function () {
	        var strThisClass = "." + $(this).attr("class");
	        $(this).children().children(".link").show();
	        $(this).addClass("over-state");
	        for (var i = 0; i < arrModels.length; i++) {
	            if (strThisClass.search(arrModels[i].cssclass) > -1) {
	                if (!arrModels[i].currentlyAvailable || !arrModels[i].currentlyAvailableTrims) {
	                    $(this).customFadeTo(100, 1.0);
	                }
	            }
	        }
	    },
	    function () {
	        $(this).children().children(".link").hide();
	        $(this).removeClass("over-state");
	        var strThisClass = "." + $(this).attr("class");
	        for (var i = 0; i < arrModels.length; i++) {
	            if (strThisClass.search(arrModels[i].cssclass) > -1) {
	                if (!arrModels[i].currentlyAvailable || !arrModels[i].currentlyAvailableTrims) {
	                    $(this).customFadeTo(rolloverFadeSpeed, modelOpacity);
	                }
	            }
	        }
	    }
	);
	
	// Progressive enhancement: Add link state to model images by floating over them 
	// a positioned link.
	$(".model-items").append("<li class='model-link'><a href=''>&nbsp;<\/a><\/li>");
	$(".model-link a").each(function(i) {
	    var strHref = $(this).parent().parent().children(".model-name").children("a").attr("href");
	    $(this).attr("href", strHref);
	});
	
	// Activate Sort By selector
	$("#select-sortby").change(function() {
	    var strSelected = $("#select-sortby option:selected").text();
	    if (strSelected == "Starting Price") {
	        $("#model").hide();
	        $("#price").show();
	    } else { 
	        $("#model").show();
	        $("#price").hide();
	    }
	    UpdateResetButton();
	});
	
	
	// Activate Seating slider
	$("#slider-seating .ui-slider").slider({
	    min : 4,
	    max: 7,
	    step: 1,
	    animate: true,
	    slide: function(event, ui) {
	       $(this).children().children().text(Math.round(ui.value));
	    },
	    change: function(event, ui) {
	       sliderSeating.value = $(this).children().children().html();
	       if (ui.value<=4){
	           $("#slider-seating p.caption").html("Friends")
	       }
	       if ((ui.value > 4) && (ui.value <= 6)) {
	           $("#slider-seating p.caption").html("Family")
	       }
	       if (ui.value > 6){
	           $("#slider-seating p.caption").html("Friends &amp; Family")
	       }
	       if (!boolReset) {
	       UpdateModels();
	       }
	       
	    }
	});
	
	// Activate cargospace slider
	$("#slider-cargospace .ui-slider").slider({
	    min : 4,
	    max: 144,
	    step: 2,
	    animate: true,
	    slide: function(event, ui) {
	       $("#slider-cargospace .ui-slider-handle span").html(Math.round(ui.value));
	       
	    },
	    change: function(event, ui) {
	       sliderCargoSpace.value = Math.round(ui.value);
	       if (ui.value<=30){
	           $("#slider-cargospace p.caption").html("Minimalist")
	       }
	       if ((ui.value > 30) && (ui.value <= 75)) {
	           $("#slider-cargospace p.caption").html("Weekender")
	       }
	       if (ui.value > 75) {
	           $("#slider-cargospace p.caption").html("Road Tripper")
	       }
	       if (!boolReset) {
	       UpdateModels();
	       }
	    }
	});
	
	// Activate Horsepower slider
	$("#slider-horsepower .ui-slider").slider({
	    min : 140,
	    max: 350,
	    step: 5,
	    animate: true,
	    slide: function(event, ui) {
	       $("#slider-horsepower .ui-slider-handle span").html(Math.round(ui.value));
	       
	    },
	    change: function(event, ui) {
	       sliderHorsePower.value = Math.round(ui.value);
	       if (ui.value<=200){
	           $("#slider-horsepower p.caption").html("Interstate")
	       }
	       if ((ui.value > 200) && (ui.value <= 280)) {
	           $("#slider-horsepower p.caption").html("Autobahn")
	       }
	       if (ui.value > 280) {
	           $("#slider-horsepower p.caption").html("Race Track")
	       }
	       if (!boolReset) {
	       UpdateModels();
	       }
	    }
	});
	
	
	// Attach events to AWD checkbox
	$("#checkbox-awd").click(function() {
	  if ($("#checkbox-awd").attr("checked")) {
	      boolSearchAWD = true;
	  } else {
	      boolSearchAWD = false;
	  }
	  if (!boolReset) {
	       UpdateModels();
	       }
	});
	
	// Attach events to TDI checkbox
	$("#checkbox-tdi").click(function() {
	  if ($("#checkbox-tdi").attr("checked")) {
	      boolSearchTDI = true;
	  } else {
	      boolSearchTDI = false;
	  }
	  if (!boolReset) {
	       UpdateModels();
	       }
	});
	
	
	function ResetAll() {
	// Convenience function to reset both the UI and object model to initial state
	    
	    boolReset = true;
	    
		// Sort By selector reset
		$("#select-sortby option:eq(0)").attr("selected", "selected");
		$("#model").show();
		$("#price").hide();
		
		// Seating slider reset
		$("#slider-seating .ui-slider").slider('value', sliderSeating.startingValue);
		$("#slider-seating span").html(sliderSeating.startingValue);
		sliderSeating.value = sliderSeating.startingValue;
		
		// Cargo Space slider reset
		$("#slider-cargospace .ui-slider").slider('value', sliderCargoSpace.startingValue);
		$("#slider-cargospace .ui-slider-handle span").html(sliderCargoSpace.startingValue);
		sliderCargoSpace.value = sliderCargoSpace.startingValue;
		
		// Horsepower slider reset
		$("#slider-horsepower .ui-slider").slider('value', sliderHorsePower.startingValue);
		$("#slider-horsepower .ui-slider-handle span").html(sliderHorsePower.startingValue);
		sliderHorsePower.value = sliderHorsePower.startingValue;

		// AWD and TDI checkboxes
		$(".container-checkboxes input:checkbox").each(function() {
		    $(this).removeAttr("checked");
		});
		boolSearchAWD = false;
		boolSearchTDI = false;
		// Update UI
		UpdateModels();
		boolReset = false;
	}
	
	
	function UpdateModels() {
	// Convenience function call all UpdateAvailability methods.
	    for (var i = 0; i < arrModels.length; i++) {
	        arrModels[i].UpdateAvailability();
	    }
	    UpdateResetButton();
	}
	
	// Functions to handle the reset button 
	function ActivateResetButton() {
	    $("#button-reset").show();
	}
	
	function DeactivateResetButton() {
    	$("#button-reset").hide();
	}	
	
	function UpdateResetButton() {
	    var boolButtonAvailable = false;
	    if (sliderSeating.value != sliderSeating.startingValue) {
	        boolButtonAvailable = true;
	    }
	    if (sliderCargoSpace.value != sliderCargoSpace.startingValue) {
	        boolButtonAvailable = true;
	    }
	    if (sliderHorsePower.value != sliderHorsePower.startingValue) {
	        boolButtonAvailable = true;
	    }
	    if (boolSearchAWD) {
	        boolButtonAvailable = true;
	    }
	    if (boolSearchTDI) {
	        boolButtonAvailable = true;
	    }
	    if ($("#select-sortby option:eq(1)").attr("selected")) {
	        boolButtonAvailable = true;
	    }
	    
	    if (boolButtonAvailable) {
	        ActivateResetButton();
	    } else {
	        DeactivateResetButton();
	    }
	}
	
	// Attach events to reset button 
	$("#button-reset").click(function(){
	    ResetAll();
	})
	
	// Set initial conditions on load
	ResetAll();
	
});