
/* Constants */
/*
  6:23:29 PM: define an initialize function that the jsps can call
  6:23:49 PM: function initializeVariable(varName, varValue) { ... }
  6:24:00 PM: the jsps can call that
  6:24:27 PM: so it's obvious, in the jsp, that the variable refers to something defined elsewhere
  6:24:45 PM: and @varValue will be dynamically evaluated server-side
  6:25:22 PM: it's an extra step, and therefore slightly heavy-handed, but at least keeps what's going on a bit clearer
*/
var COMPARE_VIEW_IMG_SEE_ALL; 	// paul says: think of it this way: it's Defined in the js, and initialized in the jsp
var COMPARE_VIEW_IMAGE_SEE_ADV; //            aside from element ids, I tend to frown on referencing things in the .js files that refer to outside "entities"
var TEXT_SELECT_NEW_MODEL;
var TEXT_SEE_ALL_MAKES;
var TEXT_SELECT_AT_LEAST;
var TEXT_SELECT_2_DIFFERENT;
var TEXT_MUST_SELECT_MITS;
var IE_MAX_TRIMS_TEXT_LENGTH = 22;
var IE_MENU_RESIZE_SIZE = "210px";
var IE_MENU_ORIG_SIZE = "138px";
var SHOW_ADVANTAGES_ONLY = "show_advantages_only";
var COMPARE_PRINT_INSTRUCTIONS;

var SHOW = "show";
var HIDE = "hide";

var defaultModelReference = null; //will hold a reference to the model wrapper associated with the current "model-context" of the site
var emptyColumnImage;
var mitsuModelIndexes = null; //will be initialized as an object, and will act as a quasi "linked list"
var globalTrimMess = new Array();

//augment the navigator object with this custom field in order to facilitate IE-specific evasive maneuvers:
navigator["isIE"] = navigator.userAgent.indexOf("MSIE") != -1 ? true : false;

window.undefined = window.undefined;

function $(id) {
	// Convenience/shorthand function
	return document.getElementById(id);
}


function buildModelDropdown(colNumber, modelStruct) {
/*
	Builds a dropdown for car models, for the dropdown in column @colNumber
*/
	var modPrefix = "models";
	var selectRef = $(modPrefix + colNumber);
	
	clearSelector(selectRef);
	
	try {
		for(modelKey in modelStruct) {
			var temp = new Option(modelStruct[modelKey].name, modelKey, false, false);
			selectRef.options[selectRef.options.length] = temp;
		}
	} catch(e) { sendToErrorSink(e, null); }
	
	$(("modelsBlock" + colNumber)).style.display = "block";
}
buildModelDropdown["name"] = "buildModelDropdown";


function hideElement(id) {
	try {
		//$(id).style.visibility = "hidden";
		$(id).style.display = "none";
	} catch(e) { sendToErrorSink(e, null); }
}
hideElement["name"] = "hideElement";


function buildTrimsDropdown(colNumber, refSelect) {
	/*
	Called when a Model is selected from a model dropdown - if overloaded, then called to display preselected competitive set
	@colNumber is the column in which to build the trims dropdown (and the column of the calling model dropdown, for that matter)
	@modelKey is the key employed to locate the model wrapper object whose trims are to be built/displayed
	*/
	//onRaider = aicModels[modelKey].name.indexOf("Raider") != -1 ? true : false;
	//clear the current image in this column, as a matter of course:
	
	try {
		var modelKey = refSelect.options[refSelect.selectedIndex].value;
	} catch(e) { }
	var imgPrefix = "vImg";
	loadImage(null, $(imgPrefix + colNumber));
	
	var trimsPrefix = "trims";
	var selectRef = $(trimsPrefix + colNumber);
	//case of someone selecting the menu header itself ("Select Model")
	if(modelKey == "0") {
		try {
			//clear the trims content, and hide the dropdown:
			selectRef.options.length = 1;
			hideElement(trimsPrefix + colNumber);
			StateMonitor.trimEvent(selectedTrimsMonitor.TYPE_CLEARED, colNumber, null);
			
			return;
		} catch(e) { sendToErrorSink(e, "modelKey == \"0\""); }
	}
	
	//retrieve the trims associated with the model key: either by plugging into aicModels, or using allTrims
	//allTrims refers to the competitive set or to the retrieval of trims for a model under the "all scenario"
	//HACK; BAD!! FIX
	var trimsRef;
	if(arguments.length == 3) {
		if(arguments[2]) {
			trimsRef = compVehicles;
		} else {
			trimsRef = allTrims;
		}
	} else {
		trimsRef = aicModels[modelKey].trims
	}
	try {
		//null out whatever is in there:
		selectRef.options.length = 1;
		//build the new list:
		//this is where the new select is created which causes
		//trim selects to appear to wide in IE ... TODO
		for(var i=0; i < trimsRef.length; i++) {
			var temp = new Option(trimsRef[i].shortName, (modelKey + "|" + trimsRef[i].id), false, false);
			selectRef.options[selectRef.options.length] = temp;
		}
		
		//selectRef.style.visibility = "visible";
		selectRef.style.display = "block";
		
		if( navigator.isIE6 && (aicModels[modelKey].maxTrimNameLength > IE_MAX_TRIMS_TEXT_LENGTH)) {
			selectRef.onmouseover = function() { trimsMouseover(colNumber); };
		} else if(navigator.isIE) {
			selectRef.onmouseover = null; 
		}
		
	}
	catch(e) { sendToErrorSink(e, null); };
}
buildTrimsDropdown["name"] = "buildTrimsDropdown";


function retrieveMitsTrimObject(modelKey, trimId) {
	//get the model object:
	var trimWrapper = null;
	
	var modelRef = aicModels[modelKey];
	try {
		var trimsRef = modelRef.trims;
		var loopLimit = trimsRef.length;
		var temp = null;
		for(var i=0; i < loopLimit; i++) {
			temp = trimsRef[i];
			if(temp.id == trimId) {
				trimWrapper = temp;
				break;
			}
		}
	} catch(e) { sendToErrorSink(e, null); }
	
	return trimWrapper;
}
retrieveMitsTrimObject["name"] = "retrieveMitsTrimObject";


function packageModelAndTrimKeys(compositeValue) {
	return compositeValue.split("|");
}


function loadImage(refTrim, refImg) {
	try {
		var temp = new Image();
		temp.src = refTrim.img;
		refImg.style.backgroundImage = "url(" + temp.src + ")";
		temp = null;
	} catch(e) { 
		if(refImg) {
			refImg.style.backgroundImage = "url(" + emptyColumnImage + ")";
		}
	}
}


function resetSelectset(colNumber) {
	/*
	A function to restore a column to its original (i.e., ready-to-select) state
	@colNumber specifies the column to restore
	*/	

	//hide the block for the trim copy
	$(("trimData" + colNumber)).style.display = "none";
	
	//load the non-image
	var refImg = $("vImg" + colNumber);
	loadImage(null, refImg);
	
	//reset the models select to the zero index
	$(("models" + colNumber)).selectedIndex = 0;
	
	//make visible the select block itself
	$(("modelsBlock" + colNumber)).style.display = "block";	
	$(("models" + colNumber)).style.display = "block";
	$(("selectNewModel" + colNumber)).style.display = "none";
	//zero-out the trims select and make sure its invisible
	//hideElement("trims" + colNumber);
	$(("trims" + colNumber)).style.display = "none";
	
	//record "cleared" state of the column with the StateMonitor
	StateMonitor.trimEvent(selectedTrimsMonitor.TYPE_CLEARED, colNumber, null);
}


function trimSelected(colNumber, refSelect) {
	/* 
	refSelect is a html select element ... 
	
	this function is assigned dynamically to all of the non-competative trims to handle .onchange
	*/
	
	compareButton(true);
	
	try { //TEMP - HACK - BAD! ... example compositeId aicModel4810key|19080
		var compositeId = refSelect.options[refSelect.selectedIndex].value;
	} catch(e) { } //suppress error sink in this case
	
	//get reference to the correct image to fill:
	var refImg = $("vImg" + colNumber);
	
	//case of selecting the trims' column header/label:
	if(compositeId == "0") {
		StateMonitor.trimEvent(selectedTrimsMonitor.TYPE_CLEARED, colNumber, null);
		loadImage(null, refImg);
		return;
	}
	
	try {
		//things to do when a trim is selected:
		//- load the relevant image
		//- hide the select block
		//- display the data block for the trim
		//Code fork: break out the model/trim pair under certain conditions:
		
		if(navigator.isIE) {
			$(("trims" + colNumber)).style.width = IE_MENU_ORIG_SIZE;
		}
		
		var refTrim = null;
		var parentData = "";
		var keys = compositeId.split("|");
		
		StateMonitor.trimEvent(selectedTrimsMonitor.TYPE_SELECTED, colNumber, keys[1], keys[0]);
		
		//TEMP - HACK - BAD!
		if(arguments.length == 3) {
			//new COMPETITIVE trim selected by user
			refTrim = arguments[2];
			globalTrimMess[colNumber] = refTrim;
			//built a more descriptive shortName
			refTrim.shortName = refTrim.year + " " + refTrim.model + " " + refTrim.make + " " + refTrim.shortName;
		}
		else if(StateMonitor.getCompetitiveTabState() == selectedTrimsMonitor.OFF || 
					(StateMonitor.getCompetitiveTabState() == selectedTrimsMonitor.ON && colNumber == '1') ) {
			//case for compare mitsu model columns
			var refParent = aicModels[keys[0]];
			parentData =  refParent.name + '<br />';
			
			refTrim = retrieveMitsTrimObject(keys[0], keys[1]);
			
			var refBlock = $("modelsBlock" + colNumber);
			refBlock.style.display = "none";
		}
		else if(colNumber != '1') {
			// loading preselected competitors ...
			// not when a trim is selected for them
			refTrim = retrievePreselectTrim(keys[1]);
		}
		loadImage(refTrim, refImg);
		
		var refTrimData = $("trimData" + colNumber);
		
		//grab the parent wrapper object:	
		var data = parentData + refTrim.shortName;
		
//		alert("p: " + parentData + "\nd: " + data);
		refTrimData.innerHTML = data;
		refTrimData.style.display = "block";
		
		$(("trims" + colNumber)).style.display = "none";
		
		$(("selectNewModel" + colNumber)).style.display = "block";
	} catch(e) {sendToErrorSink(e, null);}
	
	// hack to reload competitive default vehicles from aic 
	// when user selects new mitsu trim
	if(StateMonitor.getCompetitiveTabState() == "on" && colNumber == 1 && StateMonitor.trimSetByRobot == false){
		// triggered by user interaction
		prepareCompetitiveScreen();
		StateMonitor.trimSetByRobot = false;
 	}
	else {
		StateMonitor.trimSetByRobot = false;
	}
	
}
trimSelected["name"] = "trimSelected";


function retrievePreselectTrim(id) {
	var trim = null;
	for(trimKey in compVehicles) {
		if(compVehicles[trimKey].id == id) {
			trim = compVehicles[trimKey];
			break;
		}
	}
	
	return trim;
}


function sendToErrorSink(exception, msg) {
	var throwerName;
	
	//make sure thrower has a name:
	try {
		throwerName = sendToErrorSink.caller.name;
	} catch(e) {
		throwerName = "~Anonymous/Unknown Function~";
	}
	
	var message = msg == null ? "" : msg;
	
	//comment/uncomment to disable/enable error feedback for debugging:
	//alert("*Function {" + throwerName + "}* !!" + message + "!! " +  exception.toString());
}


function test () {
	/*
	Invoke test as a "unit test" of sorts for the error sink functionality
	*/
	try {
		var x = document.doThis();
	} catch(e) {
		sendToErrorSink(e, "testing, testing");
	}
}
test["name"] = "test";


function trimsMouseover(strCol) {
	try {
		$(("trims" + strCol)).style.width = IE_MENU_RESIZE_SIZE;
	} catch(e) { sendToErrorSink(e, null); }
}
trimsMouseover["name"] = "trimsMouseover";


function prepareCompetitiveScreen() {
	/*
	//determine the trim for this section, if possible
	//jjg: this case never gets hit, determineDefaultMitsuTrim is called in the MITS case of compareEntrypoint.js
	if(defaultModelReference == null) { //when is this case hit?
		alert("prepareCompetitiveScreen had no defaultModelReference");
		determineDefaultMitsuTrim(); 
		setDefaultTrimColumn();
	}
	*/
	try {
			var query = "trim=" + StateMonitor.columnPointers[0].trimID; // was defaultModelReference.trims[0].id
			var strCallback = "preselectCompetitorsCallback(http_request[i].responseText)";
			sendToAjaxPipeline(ACTION_GET_COMP_TO_TRIM, query, strCallback);
	}
	catch(e) {
			StateMonitor.setIsAjaxInProgress(false);
			hideAsyncMsg();
			sendToErrorSink(e, null);
	}
	//for as many columns as there are
}
prepareCompetitiveScreen["name"] = "prepareCompetitiveScreen";


function preselectCompetitorsCallback(ajaxResponse) {
	ajaxCleanup();
	var success = ajaxTransportEval(ajaxResponse);
	if(success) {
		//need to build trims dropdowns for columns 2 - 4
		for(var i = 2; i <= 4; i++) {
			hideModelSelector(i);
			hideMakesSelector(i);
			buildTrimsDropdown(i, null, true);
			$(("trims" + i)).selectedIndex = i - 1;
			trimSelected(i, $(("trims" + i)));
			$(("selectNewLink" + i)).innerHTML = TEXT_SEE_ALL_MAKES;
		}
	
	}
}
preselectCompetitorsCallback["name"] = "preselectCompetitorsCallback";


function hideModelSelector(strColumn) {
	$("modelsBlock" + strColumn).style.display = "none";
}


function hideMakesSelector(strColumn) {
	$("makesBlock" + strColumn).style.display = "none";
}


function ajaxTransportEval(jsonTransport) {
	/*
	A centralized mechanism to evaluate all ajax responses
	*/
	var validEval = true;
	try {
		eval(jsonTransport);
	} catch(e) {
		validEval = false;
		//if overloaded, invoke the errorhanding function:
		if(arguments.length == 2) {
			try {
				arguments[1]();
			} catch(ex) { sendToErrorSink(ex, "Could Not invoke \"" + arguments[1] + "\""); }
		}
		sendToErrorSink(e, "Evaluation error with " + ajaxTransportEval.caller.name);
	}
	return validEval;
}
ajaxTransportEval["name"] = "ajaxTransportEval";


function selectNewGateway(strColumn) {
	checkAndHideResults();
	if( StateMonitor.getCompetitiveTabState() == selectedTrimsMonitor.OFF || 
					(StateMonitor.getCompetitiveTabState() == selectedTrimsMonitor.ON && strColumn == '1') ) 
	{
		//for strColumn 1 on either compare page
		resetSelectset(strColumn);
	} else {
		$(("makes" + strColumn)).selectedIndex = "0";
		$(("makes" + strColumn)).style.display = "block";
		$(("models" + strColumn)).style.display = "block";
		manageMakesRetrieval(strColumn);
	}
}


function manageMakesRetrieval(strColumn) {
	if(allMakes == null) {
		var strCallback = 'makesCallback("' + strColumn + '", http_request[i].responseText)';
		sendToAjaxPipeline(ACTION_GET_ALL_MAKES, null, strCallback);
	} else {
		coordinateMakesBuild(strColumn);
	}
}


function makesCallback(strColumn, ajaxResponse) {
	ajaxCleanup();
	var success = ajaxTransportEval(ajaxResponse);
	if(success) {
		coordinateMakesBuild(strColumn);
	}
}


function coordinateMakesBuild(strColumn) {
	/* This is broken out into its own little function so that it can be called directly (once makes have been retrieved
	   for one column; that way we don't have to keep retrieving makes */
	resetSelectset(strColumn);
	$(("modelsBlock" + strColumn)).style.display = "none";
	populateMakes(strColumn);
}


function populateMakes(strColumn) {
	var id = "makes" + strColumn;
	
	var refMakeSelect = $(id);
	try {
		for(var i=0; i < allMakes.length; i++) {
			var temp = new Option(allMakes[i].name, allMakes[i].name, false, false);
			refMakeSelect.options[refMakeSelect.options.length] = temp;
		}
		$(("makesBlock" + strColumn)).style.display = "block";
	} catch(e) { sendToErrorSink(e);}
}
populateMakes["name"] = "populateMakes";


function clearSelector(refSelect) {
	refSelect.options.length = 1;
}


function makeSelected(refSelect, strColumn) {
	var selectVal = refSelect.options[refSelect.selectedIndex].value;
	if(selectVal != "0") {
		manageModelsRetrieval(selectVal, strColumn);
	}
}


function sendToAjaxPipeline(serverEndpt, querystring, callback) {
	try {
		if(serverEndpt == ACTION_GET_COMPARISON){
			showAsyncMsg();
		}		
		else{
			showAsyncMsgMinimal();
		}
		StateMonitor.setIsAjaxInProgress(true);
		makeRequest(serverEndpt, querystring, callback);
	}
	catch(e) {
		StateMonitor.setIsAjaxInProgress(false);
		hideAsyncMsg();
		sendToErrorSink(e, "problemo invoking " + serverEndpt);
	}
}
sendToAjaxPipeline["name"] = "sendToAjaxPipeline";


function manageTrimsForModelsRetrieval(strColumn, refSelect) {
	//attempt to pull the id for the selected item
	var selectVal = refSelect.options[refSelect.selectedIndex].value;
	if(selectVal != "0") {
		try {
			var modelID = allModels[refSelect.options[refSelect.selectedIndex].value].id;
			var query = "model=" + modelID;
			var strCallback = "trimsForModelsCallback('" + strColumn + "', http_request[i].responseText)";
			sendToAjaxPipeline(ACTION_GET_TRIMS_FOR_MODEL, query, strCallback);
		} catch(e) {
			sendToErrorSink(e, null);
		}
	}
}
manageTrimsForModelsRetrieval["name"] = "manageTrimsForModelsRetrieval";


function trimsForModelsCallback(strColumn, ajaxResponse) {
	ajaxCleanup();
	var success = ajaxTransportEval(ajaxResponse);
	if(success) {
		buildTrimsDropdown(strColumn, null, false);
		//attach new event handler for this case:
		$(("trims" + strColumn)).onchange = function() { allMakesTrimOnSelect(strColumn, this); };
		//invisible text:
		$(("selectNewLink" + strColumn)).innerHTML = "";
	}
}


function allMakesTrimOnSelect(strColumn, refSelect) {
	// aka competitive trim got selected
	var selectVal = refSelect.options[refSelect.selectedIndex].value;
	if(selectVal != "0") {
		var refTrim = retrieveAllMakesTrim(selectVal);
		trimSelected(strColumn, refSelect, refTrim);
	}
	
	$(("makes" + strColumn)).style.display = "none";
	$(("models" + strColumn)).style.display = "none";
	$(("selectNewLink" + strColumn)).innerHTML = TEXT_SEE_ALL_MAKES;
}


function retrieveAllMakesTrim(compositeKey) {
/*
 retrieves a trim wrapper object from the allTrims array
*/
	var refTrim = null;
	var splitted = compositeKey.split("|");
	if(splitted) {
		var trimID = splitted[1];
		for(var i=0; i < allTrims.length; i++) {
			if(allTrims[i].id == trimID) {
				refTrim = allTrims[i];
				break;
			}
		}
	}
	
	return refTrim;
}


function ajaxCleanup() {
	// tasks that need to be run once an ajax call has returned, common to many ajax calls
	hideAsyncMsg();
	StateMonitor.setIsAjaxInProgress(false);
}


function manageModelsRetrieval(makeName, strColumn) {
	var query = "make=" + makeName;
	var strCallback = "modelsForMakesCallback('" + strColumn + "', http_request[i].responseText)";
	sendToAjaxPipeline(ACTION_GET_MODELS_FOR_MAKE, query, strCallback);
	
}

function modelsForMakesCallback(strColumn, ajaxResponse) {
	ajaxCleanup();
	var success = ajaxTransportEval(ajaxResponse);
	if(success) {
		buildModelDropdown(strColumn, allModels);
		//make sure that the trims dropdown associated with this column is hidden, and that the image is cleared in this column:
		//$(("trims" + strColumn)).style.visibility = "hidden";
		$(("trims" + strColumn)).style.display = "none";
		loadImage(null, $(("vImg" + strColumn)));
		//attach modified event handler - in this case we need to set up an AJAX "trigger":
		$(("models" + strColumn)).onchange = function() { manageTrimsForModelsRetrieval(strColumn, this); };
	}
}


function setDefaultTrimColumn() {
	/*
	ONLY when page loads or user switches tabs
	doesnt execute when user selects a new trim for the default column (1)
	*/
	
	StateMonitor.trimSetByRobot = true;
	//we have the default model [defaultModelReference]
	try {
		//set the selectedIndex for column 1
		$(("models1")).selectedIndex = mitsuModelIndexes[defaultModelReference.name];
		//populate the trims:
		buildTrimsDropdown('1', $("models1"));
		//set the first trim to selected and invoke event-handler:
		var refTrims = $(("trims1"));
		refTrims.selectedIndex = 1;
		trimSelected("1", refTrims);
	} catch(e) { sendToErrorSink(e, null); }	
}
setDefaultTrimColumn["name"] = "setDefaultTrimColumn";


function constructAicKey(id) {
		var PREFIX = "aicModel";
		var SUFFIX = "key";
		
		return PREFIX + id + SUFFIX;
	}


function hideMakesDropdowns() {
	//by definition, those will only exist in columns 2 -4:
	for(var i=2; i <= 4; i++) {
		try {
			$(("makesBlock" + i)).style.display = "none";
		} catch(e) { sendToErrorSink(e, "problem with column " + i); }
	}
}
hideMakesDropdowns["name"] = "hideMakesDropdowns";


function setMitsModelOnChangeHandlers() {
	/*
	4:00:36 PM: it's a fairly abstract use of javascript, but shows the power of the language
	4:00:43 PM: using function references, closures, etc
	*/
	//columns 2 -4:
	for(var i=2; i <= 4; i++) {
		$(("models" + i)).onchange = closureFacilitator(i, buildTrimsDropdown);
		$(("trims" + i)).onchange = closureFacilitator(i, trimSelected);
		$(("selectNewLink" + i)).innerHTML = TEXT_SELECT_NEW_MODEL;
	}
}


function closureFacilitator(val, refFunction) {
	function closured() {
		refFunction(val, this); 
	}
	
	return closured;
}


function buildMenus() {
	buildModelDropdown('1', aicModels);
	buildModelDropdown('2', aicModels);
	buildModelDropdown('3', aicModels);
	buildModelDropdown('4', aicModels);
}
buildMenus.name = "buildMenus"; // same as buildMenus.name = "buildMenus";


//addToOnload(buildMenus);
/* compare */
function initiateCompare(obj) {
	if(StateMonitor.numberSelected < 2) {
		alert(TEXT_SELECT_AT_LEAST);//TBD?
	} 
	else if(StateMonitor.getCompetitiveTabState() == "on" && !StateMonitor.isColumnSelected(1)) {
		alert(TEXT_MUST_SELECT_MITS);
	} 
	else {
		//call to StateMonitor
		var normalized = StateMonitor.getNormalizedSelections();
		
		if(normalized.length < 2) {
			alert(TEXT_SELECT_2_DIFFERENT);
		} 
		else {
			//build up the query string:
			try {
				var query = "compTrims=";
				for(var i = 0; i < normalized.length; i++) {
					query += (i == (normalized.length - 1)) ? normalized[i] : normalized[i] + "|";
				}
			query += "&hippo=" + new Date().getTime().toString();
			
			var strCallback = "comparisonCallback(http_request[i].responseText)";
			sendToAjaxPipeline(ACTION_GET_COMPARISON, query, strCallback);
			} catch(e) { sendToErrorSink(e); }
		}
	}
}
initiateCompare["name"] = "initiateCompare";

function showSpecs() {
	/*
	aka toggle see all / see advantages for the comparison chart
	
	called only when user clicks "see advantages" "see all features" toggle button
	NOT a single point of entry for the build functions
	*/
	
	//get the current flag to determine whether we show all specs, or advantages only :
	var advantagesOnly = $("compareViewToggle")[SHOW_ADVANTAGES_ONLY];	
	
	//get results of the build, passing in the flag:
	var builderStruct;
	builderStruct = competitiveComparisonBuilder(advantagesOnly);
	//toggle the image (which will also toggle the advantages flag)
	setCompareViewImage();
	
	displayEncapsulation(builderStruct["markup"], builderStruct["resize"]);
	toggleCompareViewBoolean();
}


function setCompareViewImage() {
	//if only advantages are showing, ask the user if they'd like to SEE_ALL features (and vice versa)
	var src = $("compareViewToggle")[SHOW_ADVANTAGES_ONLY] ? COMPARE_VIEW_IMG_SEE_ALL : COMPARE_VIEW_IMAGE_SEE_ADV;
	try {
		$("compareViewToggleImg").src = src;
	} catch(e) { sendToErrorSink(e, null); }
}
setCompareViewImage["name"] = "setCompareViewImage";


function toggleCompareViewBoolean() {
	var advantagesOnly = $("compareViewToggle")[SHOW_ADVANTAGES_ONLY];
	$("compareViewToggle")[SHOW_ADVANTAGES_ONLY] = !advantagesOnly;
	var advantagesOnly = $("compareViewToggle")[SHOW_ADVANTAGES_ONLY];	
}


function comparisonCallback(ajaxResponse) {
	ajaxCleanup();
	var success = ajaxTransportEval(ajaxResponse, function() { displayEncapsulation(COMPARE_ERROR_MARKUP, false);});
	if(success) {
		var builderStruct;
		if(StateMonitor.getCompetitiveTabState() == "off") {
			builderStruct = comparisonBuilder();
		} else {
			builderStruct = competitiveComparisonBuilder(true);
		}
		displayEncapsulation(builderStruct["markup"], builderStruct["resize"]);
		//todo: make a better check here!
		//what if we have success but the data is zero or something else nasty like that
		StateMonitor.setHaveCompareData(true);
	}
}


function retrieveColumnMarkedTrims(length) {
	/*
	inefficient: consider an alternative

	3:33:43 PM: there's a data structure returned called compareModels which my code should have been leveraging more
	3:33:55 PM: you might plug into that
	3:51:44 PM: the issue is associating those array items, which are ordinal (0, 1, 2, etc) with the de facto columns that they appear within
	3:51:58 PM: I do have a function which is doing that already so you can probably modify it to store the image info
	3:52:23 PM: and then can bypass getTrimPacket altogether

	4:03:20 PM: check out "compareModels"
	4:04:02 PM: and look at function retrieveColumnMarkedTrims
	4:18:33 PM: yeah, you should be able to doctor that one
	4:18:47 PM: actually, the image may already be set for the trim objects
	4:18:49 PM: check it out
	alert(compareModels[i].img);
	*/
	
	var trims = new Array(length);
	
	/* 
	compareModels=[
	new trimWrapper("19024", "GS", "http://comp.autosite.com/configurator/photos/127x64jpg/ECLIPS12.jpg", "2007", null, "null", null),
	new trimWrapper("19094", "V6 Premium Convertible", "http://comp.autosite.com/configurator/photos/148x74jpg/MUSTAN24.jpg", "2007", null, "null", null)];	
	*/
	for(var i = 0; i < compareModels.length; i++) {
		var trimRef = compareModels[i];
		trimRef.columnNumber = StateMonitor.getColumnforID(trimRef.id);
		trims[trimRef.columnNumber] = trimRef;
	}
	
	return trims;
}


function buildCompareHeaderRow(numColumns, header, arrTrims) {
	var css = "style=\"color:#cccccc; background-color:#000000; font-size:11px; font-weight:bold;\"";
	var markup = "<tr><td " + css + ">" + header + "</td>";
	
	//only if we're on the competitive page we need an extra data cell for the checkmark:
	if( StateMonitor.getCompetitiveTabState() == "on" ){
		markup += "<td " + css + ">&nbsp;</td>"
	}
	
	for(var i=1; i < arrTrims.length; i++) {
		if(arrTrims[i] != undefined) {
			// markup += "<td " + css + ">" + arrTrims[i].shortName +  "</td>"; 
			markup += "<td " + css + ">&nbsp;</td>"; 
		} else {
			markup += "<td " + css + ">" + "&nbsp;</td>";
		}
	}

	markup += "</tr>"
	
	return markup;
}


function competitiveComparisonBuilder(advantagesOnly) {
	/*
	called every time user hits compare or toggles see advantages / all features
	*/
	var struct = null;
	//firstly, loop through the short list of trims which are being compared; determine and set the column:
	var comparedTrims = new Array();
	var compareMarkup;
	var resize = true;
	var oddRow = false;
	var styles = "#cccccc";
	var advantageIcon = "/MMNA/images/compare/icon_dark.gif";
	if(compareData.length > 0) {
		var numberOfColumns = 5;
		var comparedTrims = retrieveColumnMarkedTrims(numberOfColumns);
		// set these individually instead, and earlier
		// globalTrimMess = comparedTrims;
		// when i moved this up here it broke the see all/advantages toggle:
		// StateMonitor.setHaveCompareData(true);
		compareMarkup = "<table id=\"compareDataTable\" width=\"958\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">";
		compareMarkup += "<tr> <td class=\"firstRow\" width=\"192\">&nbsp;</td> <td class=\"firstRow\" width=\"13\">&nbsp;</td> <td class=\"firstRow\" width=\"180\">&nbsp;</td> <td class=\"firstRow\" width=\"175\">&nbsp;</td> <td class=\"firstRow\" width=\"175\">&nbsp;</td> <td class=\"firstRow\" width=\"237\">&nbsp;</td> </tr>";
		
		for(var i = 0; i < compareData.length; i++) { //number of categories
			var refCompare = compareData[i];
			
			if(advantagesOnly && !refCompare.hasMitsAdvantage) { continue; }
				//get the compare's id, and retrieve its display column
				//get the sectional header:				
				//compareMarkup += "<tr><td style=\"color:#cccccc; background-color:#000000; font-size:11px; font-weight:bold;\" colspan=\"" + numberOfColumns + "\">" + refCompare.header + "</td></tr>";
				compareMarkup += buildCompareHeaderRow(numberOfColumns, refCompare.header, comparedTrims);
				
				//now for the details - discrete sections and values - for this section:	
//				var advantage = ["/MMNA/images/compare/icon_light.gif", "/MMNA/images/compare/icon_dark.gif"]
				for(var j = 0; j < refCompare.details.length; j++) { 
					
					//subheads within categories
					var refDetail = refCompare.details[j];
					
					if(advantagesOnly && refDetail.getAdvantageFlag() != true) { continue; }
					
					//toggle the color of the rows
					if(oddRow == true){
						styles = "#cccccc";
						oddRow = false;
						advantageIcon = "/MMNA/images/compare/mitsu_aic_chkmrk_light.gif";
					}
					else{
						styles = "#aaaaaa";
						oddRow = true;
						advantageIcon = "/MMNA/images/compare/mitsu_aic_chkmrk_dark.gif";
					}
					
					//advantageFlag
					compareMarkup += "<tr><td style=\"background-color:" + styles + "; font-size:9px; font-weight:bold;\">";
					
					compareMarkup += refDetail.label;
					
					//compareMarkup += refDetail.getAdvantageFlag() == true ? "<img style="float: right;" src=\"" + advantageIcon + "\">" : " ";
										
					compareMarkup += "</td>";

					//is there a mitsu advantage here?
					compareMarkup += "<td style=\"background-color:" + styles + ";\">";
					compareMarkup += refDetail.getAdvantageFlag() == true ? "<img border='0' src=\"" + advantageIcon + "\">" : "&nbsp;";
					compareMarkup += "</td>";
										
					//populate values in columns:
					var lastWritten = 0;
					for(var jj = 0; jj < numberOfColumns - 1; jj++) { //individual data
						if (StateMonitor.isColumnSelected(jj + 1)) {
							//get the value to display:
							var val = refDetail.values[lastWritten];              
							lastWritten++;
							
							compareMarkup += "<td style=\"background-color:" + styles + "; font-size:9px;\">" + val + "</td>";
						} else {
							compareMarkup += "<td style=\"background-color:" + styles + ";\">&nbsp;</td>";
						}
					}
					//compareMarkup += '</div><br/><br/>';
					compareMarkup += "</tr>";
				}
				
		}//end outer loop                         
		compareMarkup += "</table>";
		
	}
	else {
		StateMonitor.setHaveCompareData(false);
		compareMarkup = COMPARE_ERROR_MARKUP;
		resize = false;
	}
	
	struct = new Object();
	struct["markup"] = compareMarkup;
	struct["resize"] = resize;
	
	return struct;
}

function comparisonBuilder() {
	var struct = null;
	//firstly, loop through the short list of trims which are being compared; determine and set the column:
	var comparedTrims = new Array();
	var compareMarkup;
	var resize = true;
	if(compareData.length > 0) {
		StateMonitor.setHaveCompareData(true);
		var numberOfColumns = 5;
		var comparedTrims = retrieveColumnMarkedTrims(numberOfColumns);
						
		compareMarkup = "<table id=\"compareDataTable\" width=\"958\" cellpadding=\"0\" cellspacing=\"0\">";
		compareMarkup += "<tr><td class=\"firstRow\" width=\"192\">&nbsp;</td><td class=\"firstRow\" width=\"180\">&nbsp;</td><td class=\"firstRow\" width=\"175\">&nbsp;</td><td class=\"firstRow\" width=\"175\">&nbsp;</td><td class=\"firstRow\" width=\"237\">&nbsp;</td></tr>";
		
		for(var i = 0; i < compareData.length; i++) { //number of categories
			var refCompare = compareData[i];
			//get the compare's id, and retrieve its display column
			//get the sectional header:
			
			//compareMarkup += "<tr><td style=\"color:#cccccc; background-color:#000000; font-size:11px; font-weight:bold;\" colspan=\"" + numberOfColumns + "\">" + refCompare.header + "</td></tr>";

			compareMarkup += buildCompareHeaderRow(numberOfColumns, refCompare.header, comparedTrims);

			//now for the details - discrete sections and values - for this section:
			var left;
			var refCoordinates;
			var styles = ["#cccccc", "#aaaaaa"];
			
			for(var j = 0; j < refCompare.details.length; j++) { //subheads within categories
				//get ref to detail object
				
				var refDetail = refCompare.details[j];
				
				compareMarkup += "<tr><td style=\"background-color:" + styles[j%2] + "; font-size:9px; font-weight:bold;\">" + refDetail.label + "</td>";;
				
				//populate values in columns:
				var lastWritten = 0;
				for(var jj = 0; jj < numberOfColumns - 1; jj++) { //individual data
					if (StateMonitor.isColumnSelected(jj + 1)) {
						//get the value to display:
						var val = refDetail.values[lastWritten];              
						lastWritten++;
						compareMarkup += "<td style=\"background-color:" + styles[j%2] + "; font-size:9px;\">" + val + "</td>";
					} else {
						compareMarkup += "<td style=\"background-color:" + styles[j%2] + ";\">&nbsp;</td>";
					}
				}
				//compareMarkup += '</div><br/><br/>';
				
				compareMarkup += "</tr>";
			}
		}
		compareMarkup += "</table>";
		
	}
	else {
		StateMonitor.setHaveCompareData(false);
		compareMarkup = COMPARE_ERROR_MARKUP;
		resize = false;
	}
	
	struct = new Object();
	struct["markup"] = compareMarkup;
	struct["resize"] = resize;
	
	return struct;
	
}


function displayEncapsulation(displayMarkup, resize) {
	var refDataPane = $("compareDisplayPane");
	refDataPane.innerHTML = displayMarkup;
	
	if(resize) {
		//4 ancestorsBack should be the same size as element with id compareDisplayPane. last param is extra padding added to the height
		resizeAncestor("compareDisplayPane", 4, (refDataPane.offsetTop + refDataPane.parentNode.offsetTop + 305));
	}
	refDataPane.style.visibility = "visible";
	var legalHeight = refDataPane.offsetHeight + 100;
	$("legalCopy").style.top = legalHeight + "px";
	hideAsyncMsg();
	
	StateMonitor.setIsAjaxInProgress(false);
}


function hideCompareResults() {
	StateMonitor.setHaveCompareData(false);
	try {
	//hide the compare results pane:
	var refResults = $("compareDisplayPane");
	refResults.innerHTML = "";
	refResults.style.visibility = "hidden";
	} catch(e) { }
}
hideCompareResults["name"] = "hideCompareResults";

function resetSystem() {
	//clear any selected trims
	
	for(var i = 0; i < StateMonitor.getNumberOfColumns(); i++) {
		resetSelect(i + 1);
	}
	
	StateMonitor.numberSelected = 0;
}

function checkAndHideResults() {
	StateMonitor.setHaveCompareData(false);
	var refDataPane = $("compareDisplayPane");
	if(refDataPane.style.visibility == "visible") {
		refDataPane.innerHTML = "";
		refDataPane.style.visibility = "hidden";
	}
	
}


function redrawFlash() {
	/*
	needs to respond to mitsubishi_mainnav.swf being all the way opened
	nav_event defined in jsp\layouts\intra_vehicle_nav.jsp
	*/
	
	nav_event("close");
	transparent = "false";
	isOpen = false; 
	
	/*
	the Flash object is just a way of embedding the flash just a wrapper to write it into the page 
	it gets around IE security restrictions you can't directly embed flash anymore, w/o prompting a security warning
	*/
	var fo = new FlashObject("/MMNA/swf/mitsubishi_vehicleNav.swf?xmlpath=" + swfXml + "&isOpen="+isOpen, "vehicleNav", "203", "360", "6", "black");
	fo.addParam("scale", "noscale");
	fo.addParam("menu", "false");
	fo.addParam("wmode", "transparent");
	fo.addVariable("isTransparent", transparent);
	fo.addVariable("currentPage", window.location.pathname);
	fo.write("individual_vehicle_nav");
	fo = null;
	delete(fo);
	nav_event(NAV_EVENT_CLOSE);
}


function showCompare() {
	/*
	callback for selectedTrimsMonitor.COMPARE_DATA, assigned in compare.jsp
	
	runs just once per compare
	*/
	try {
		if(StateMonitor.getCompetitiveTabState() == "on") {
			$("advantageKey").style.visibility = "visible"; // turn the checkmarks on
			
			//use object augmentation to define a custom field on the toggle image:
			$("compareViewToggle")[SHOW_ADVANTAGES_ONLY] = true; //give the div a boolean
			setCompareViewImage();
			toggleCompareViewBoolean();
			$("compareViewToggle").style.display = "block";
		}
		$("printCompare").style.visibility = "visible";
		compareButton(false);
	} catch(e) { sendToErrorSink(e, null); }
}
showCompare["name"] = "showCompare";


function hideCompare() {
	try {
		compareButton(true);
		$("advantageKey").style.visibility = "hidden";
		$("compareViewToggle").style.display = "none";
		$("printCompare").style.visibility = "hidden";
	}
	catch(e) { sendToErrorSink(e, null); }
}
hideCompare["name"] = "hideCompare";


function compareButton(toggler){
	/*
	true toggler makes it bright
	false toggler makes it dim
	*/
	if(toggler){
		$("compareButtonDim").style.display = "none";
		$("compareButtonBright").style.display = "inline";
	}
	else{
		$("compareButtonDim").style.display = "inline";
		$("compareButtonBright").style.display = "none";
	}
}
compareButton["name"] = "compareButton";


function determineDefaultMitsuTrim() {
	if(defaultModelReference == null) {
		var key = pullKeyFromUrl();
		if(key != null) {
			MSG_AIC_VEH_REPLACE = key;
			var refModel = retrieveModelwithName(key);
			//set the global reference to this vehicle, for future use:
			defaultModelReference = refModel;
		}
	}
}


function pullKeyFromUrl() {
	var key = null;
	
	var regX =  new RegExp(/jsp\/([\w]+\/[\d]{2})\//);              
	var path = window.location.pathname;
	var result = path.match(regX);
	
	if(result != null) {
		key = urlSignature[result[1]];
	}
	
	return key;
}


function retrieveModelwithName(name) {
	var model = null;
	
	if(aicModels != null) {
		for(key in aicModels) {
			model = aicModels[key];
			//alert(model.name);
			if(model.name == name) {
				break;
			}
			else {
				model = null;
			}
		}
	}
	
	return model;
}


function showAsyncMsg(){
	$("asyncMsg").style.visibility = 'visible';
}
showAsyncMsg["name"] = "showAsyncMsg";


function showAsyncMsgMinimal(){
	$("asyncMsgMinimal").style.visibility = 'visible';
}
showAsyncMsgMinimal["name"] = "showAsyncMsgMinimal";


function hideAsyncMsg(){
	$("asyncMsg").style.visibility = 'hidden';
	$("asyncMsgMinimal").style.visibility = 'hidden';
}
hideAsyncMsg["name"] = "hideAsyncMsg";


function killAjax() {
	//NB: 'whatFunction' is defined in Ajax.js
	if(whatFunction.length > 0) {
		try {
			whatFunction[whatFunction.length - 1] = "";
			$("asyncMsg").style.visibility = "hidden";
		} catch(e) { sendToErrorSink(e, null); }
	}
	StateMonitor.setIsAjaxInProgress(false);
}
killAjax["name"] = "killAjax";


function printComparison() {
	var openDirs = window.open("about:blank", "Comparison", "", "");
	
    //var refDataPane = $("compareDisplayPane");
	var markup = "";
	markup += "<html>";
	markup += "<head>";
	markup += "<link href=\"/MMNA/css/styles.css\" rel=\"stylesheet\" type=\"text/css\">";
	markup += "<style>body{background-image: none; background-color: #CCCCCC; font-color: black;}</style>"
	markup += "</head>";
	markup += "<body style='text-align: center;'>";	
	markup += "<div style='width: 959; margin: 0 auto; text-align: left;'>";
	
	markup += "<table width=\"959\" border=\"0\" cellpadding=\"4\" cellspacing=\"0\">";
	markup += "<tr><td width=\"192\"></td><td width=\"180\">&nbsp;</td><td width=\"175\">&nbsp;</td><td width=\"175\">&nbsp;</td><td width=\"237\">&nbsp;</td></tr>";
	markup += "<tr valign='top'>";
	var numberOfColumns = 4;
	markup += '<td><p><strong>';
	markup += COMPARE_PRINT_INSTRUCTIONS;
	markup += '</strong></p>';
	
	//if comming from compare tab, provide a legend for the checkmark
	if( StateMonitor.getCompetitiveTabState() == "on" ){
		markup += "<img src='/MMNA/images/compare/mitsu_aic_chkmrk_light.gif'/>&nbsp;The Mitsubishi Competitive Advantage"
	}
	
	markup += "</td>";
	
	// row with vehicle images and names
	for(var i = 0; i < numberOfColumns; i++) { //individual data
		if (StateMonitor.isColumnSelected(i + 1)) {
			//get the column wrapper object
			var wrap = StateMonitor.getDataWrapperForColumn(i + 1);
			//alert("wrap.trimID: " + wrap.trimID + "\nwrap.parentID: " + wrap.parentID)
			var shortTrim = getTrimPacket(wrap.trimID, wrap.parentID);
			
			/* globalTrimMess hack, because getTrimPacket will return a null shortTrimWrap
			if the user has selected a trim (rather than using the default comparison set)
			only on the COMPETITIVE page
			
			stuffing a short trim to make adds to the markup uniform
			*/
			if(shortTrim == null){
				// broke: globalTrimMess is missing model and make
				//var vehicleDescription = globalTrimMess[(i + 1)].year + " " + globalTrimMess[(i + 1)].model + " " + globalTrimMess[(i + 1)].make + " " + globalTrimMess[(i + 1)].shortName;
				shortTrim = new shortHandTrimWrapper(globalTrimMess[(i + 1)].id, globalTrimMess[(i + 1)].shortName, globalTrimMess[(i + 1)].img);
			}
 			
			var objImg = new Image();
			try {
				//alert(shortTrim.img);
				objImg.src = shortTrim.img;
			var toDisplay = "<img border='2' src=\"" + objImg.src + "\"/><br>" + "<div style='text-transform: uppercase; width: 128px;'>" + shortTrim.text + "</div>";
				markup += "<td>" + toDisplay + "</td>";
			} catch(e) { sendToErrorSink(e, "short trim assignments"); }
		} else {
			markup += "<td>&nbsp;</td>";
		}
	}
	markup += "</tr>";
	markup += "</table>";
	
	var refDataPane = $("compareDisplayPane"); // the compare table
	markup += refDataPane.innerHTML;
	
	var legal = "<div style=\"padding: 10px 0 0 0;\">" + $("legalCopy").innerHTML + "</div>";
	markup += legal;
	
	markup += "<script>setTimeout('window.print()', 3000);</script>";
	
	markup += "</div>";
	markup += "</body>";
	markup += "</html>";
	
	openDirs.document.write(markup);
	openDirs.document.close();

}
printComparison["name"] = "printComparison";


function getTrimPacket(trimID, key) {
	var shortTrimWrap = null;
	
	if(key == "undefined") {
		//we have no model "parent" in this case - when we get the short set of trims from AIC, based on a mitsu trim
		trimWrap = grabCompetitorsTrimWrapper(trimID);
		
		if(trimWrap) {
			shortTrimWrap = new shortHandTrimWrapper(trimID, trimWrap.shortName, trimWrap.img);
		}
	}
	else {
		try {
			//this is the case of the mitsu trims
			var modelWrap = aicModels[key];
			var trimRef = retrieveTrimFromModel(modelWrap, trimID);
			
			if(trimRef != null) {
				var text = modelWrap.name + "<br>" + trimRef.shortName;
				shortTrimWrap = new shortHandTrimWrapper(trimRef.id, text, trimRef.img);
			}
			
			
		} catch(e) { sendToErrorSink(e, null); }
	}
	
	//still null?
	if(shortTrimWrap == null) {
		//alert("key: " + key + "evaled: " + eval(key));
		try {
			//this is the case of the get all competitor's models fragment call:
			var mdl = eval(key);
			if(mdl) {
				trimRef = retrieveTrimFromModel(mdl, trimID);
					
				if(trimRef != null) {
					//alert("trimRef aint null");
					shortTrimWrap = new shortHandTrimWrapper(trimID, trimRef.shortName, trimRef.img);
				}
			}
			else{//get the key
			}
		} catch(e) { sendToErrorSink(e, null); }
	}
	
	return shortTrimWrap;
}
getTrimPacket["name"] = "getTrimPacket";


function shortHandTrimWrapper(id, displayText, img) {
	this.id = id;
	this.text = displayText;
	this.img = img;
}


function grabCompetitorsTrimWrapper(id) {
	var wrapper = null;
	if(compVehicles != null) {
		for(var i = 0; i < compVehicles.length; i++) {
			var ref = compVehicles[i];
			if(ref.id == id) {
				//alert("got ref for id " + id);
				wrapper = ref;
				break;
			}
		}
	}
	
	return wrapper;
}


function retrieveTrimFromModel(refModel, trimID) {
	var refTrim = null;
	var trimRef;
	for(var i=0; i < refModel.trims.length; i++) {
		trimRef = refModel.trims[i];
		if(trimRef.id == trimID) {
			brokeOut = true;
			break;
		}
	}
	
	if(brokeOut) {
		refTrim = trimRef;
	}
	
	return refTrim;
}


function setAICMessaging() {
	var refAICMsg = $("aicMsgBox");
	try {
		if(StateMonitor.getCompetitiveTabState() == "on") {
			refAICMsg.innerHTML = MSG_AIC_COMP.replace(MSG_AIC_VEH_REPLACE_EXP, MSG_AIC_VEH_REPLACE);
		}
		else {
			refAICMsg.innerHTML = MSG_AIC_MITS.replace(MSG_AIC_VEH_REPLACE_EXP, MSG_AIC_VEH_REPLACE);
		}
	} catch(e) { sendToErrorSink(e, null);  }
}
setAICMessaging["name"] = "setAICMessaging";

/*
Latch provided to the flash nav menu, called whenever that thing opens or closes
*/
var showHideElements = new Array();
function showHideFields() {
	if (showHideElements.length == 0){
		for(var i = 4 ; i > 0; i--) {
			if( $(("makes" + i)).style.display == "block" ) {
				showHideElements.push( ("makes" + i) );
				$(("makes" + i)).style.display = "none";
			}
			if( $(("models" + i)).style.display == "block" ) {
				showHideElements.push( ("models" + i) );
				$(("models" + i)).style.display = "none";
			}
			if( $(("trims" + i)).style.display == "block" ) {
				showHideElements.push( ("trims" + i) );
				$(("trims" + i)).style.display = "none";
			}			
		}
	}
	else {
		while(showHideElements.length != 0){
			var elemRef = showHideElements.pop();
			$((elemRef)).style.display = "block";
		}	
	}
}


