/* Manufacturer Incentives Widget JS v0.2 by Josh Lizarraga */
/* Copyright 2009 Autofusion.com */

(function(){

/* AF Library */

if(typeof(YAHOO.AUTOFUSION) == "undefined"){
	YAHOO.namespace("AUTOFUSION");
}
if(typeof(YAHOO.AUTOFUSION.items) == "undefined"){
	YAHOO.AUTOFUSION.items = new Object();
}
var AF = YAHOO.AUTOFUSION;

/* Manufacturer Incentives Widget */

// MIW Object:
AF.Incentives = new Object();

// Widget Constructor:
AF.Incentives.Widget = function(afID, afConfID, afConfig){
	// Properties:
	this.id = (afID) ? afID : false;
	this.confid = (afConfID) ? afConfID : false;
	this.config = (afConfig) ? afConfig : false;
	this.container = document.getElementById(this.id);
	this.MIL = [];
	this.completedRequests = 0;
	this.makes = [];
	this.results = [];
	this.currentResults = [];
	this.currentResultIndex = 0;
	this.quoteCGI = "/cgi-bin/quick_quote.cgi";
	this.detailsConfid = false;
	this.detailsURLs = false;
	this.altTemplate = false;
	this.savedIncentive = false;
	this.savedButtons = false;
	this.fadeLevel = 0.5;
	this.fadeSpeed = 0.25;
	this.fadeEasing = YAHOO.util.Easing.easeOut;
	this.header = false;
	this.body = false;
	this.nav = false;
	this.footer = false;
	this.selectYear = false;
	this.selectModel = false;
	this.prev = false;
	this.next = false;
	this.viewing = false;
	this.info = false;
	this.form = false;
	this.busy = false;
	this.groupSite = false;
	if(this.config != false){
		for(var i in this.config){
			this[i] = this.config[i];
		}
	}
	var that = this;
	// Validation:
	this.validate = {
		text: function(pInput){
			if(pInput.value.length > 1){
				return true;
			} else {
				return "Please enter a valid name.";
			}
		},
		phone: function(pInput){
			var oStripped = pInput.value.replace(/[\(\)\.\-\ ]/g, "");
			oStripped = parseInt(oStripped);
			if(isNaN(oStripped) == false){
				if((oStripped + "").length == 7 || (oStripped + "").length == 10 || (oStripped + "").length == 11){
					return true;
				} else {
					return "Please enter a valid phone number.";
				}
			} else {
				return "Please enter a valid phone number.";
			}
		},
		email: function(pInput){
			var oPattern = /^.+@.+\..{2,6}$/;
			var oIllegal = /[\s\(\)\<\>\,\;\:\\\/\"\[\]]/;
			if(pInput.value.length > 1 && oPattern.test(pInput.value) && pInput.value.match(oIllegal) == null){
				return true;
			} else {
				return "Please enter a valid email address.";
			}
		}
	}; // this.validate{}
	// Methods:
	this.resultObject = function(pIncentive, pIndex){
		// Basic:
		this.year = that.MIL[0].getValue(pIncentive.getElementsByTagName("year")[0]);
		this.make = that.MIL[0].getValue(pIncentive.getElementsByTagName("make")[0]);
		this.model = that.MIL[0].getValue(pIncentive.getElementsByTagName("model")[0]);
		this.image = that.MIL[0].getValue(pIncentive.getElementsByTagName("image")[0]);
		// Rebate:
		this.rebate = false;
		if(pIncentive.getElementsByTagName("amount").length > 0){
			this.rebate = that.MIL[0].getValue(pIncentive.getElementsByTagName("amount")[1]);
		}
		// Rates:
		var oRates = pIncentive.getElementsByTagName("rate");
		this.lowestAPR = 100.00;
		this.rates = [];
		for(var i=0; i<oRates.length; i++){
			var oAPR = parseFloat(that.MIL[0].getValue(oRates[i]));
			if(oAPR < this.lowestAPR){
				this.lowestAPR = oAPR;
			}
			var oTerm = oRates[i].getAttribute("term");
			oTerm = (oTerm.toLowerCase().indexOf("months") > -1) ? oTerm : oTerm + " Months";
			this.rates.push({
				term: oTerm,
				apr: oAPR
			});
		}
		// Lease Special:
		this.lease = false;
		var oLeases = pIncentive.getElementsByTagName("special_lease");
		if(oLeases.length > 0){
			this.lease = [];
			for(var i=0; i<oLeases.length; i++){
				this.lease.push({
					trim: that.MIL[0].getValue(oLeases[i].getElementsByTagName("trim")[0]),
					text: that.MIL[0].getValue(oLeases[i].getElementsByTagName("text")[0])
				});
			}
		}
		// Trims:
		this.appliesTo = that.MIL[0].getValue(pIncentive.getElementsByTagName("trims")[0]) + '.';
		// URL:
		this.url = that.MIL[0].getValue(pIncentive.getElementsByTagName("details_link")[0]);
		if(that.altTemplate != false){
			this.url = this.url.replace(/TrimsIncentives/, that.altTemplate);
		}
		if(that.detailsConfid != false){
			this.url = this.url.replace(/confid_.*\//, 'confid_' + that.detailsConfid + '/');
		}
		if(that.detailsURLs != false){
			this.url = that.detailsURLs[pIndex] + this.url;
		}
		// Disclaimer:
		this.disclaimer = "<strong>Applies to: " + this.appliesTo + "</strong><br />" + that.MIL[0].getValue(pIncentive.getElementsByTagName("comment")[0]) + "<br />Expires " + that.MIL[0].getValue(pIncentive.getElementsByTagName("expiration")[0]) + '.<br /><a href="' + this.url + '#trims_incentives">Click here</a> for complete terms and conditions.';
		// Push:
		if(typeof(that.makes[this.make]) == 'undefined'){
			that.makes[this.make] = {}; // Object because indexes will be integers.
		}
		if(typeof(that.makes[this.make][this.year]) == 'undefined'){
			that.makes[this.make][this.year] = [];
		}
		if(typeof(that.makes[this.make][this.year][this.model]) == 'undefined'){
			that.makes[this.make][this.year][this.model] = [];
		}
		that.makes[this.make][this.year][this.model].push(this);
	}; // this.resultObject()
	this.fadeContent = function(pTarget, pOpacity, pCallback){
		var oFade = new YAHOO.util.Anim(pTarget, {
				opacity: { to: pOpacity }
			}, that.fadeSpeed, that.fadeEasing);
		oFade.animate();
		if(YAHOO.env.ua.ie == 6 || YAHOO.env.ua.ie == 7){
			oFade.onComplete.subscribe(function(){
				pTarget.style.removeAttribute("filter");
			});
		}
		if(pCallback){
			oFade.onComplete.subscribe(pCallback);
		}
	}; // this.fadeContent()
	this.startLoad = function(){
		that.fadeContent(that.header, that.fadeLevel);
		that.fadeContent(that.body, that.fadeLevel);
		that.fadeContent(that.footer, that.fadeLevel, function(){
			that.container.appendChild(that.loadBar);
			that.toggleSelects(true);
			that.busy = !that.busy;
		});
	}; // this.startLoad()
	this.endLoad = function(){
		that.fadeContent(that.header, 1);
		that.fadeContent(that.body, 1);
		that.fadeContent(that.footer, 1, function(){
			that.container.removeChild(that.loadBar);
			that.toggleSelects(false);
			that.busy = !that.busy;
		});
	}; // this.endLoad()
	this.toggleSelects = function(pBoolean){
		if(YAHOO.util.Dom.inDocument(that.selectYear)){
			that.selectYear.disabled = pBoolean;
		}
		if(YAHOO.util.Dom.inDocument(that.selectModel)){
			that.selectModel.disabled = pBoolean;
		}
	}; // this.toggleSelects()
	this.populateHeader = function(){
		// Models:
		that.selectModel = document.createElement("select");
		that.selectModel.className = "miw-select-model";
		that.selectModel.disabled = true;
		var oFirstOption = document.createElement("option");
		oFirstOption.value = 'none';
		oFirstOption.innerHTML = "Select a Model:";
		that.selectModel.appendChild(oFirstOption);
		var oSecondOption = document.createElement("option");
		oSecondOption.value = "none";
		oSecondOption.innerHTML = "---";
		that.selectModel.appendChild(oSecondOption);
		for(var fMake in that.makes){
			// Loop through makes:
			if(that.makes.hasOwnProperty(fMake)){
				var oOptgroup = document.createElement("optgroup");
				oOptgroup.label = fMake;
				that.selectModel.appendChild(oOptgroup);
				for(var fYear in that.makes[fMake]){
					// Loop through years:
					if(that.makes[fMake].hasOwnProperty(fYear)){
						var oYear = document.createElement("option");
						oYear.value = 'none';
						oYear.innerHTML = '<strong>' + fYear + '</strong>';
						oOptgroup.appendChild(oYear);
						for(var fModel in that.makes[fMake][fYear]){
							// Loop through models:
							if(that.makes[fMake][fYear].hasOwnProperty(fModel)){
								var oOption = document.createElement("option");
								oOption.value = fYear + '|' + fModel;
								oOption.innerHTML = '&nbsp;&nbsp;&nbsp;&nbsp;' + fModel; // **** you IE.
								oOptgroup.appendChild(oOption);
							}
						}
					}
				}
			}
		}
		if(!that.groupSite){
			var oLastOption = document.createElement("option");
			oLastOption.value = "none";
			oLastOption.innerHTML = "---";
			that.selectModel.appendChild(oLastOption);
			var oAllModels = document.createElement("option");
			oAllModels.value = 'All';
			oAllModels.innerHTML = "View All Incentives";
			that.selectModel.appendChild(oAllModels);
		}
		that.header.appendChild(that.selectModel);
	}; // this.populateHeader()
	this.populateNav = function(){
		that.prev = document.createElement("a");
		that.prev.className = "miw-prev";
		that.prev.href = "javascript:void(0);";
		that.prev.innerHTML = "Previous";
		that.nav.appendChild(that.prev);
		that.next = document.createElement("a");
		that.next.className = "miw-next";
		that.next.href = "javascript:void(0);";
		that.next.innerHTML = "Next";
		that.nav.appendChild(that.next);
		that.viewing = document.createElement("div");
		that.viewing.className = "miw-viewing";
		that.viewing.innerHTML = "Please select a model.";
		that.nav.appendChild(that.viewing);
		var oClear = document.createElement("div");
		oClear.className = "miw-clear";
		that.nav.appendChild(oClear);
	}; // this.populateNav()
	this.populateFooter = function(){
		that.footer.innerHTML = '\
			<a class="miw-links-af" href="http://www.autofusion.com/" target="_blank">&copy;2010 Autofusion.com</a>\
			<a class="miw-links-all" href="/incentives.html">View all Incentives</a>\
			<div class="miw-clear"></div>\
		';
	}; // this.populateFooter()
	this.infoBox = function(pColor, pMessage){
		that.info = document.createElement("div");
		that.info.className = "miw-info-box miw-box-" + pColor;
		that.info.innerHTML = pMessage;
		that.body.appendChild(that.info);
	}; // this.infoBox()
	this.removeAltContent = function(){
		var oLoaders = YAHOO.util.Dom.getElementsByClassName("miw-loading", null, that.container);
		for(var i=0; i<oLoaders.length; i++){
			oLoaders[i].parentNode.removeChild(oLoaders[i]);
		}
	}; // this.removeAltContent()
	this.sortIncentives = function(pXML, pIndex){
		var oIncentives = pXML.getElementsByTagName("incentive");
		for(var i=0; i<oIncentives.length; i++){
			that.results.push(new that.resultObject(oIncentives[i], pIndex));
		}
	}; // this.sortIncentives()
	this.loadIncentive = function(pIndex){
		var oIndex = (pIndex) ? pIndex : that.currentResultIndex;
		that.currentResultIndex = oIndex;
		var oResult = that.currentResults[oIndex];
		that.viewing.innerHTML = "Viewing " + (that.currentResultIndex + 1) + " of " + (that.currentResults.length) + " Results";
		that.wrapper.innerHTML = '';
		var oIncentiveDiv = document.createElement("div");
		oIncentiveDiv.className = "miw-incentive";
		that.wrapper.appendChild(oIncentiveDiv);
		if(oResult.rebate != false){
			var oAS = "OR AS";
			oIncentiveDiv.innerHTML = '\
				<div class="miw-rebate-amount">' + oResult.rebate + '</div>\
				<div class="miw-rebate-after">Factory<br />Rebate!</div>\
				<div class="miw-clear"></div>\
			';
		} else {
			var oAS = "AS";
		}
		if(oResult.rates.length > 0){
			var oRatesHTML = '';
			for(var i=0; i<oResult.rates.length; i++){
				oRatesHTML += '<div>' + oResult.rates[i].apr + '% up to ' + oResult.rates[i].term + '</div>';
			}
			oIncentiveDiv.innerHTML += '\
				<div class="miw-apr">\
					<div class="miw-apr-before">' + oAS + '<br />LOW AS</div>\
					<div class="miw-apr-amount">' + oResult.lowestAPR + '%</div>\
					<div class="miw-apr-after">APR!</div>\
				</div>\
				<div class="miw-rates">' + oRatesHTML + '</div>\
				<div class="miw-clear"></div>\
			';
		}
		if(oResult.lease != false){
			for(var i in oResult.lease){
				if (oResult.lease[i].text && oResult.lease[i].trim) {
				oIncentiveDiv.innerHTML += '\
					<div class="miw-lease"><span>Lease Offer:</span> ' + oResult.lease[i].text + ' <small>(Trim: ' + oResult.lease[i].trim + ')</small></div>\
				';
				}
			}
		}
		that.wrapper.innerHTML += '\
			<div id="' + that.confid + '-image" class="miw-image">\
				<img src="' + oResult.image + '" alt="' + oResult.year + ' ' + oResult.make + ' ' + oResult.model + '" />\
			</div>\
			<div class="miw-disclaimer">' + oResult.disclaimer + '</div>\
			<div class="miw-clear"></div>\
			<div class="miw-buttons">\
				<a class="miw-inventory" href="' + oResult.url + '#trims_incentives">View More Details</a>\
				<a class="miw-quote" href="javascript:void(0);">Get a Quick Quote</a>\
			</div>\
		';
	}; // this.loadIncentive()
	this.getIncentive = function(pMake, pModel, pYear){
		// Info box?
		var oInfos = YAHOO.util.Dom.getElementsByClassName("miw-info-box", "div", that.container);
		for(var i=0; i<oInfos.length; i++){
			oInfos[i].parentNode.removeChild(oInfos[i]);
		}
		// Reset index:
		that.currentResultIndex = 0;
		// Load incentive(s):
		that.currentResults = that.makes[pMake][pYear][pModel];
		that.loadIncentive();
		if(that.currentResults.length < 2){
			that.fadeContent(that.nav, that.fadeLevel);
		} else {
			that.fadeContent(that.nav, 1);
		}
	}; // this.getIncentive()
	this.showQuote = function(){
		that.busy = true;
		that.fadeContent(that.nav, that.fadeLevel);
		var oResult = that.currentResults[that.currentResultIndex];
		var oIncentiveDiv = YAHOO.util.Dom.getElementsByClassName("miw-incentive")[0];
		that.savedIncentive = oIncentiveDiv.innerHTML;
		var oButtonsDiv = YAHOO.util.Dom.getElementsByClassName("miw-buttons")[0];
		that.savedButtons = oButtonsDiv.innerHTML;
		oIncentiveDiv.innerHTML = '\
			<div class="miw-quote-title">Free Price Quote</div>\
			<div class="miw-quote-subtitle">All fields are required.</div>\
			<form class="miw-quote-form" action="' + that.quoteCGI + '" method="POST">\
				<input type="hidden" name="comments" value="Incentives Widget Lead" />\
				<input type="hidden" name="year" value="' + oResult.year + '" />\
				<input type="hidden" name="make" value="' + that.make + '" />\
				<input type="hidden" name="model" value="' + oResult.model + '" />\
				<span>Name:</span>\
				<input type="text" name="firstname" />\
				<div class="miw-clear"></div>\
				<span>Phone:</span>\
				<input type="text" name="dayphone" />\
				<div class="miw-clear"></div>\
				<span>Email:</span>\
				<input type="text" name="email" />\
				<div class="miw-clear"></div>\
				<input class="submit" type="submit" value="Submit" />\
			</form>\
		';
		oButtonsDiv.innerHTML = '\
			<a class="miw-submit-form" href="#">Submit Quote Form</a>\
			<a class="miw-cancel-form" href="#">Back to Results</a>\
		';
		that.form = that.container.getElementsByTagName("form")[0];
		YAHOO.util.Event.addListener(that.form, 'submit', that.validateForm);
	}; // this.showQuote()
	this.validateForm = function(e){
		var oValid = true;
		var oForm = that.container.getElementsByTagName("form")[0];
		var oInputs = oForm.getElementsByTagName("input");
		var oBroken = false;
		for(var i=0; i<oInputs.length; i++){
			if(oBroken == false){
				if(oInputs[i].type != "hidden"){
					switch(oInputs[i].name){
						case "firstname":
							oValid = that.validate.text(oInputs[i]);
							if(oValid != true){
								oBroken = true;
							}
							break;
						case "dayphone":
							oValid = that.validate.phone(oInputs[i]);
							if(oValid != true){
								oBroken = true;
							}
							break;
						case "email":
							oValid = that.validate.email(oInputs[i]);
							if(oValid != true){
								oBroken = true;
							}
							break;
						default:
							oValid = that.validate.text(oInputs[i]);
					}
				}
			}
		}
		if(oValid === true){
			that.form.submit();
			return true;
		} else {
			alert(oValid);
			if(typeof(e) != 'undefined'){
				YAHOO.util.Event.preventDefault(e);
			}
			return false;
		}
	}; // this.validateForm()
	this.handleChange = function(e){
		YAHOO.util.Event.stopPropagation(e);
		YAHOO.util.Event.preventDefault(e);
		var oTarget = YAHOO.util.Event.getTarget(e);
		if(oTarget.nodeName.toUpperCase() == "SELECT"){
			var oOption = oTarget.options[oTarget.selectedIndex];
			switch(oOption.value){
				case 'none':
					oTarget.selectedIndex = 0;
					break;
				case "All":
					window.location.href = "/incentives.html";
					break;
				default:
					var oMake = YAHOO.util.Dom.getAncestorByTagName(oOption, 'optgroup').label;
					var oModel = oOption.value.split('|')[1];
					var oYear = oOption.value.split('|')[0];
					that.getIncentive(oMake, oModel, oYear);
			}
		}
	}; // this.handleChange()
	this.handleClick = function(e){
		YAHOO.util.Event.stopPropagation(e);
		var oTarget = YAHOO.util.Event.getTarget(e);
		switch(oTarget.className){
			case "miw-prev":
				if(that.currentResultIndex > 0 && that.busy == false){
					that.currentResultIndex--;
					that.loadIncentive();
				}
				break;
			case "miw-next":
				if(that.currentResultIndex + 1 < that.currentResults.length && that.busy == false){
					that.currentResultIndex++;
					that.loadIncentive();
				}
				break;
			case "miw-quote":
				that.showQuote();
				break;
			case "miw-submit-form":
				that.validateForm();
				break;
			case "miw-cancel-form":
				if(that.currentResults.length < 2){
					that.fadeContent(that.nav, that.fadeLevel);
				} else {
					that.fadeContent(that.nav, 1);
				}
				that.busy = false;
				that.loadIncentive();
				break;
			default:
				return true;
		}
	}; // this.handleClick()
	// Init:
	this.init = function(){
		// Header:
		this.header = document.createElement("div");
		this.header.className = "miw-header";
		this.container.appendChild(this.header);
		// Body:
		this.body = document.createElement("div");
		this.body.className = "miw-body";
		this.container.appendChild(this.body);
		// Footer:
		this.footer = document.createElement("div");
		this.footer.className = "miw-footer";
		this.container.appendChild(this.footer);
		// Load Bar:
		this.loadBar = document.createElement("div");
		this.loadBar.className = "miw-load-bar";
		// Start loading:
		this.startLoad();
		// Remove noscript content:
		this.removeAltContent();
		// Run when the requests are done:
		var requestsComplete = function(){
			if(that.results.length == 0){
				that.infoBox("red", "There are no current incentives available. Please check back soon.");
			} else {
				// Header II:
				that.populateHeader();
				// Nav:
				that.nav = document.createElement("div");
				that.nav.className = "miw-nav";
				that.body.appendChild(that.nav);
				// Incentive Wrapper:
				that.wrapper = document.createElement("div");
				that.wrapper.className = "miw-wrapper";
				that.body.appendChild(that.wrapper);
				// Continue loading:
				that.populateNav();
				that.populateFooter();
				that.infoBox("green", "Select a model to see available incentives.");
				// Attach listeners:
				YAHOO.util.Event.addListener(that.container, "click", that.handleClick);
				if(YAHOO.env.ua.ie > 0){
					// IE's "change" event does not bubble, and YUI 2.7.0 doesn't fix it. WAH!
					YAHOO.util.Event.addListener(that.container.getElementsByTagName("select"), "change", that.handleChange);
				} else {
					YAHOO.util.Event.addListener(that.container, "change", that.handleChange);
				}
			}
			// End loading:
			that.endLoad();
		};
		// Make requests:
		this.confid = this.confid.split(',');
		for(var i=0; i<this.confid.length; i++){
			var antiRace = i;
			this.MIL[i] = new MILAPI(this.confid[i]);
			this.MIL[i].getAll(function(pIndex){
				that.sortIncentives(that.MIL[pIndex].XML, pIndex);
				that.completedRequests++;
				if(that.completedRequests == that.confid.length){
					requestsComplete();
				}
			}, antiRace + ''); // this.MIL.getAll()
		}
	}; // this.init()
}; // AF.Incentives.Widget()

// Table Constructor:
AF.Incentives.Table = function(afID, afConfID, afConfig){
	// Properties:
	this.id = (afID) ? afID : false;
	this.confid = (afConfID) ? afConfID : false;
	this.config = (afConfig) ? afConfig : false;
	this.container = document.getElementById(this.id);
	this.MIL = [];
	this.completedRequests = 0;
	this.DS = false;
	this.DT = false;
	this.results = [];
	this.height = 200;
	this.sortBy = 0;
	if(this.config != false){
		for(var i in this.config){
			this[i] = this.config[i];
		}
	}
	var that = this;
	// Methods:
	this.resultObject = function(pIncentive){
		// Basic:
		this.make = that.MIL[0].getValue(pIncentive.getElementsByTagName('make')[0]);
		this.year = that.MIL[0].getValue(pIncentive.getElementsByTagName('year')[0]);
		this.model = that.MIL[0].getValue(pIncentive.getElementsByTagName('model')[0]);
		// Rebate:
		this.rebate = 'N/A';
		if(pIncentive.getElementsByTagName('amount').length > 0){
			this.rebate = that.MIL[0].getValue(pIncentive.getElementsByTagName('amount')[1]);
		}
		// Rates:
		this.rate = 100;
		var oRates = pIncentive.getElementsByTagName('rate');
		for(var i=0; i<oRates.length; i++){
			var oRate = parseFloat(that.MIL[0].getValue(oRates[i]));
			if(oRate < this.rate){
				this.rate = oRate + '%*';
			}
		}
		if(this.rate == 100){
			this.rate = 'N/A';
		}
		// Link:
		this.link = '<a href="' + that.MIL[0].getValue(pIncentive.getElementsByTagName('details_link')[0]) + '">View Details</a>';
	}; // this.resultObject()
	this.infoBox = function(pColor, pMessage){
		that.info = document.createElement('div');
		that.info.className = 'miw-info-box miw-box-' + pColor;
		that.info.innerHTML = pMessage;
		that.container.appendChild(that.info);
	}; // this.infoBox()
	this.sortIncentives = function(pXML){
		var oIncentives = pXML.getElementsByTagName("incentive");
		for(var i=0; i<oIncentives.length; i++){
			that.results.push(new that.resultObject(oIncentives[i]));
		}
	}; // this.sortIncentives()
	// Init:
	this.init = function(){
		// Run when the requests are done:
		var requestsComplete = function(){
			if(that.results.length == 0){
				that.infoBox('red', 'There are no current incentives available. Please check back soon.');
			} else {
				// DataSource:
				that.DS = new YAHOO.util.LocalDataSource(that.results);
				that.DS.responseType = YAHOO.util.LocalDataSource.TYPE_JSARRAY;
				that.DS.responseSchema = { fields: [ 'make', 'year', 'model', 'rebate', 'rate', 'link' ] };
				// DataTable:
				that.DT = new YAHOO.widget.ScrollingDataTable(that.container,[
					{ key: 'make', label: 'Make', sortable: true },
					{ key: 'year', label: 'Year', sortable: true },
					{ key: 'model', label: 'Model', sortable: true },
					{ key: 'rebate', label: 'Rebate', sortable: true },
					{ key: 'rate', label: 'Special APR', sortable: true },
					{ key: 'link', label: 'More Info' }
				], that.DS, { height: that.height + 'px' });
				that.DT.sortColumn(that.DT.getColumn(that.sortBy));
			}
		};
		// Make requests:
		this.confid = this.confid.split(',');
		for(var i=0; i<this.confid.length; i++){
			var antiRace = i;
			this.MIL[i] = new MILAPI(this.confid[i]);
			this.MIL[i].getAll(function(pIndex){
				that.sortIncentives(that.MIL[pIndex].XML);
				that.completedRequests++;
				if(that.completedRequests == that.confid.length){
					requestsComplete();
				}
			}, antiRace + ''); // this.MIL.getAll()
		}
	}; // this.init()
}; // AF.Incentives.Table()

// Custom Constructor:
AF.Incentives.Custom = function(afConfID, afConfig){
	
	// Properties:
	this.confid = (afConfID) ? afConfID : false;
	this.config = (afConfig) ? afConfig : false;
	this.MIL = [];
	this.completedRequests = 0;
	this.makes = [];
	this.results = [];
	this.currentResults = [];
	this.currentResultIndex = 0;
	this.detailsConfid = false;
	this.detailsURLs = false;
	this.altTemplate = false;
	this.busy = false;
	this.groupSite = false;
	
	// Element Properties:
	this.selector = false;
	this.selectorDisplay = 'block';
	
	this.previous = false;
	this.previousDisplay = 'block';
	
	this.next = false
	this.nextDisplay = 'block';
	
	this.viewing = false;
	this.viewingPrefix = 'Viewing ';
	this.viewingBridge = ' of ';
	this.viewingSuffix = ' Results';
	this.viewingDisplay = 'block';
	
	this.rebate = false;
	this.rebatePrefix = '';
	this.rebateSuffix = ' Factory Rebate!';
	this.rebateDisplay = 'block';
	
	this.aprLow = false;
	this.aprPrefix = 'As low as ';
	this.aprSuffix = '% APR!';
	this.aprDisplay = 'block';
	
	this.rates = false;
	this.ratesPrefix = '';
	this.ratesBridge = '% up to ';
	this.ratesSuffix = '';
	this.ratesDisplay = 'block';
	
	this.lease = false;
	this.leasePrefix = 'Lease Offer: ';
	this.leaseBridge = ' (Trim: ';
	this.leaseSuffix = ')';
	this.leaseDisplay = 'block';
	
	this.image = false;
	this.imageDisplay = 'block';
	
	this.disclaimer = false;
	this.disclaimerDisplay = 'block';
	
	this.details = false;
	this.detailsDisplay = 'block';
	
	this.quote = false;
	this.quoteURL = '/quick_quote.html';
	this.quoteDisplay = 'block';
	
	// Config:
	if(this.config != false){
		for(var i in this.config){
			this[i] = this.config[i];
		}
	}
		
	var that = this;
	
	// Validation:
	this.validate = {
		text: function(pInput){
			if(pInput.value.length > 1){
				return true;
			} else {
				return "Please enter a valid name.";
			}
		},
		phone: function(pInput){
			var oStripped = pInput.value.replace(/[\(\)\.\-\ ]/g, "");
			oStripped = parseInt(oStripped);
			if(isNaN(oStripped) == false){
				if((oStripped + "").length == 7 || (oStripped + "").length == 10 || (oStripped + "").length == 11){
					return true;
				} else {
					return "Please enter a valid phone number.";
				}
			} else {
				return "Please enter a valid phone number.";
			}
		},
		email: function(pInput){
			var oPattern = /^.+@.+\..{2,6}$/;
			var oIllegal = /[\s\(\)\<\>\,\;\:\\\/\"\[\]]/;
			if(pInput.value.length > 1 && oPattern.test(pInput.value) && pInput.value.match(oIllegal) == null){
				return true;
			} else {
				return "Please enter a valid email address.";
			}
		}
	}; // this.validate{}
	
	// Methods:
	this.resultObject = function(pIncentive, pIndex){
		// Basic:
		this.year = that.MIL[0].getValue(pIncentive.getElementsByTagName("year")[0]);
		this.make = that.MIL[0].getValue(pIncentive.getElementsByTagName("make")[0]);
		this.model = that.MIL[0].getValue(pIncentive.getElementsByTagName("model")[0]);
		this.image = that.MIL[0].getValue(pIncentive.getElementsByTagName("image")[0]);
		// Rebate:
		this.rebate = false;
		if(pIncentive.getElementsByTagName("amount").length > 0){
			this.rebate = that.MIL[0].getValue(pIncentive.getElementsByTagName("amount")[1]);
		}
		// Rates:
		var oRates = pIncentive.getElementsByTagName("rate");
		this.lowestAPR = 100.00;
		this.rates = [];
		for(var i=0; i<oRates.length; i++){
			var oAPR = parseFloat(that.MIL[0].getValue(oRates[i]));
			if(oAPR < this.lowestAPR){
				this.lowestAPR = oAPR;
			}
			var oTerm = oRates[i].getAttribute("term");
			oTerm = (oTerm.toLowerCase().indexOf("months") > -1) ? oTerm : oTerm + " Months";
			this.rates.push({
				term: oTerm,
				apr: oAPR
			});
		}
		// Lease Special:
		this.lease = false;
		var oLeases = pIncentive.getElementsByTagName("special_lease");
		if(oLeases.length > 0){
			this.lease = [];
			for(var i=0; i<oLeases.length; i++){
				this.lease.push({
					trim: that.MIL[0].getValue(oLeases[i].getElementsByTagName("trim")[0]),
					text: that.MIL[0].getValue(oLeases[i].getElementsByTagName("text")[0])
				});
			}
		}
		// Trims:
		this.appliesTo = that.MIL[0].getValue(pIncentive.getElementsByTagName("trims")[0]) + '.';
		// URL:
		this.url = that.MIL[0].getValue(pIncentive.getElementsByTagName("details_link")[0]);
		if(that.altTemplate != false){
			this.url = this.url.replace(/TrimsIncentives/, that.altTemplate);
		}
		if(that.detailsConfid != false){
			this.url = this.url.replace(/confid_.*\//, 'confid_' + that.detailsConfid + '/');
		}
		if(that.detailsURLs != false){
			this.url = that.detailsURLs[pIndex] + this.url;
		}
		// Disclaimer:
		this.disclaimer = "<strong>Applies to: " + this.appliesTo + "</strong><br />" + that.MIL[0].getValue(pIncentive.getElementsByTagName("comment")[0]) + "<br />Expires " + that.MIL[0].getValue(pIncentive.getElementsByTagName("expiration")[0]) + '.<br /><a href="' + this.url + '#trims_incentives">Click here</a> for complete terms and conditions.';
		// Push:
		if(typeof(that.makes[this.make]) == 'undefined'){
			that.makes[this.make] = {}; // Object because indexes will be integers.
		}
		if(typeof(that.makes[this.make][this.year]) == 'undefined'){
			that.makes[this.make][this.year] = [];
		}
		if(typeof(that.makes[this.make][this.year][this.model]) == 'undefined'){
			that.makes[this.make][this.year][this.model] = [];
		}
		that.makes[this.make][this.year][this.model].push(this);
	}; // this.resultObject()
	this.populateSelector = function(){
		var oFirstOption = document.createElement("option");
		oFirstOption.value = 'none';
		oFirstOption.innerHTML = "Select a Model:";
		that.selector.appendChild(oFirstOption);
		var oSecondOption = document.createElement("option");
		oSecondOption.value = "none";
		oSecondOption.innerHTML = "---";
		that.selector.appendChild(oSecondOption);
		for(var fMake in that.makes){
			// Loop through makes:
			if(that.makes.hasOwnProperty(fMake)){
				var oOptgroup = document.createElement("optgroup");
				oOptgroup.label = fMake;
				that.selector.appendChild(oOptgroup);
				for(var fYear in that.makes[fMake]){
					// Loop through years:
					if(that.makes[fMake].hasOwnProperty(fYear)){
						var oYear = document.createElement("option");
						oYear.value = 'none';
						oYear.innerHTML = '<strong>' + fYear + '</strong>';
						oOptgroup.appendChild(oYear);
						for(var fModel in that.makes[fMake][fYear]){
							// Loop through models:
							if(that.makes[fMake][fYear].hasOwnProperty(fModel)){
								var oOption = document.createElement("option");
								oOption.value = fYear + '|' + fModel;
								oOption.innerHTML = '&nbsp;&nbsp;&nbsp;&nbsp;' + fModel; // **** you IE.
								oOptgroup.appendChild(oOption);
							}
						}
					}
				}
			}
		}
		if(!that.groupSite){
			var oLastOption = document.createElement("option");
			oLastOption.value = "none";
			oLastOption.innerHTML = "---";
			that.selector.appendChild(oLastOption);
			var oAllModels = document.createElement("option");
			oAllModels.value = 'All';
			oAllModels.innerHTML = "View All Incentives";
			that.selector.appendChild(oAllModels);
		}
		YAHOO.util.Dom.setStyle(that.selector, 'display', that.selectorDisplay);
	}; // this.populateSelector()
	this.sortIncentives = function(pXML, pIndex){
		var oIncentives = pXML.getElementsByTagName("incentive");
		for(var i=0; i<oIncentives.length; i++){
			that.results.push(new that.resultObject(oIncentives[i], pIndex));
		}
	}; // this.sortIncentives()
	this.loadIncentive = function(pIndex){
		var oIndex = (pIndex) ? pIndex : that.currentResultIndex;
		that.currentResultIndex = oIndex;
		var oResult = that.currentResults[oIndex];
		// Viewing:
		that.viewing.innerHTML = that.viewingPrefix + (that.currentResultIndex + 1) + that.viewingBridge + (that.currentResults.length) + that.viewingSuffix;
		YAHOO.util.Dom.setStyle(that.viewing, 'display', that.viewingDisplay);
		// Rebate:
		if(oResult.rebate != false){
			that.rebate.innerHTML = that.rebatePrefix + oResult.rebate + that.rebateSuffix;
			YAHOO.util.Dom.setStyle(that.rebate, 'display', that.rebateDisplay);
		} else {
			YAHOO.util.Dom.setStyle(that.rebate, 'display', 'none');
		}
		// Rates:
		if(oResult.rates.length > 0){
			that.aprLow.innerHTML = that.aprPrefix + oResult.lowestAPR + that.aprSuffix;
			that.rates.innerHTML = '';
			for(var i=0; i<oResult.rates.length; i++){
				that.rates.innerHTML += '<li>' + that.ratesPrefix + oResult.rates[i].apr + that.ratesBridge + oResult.rates[i].term + that.ratesSuffix + '</li>';
			}
			YAHOO.util.Dom.setStyle(that.aprLow, 'display', that.aprDisplay);
			YAHOO.util.Dom.setStyle(that.rates, 'display', that.ratesDisplay);
		} else {
			YAHOO.util.Dom.setStyle([that.aprLow, that.rates], 'display', 'none');
		}
		// Lease:
		if(oResult.lease != false){
			that.lease.innerHTML = '';
			for(var i in oResult.lease){
				if (oResult[i].text && oResult.lease[i].trim) {
				that.lease.innerHTML += '<li>' + that.leasePrefix + oResult.lease[i].text + that.leaseBridge + oResult.lease[i].trim + that.leaseSuffix + '</li>';
				}
			}
			YAHOO.util.Dom.setStyle(that.lease, 'display', that.ratesDisplay);
		} else {
			YAHOO.util.Dom.setStyle(that.lease, 'display', 'none');
		}
		// Image:
		that.image.src = oResult.image;
		that.image.alt = oResult.year + ' ' + oResult.make + ' ' + oResult.model;
		YAHOO.util.Dom.setStyle(that.image, 'display', that.imageDisplay);
		// Disclaimer:
		that.disclaimer.innerHTML = oResult.disclaimer;
		YAHOO.util.Dom.setStyle(that.disclaimer, 'display', that.disclaimerDisplay);
		// Details:
		that.details.href = oResult.url;
		YAHOO.util.Dom.setStyle(that.details, 'display', that.detailsDisplay);
		// Quote:
		that.quote.href = that.quoteURL + '?model=' + oResult.model;
		YAHOO.util.Dom.setStyle(that.quote, 'display', that.quoteDisplay);
	}; // this.loadIncentive()
	this.getIncentive = function(pMake, pModel, pYear){
		// Reset index:
		that.currentResultIndex = 0;
		// Load incentive(s):
		that.currentResults = that.makes[pMake][pYear][pModel];
		that.loadIncentive();
		if(that.currentResults.length < 2){
			YAHOO.util.Dom.setStyle([that.previous, that.next], 'display', 'none');
		} else {
			YAHOO.util.Dom.setStyle(that.previous, 'display', that.previousDisplay);
			YAHOO.util.Dom.setStyle(that.next, 'display', that.nextDisplay);
		}
	}; // this.getIncentive()
	this.handleChange = function(e){
		YAHOO.util.Event.stopPropagation(e);
		YAHOO.util.Event.preventDefault(e);
		var oTarget = YAHOO.util.Event.getTarget(e);
		if(oTarget.nodeName.toUpperCase() == "SELECT"){
			var oOption = oTarget.options[oTarget.selectedIndex];
			switch(oOption.value){
				case 'none':
					oTarget.selectedIndex = 0;
					break;
				case "All":
					window.location.href = "/incentives.html";
					break;
				default:
					var oMake = YAHOO.util.Dom.getAncestorByTagName(oOption, 'optgroup').label;
					var oModel = oOption.value.split('|')[1];
					var oYear = oOption.value.split('|')[0];
					that.getIncentive(oMake, oModel, oYear);
			}
		}
	}; // this.handleChange()
	this.handleClick = function(e){
		YAHOO.util.Event.stopPropagation(e);
		var oTarget = YAHOO.util.Event.getTarget(e);
		switch(oTarget.id){
			case that.previous.id:
				if(that.currentResultIndex > 0 && that.busy == false){
					that.currentResultIndex--;
					that.loadIncentive();
				}
				break;
			case that.next.id:
				if(that.currentResultIndex + 1 < that.currentResults.length && that.busy == false){
					that.currentResultIndex++;
					that.loadIncentive();
				}
				break;
			default:
				return true;
		}
	}; // this.handleClick()
	
	// Init:
	this.init = function(){
		// Setup elements:
		if(this.selector != false){ this.selector = document.getElementById(this.selector); }
		if(this.previous != false){ this.previous = document.getElementById(this.previous); }
		if(this.next != false){ this.next = document.getElementById(this.next); }
		if(this.viewing != false){ this.viewing = document.getElementById(this.viewing); }
		if(this.rebate != false){ this.rebate = document.getElementById(this.rebate); }
		if(this.aprLow != false){ this.aprLow = document.getElementById(this.aprLow); }
		if(this.rates != false){ this.rates = document.getElementById(this.rates); }
		if(this.lease != false){ this.lease = document.getElementById(this.lease); }
		if(this.image != false){ this.image = document.getElementById(this.image); }
		if(this.disclaimer != false){ this.disclaimer = document.getElementById(this.disclaimer); }
		if(this.details != false){ this.details = document.getElementById(this.details); }
		if(this.quote != false){ this.quote = document.getElementById(this.quote); }
		// Run when the requests are done:
		var requestsComplete = function(){
			if(that.results.length > 0){
				// Select:
				that.populateSelector();
				// Attach listeners:
				YAHOO.util.Event.addListener([
					that.previous,
					that.next
				], "click", that.handleClick);
				YAHOO.util.Event.addListener(that.selector, "change", that.handleChange);
			}
		};
		// Make requests:
		this.confid = this.confid.split(',');
		for(var i=0; i<this.confid.length; i++){
			var antiRace = i;
			this.MIL[i] = new MILAPI(this.confid[i]);
			this.MIL[i].getAll(function(pIndex){
				that.sortIncentives(that.MIL[pIndex].XML, pIndex);
				that.completedRequests++;
				if(that.completedRequests == that.confid.length){
					requestsComplete();
				}
			}, antiRace + ''); // this.MIL.getAll()
		}
	}; // this.init()
	
}; // AF.Incentives.Custom()

})();
