/**
 * @author jwood
 */
var _ud = "undefined";
var	_debug = false;
var	_showFirebug = false;
var _jsonPath = "http://www.pearltexas.com/tiresync/hjs/json2.js";
//var _tgBaseScriptService = "http://www.pearltexas.com/tiresync/Services/TGScriptService.svc/";
//var _tgBaseScriptService = "http://www.pearltexas.com/Services/TGDataService/";
var _tgBaseScriptService = "http://www.tiresync.com/Services/TGDataService/";

var	clientInfo = new ClientInfoObject();
var	displayInfoObject = new DisplayInfoObject();
var fetch = new Fetch();

//Protos
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/, ''); };

//Color Parse Functions//
function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7):h}
function red(h) {return parseInt((cutHex(h)).substring(0,2),16)};
function green(h) {return parseInt((cutHex(h)).substring(2,4),16)};
function blue(h) {return parseInt((cutHex(h)).substring(4,6),16)};

function ShowError(errorMsg){
	alert(errorMsg);
}
/////////////////////////	

function getRGBAString(hex,opacity){
	
	var o = String(opacity);
	return "rgba("+ String(red(hex)) + "," + String(green(hex)) + "," + String(blue(hex)) + "," + opacity + ")";					
}
//End Color Parse Functions

function stringifyJSON(data){
	return JSON.stringify(data)
}

function assignFloat(element,floatString){
	element.style.cssFloat = floatString;
	element.style.styleFloat = floatString;
}

function adjustMaskSize(){
	var vp =  displayInfoObject.getViewportSize();
	var div = document.getElementById(CSSNames.maskDivId);
	
	div.style.left="0px";
	div.style.top="0px";
	div.style.width = "100%";
	div.style.height = vp.height;
}
function stripAlphabet(str){
	return String(str).replace(/[a-z]/gi,'');			
}

function getMaskDivBase(size){	
	var div = createElement('div',CSSNames.maskDivId);	
	div.style.position = "absolute";
	div.style.left="0px";
	div.style.top="0px";
	div.style.width = "100%";
	div.style.zIndex = "101";
	div.style.height = size.height;
	return div;	
}
function getIEMaskDiv(size){	
	var div = getMaskDivBase(size);
	div.style.background = "transparent";
	div.style.filter = "progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr="+ MaskOptions.getStartColorHexString() +", EndColorStr="+ MaskOptions.getEndColorHexString() +")";
	div.style.filter += "progid:DXImageTransform.Microsoft.Alpha(Opacity="+ (MaskOptions.getStartOpacity() * 100).toString() +")";
	return div;
}
function getWebkitMaskDiv(size){
	var div = getMaskDivBase(size);
			
	div.style.background = "-webkit-gradient(linear, left top, left bottom, from("+
	 getRGBAString(MaskOptions.getStartColorHexString(),MaskOptions.getStartOpacity()) + "), to("+
	 getRGBAString(MaskOptions.getEndColorHexString(),MaskOptions.getEndOpacity()) +"))";
	 		 
	div.style.position = "fixed";
	div.style.width = "100%";		
	return div;
}
function getCanvasMaskDiv(size){
	var div = getMaskDivBase(size);	
	div.style.position = "fixed";
	div.style.width = "100%";
	div.style.height = size.height;
	
	var startColor = null;
	var endColor = null;
	
	if(clientInfo.supportsRGBATransparency()){
		startColor = getRGBAString(MaskOptions.getStartColorHexString(),MaskOptions.getStartOpacity());
		endColor = getRGBAString(MaskOptions.getEndColorHexString(),MaskOptions.getEndOpacity());		
	}
	else {
		startColor = maskColors.getStartColorHexString();
		endColor = maskColors.getEndColorHexString();
		div.style.opacity = maskOpacity.getStartOpacity().toString();		
	}
		
	//If rgba is supported use that opacity//
	var canvas = document.createElement('canvas');	
	canvas.style.width = "100%";
	canvas.style.height = "100%";
		
		
	if (canvas.getContext) {  
		var ctx = canvas.getContext("2d");  
				
		var gradient = ctx.createLinearGradient(0,0,0,stripAlphabet(size.width));
		gradient.addColorStop(0,startColor);
		gradient.addColorStop(.1,endColor);	
		ctx.fillStyle = gradient;
		ctx.fillRect (0,0,stripAlphabet(size.width),stripAlphabet(size.height));				
		div.appendChild(canvas); 				
	}
	else{
		var d = document.createElement('div');
		d.innerHTML ="I do not support canvas";
		div.appendChild(d);
	}
	
	return div;
}
 

function toggleSelectDisable(selectId, boolDisable){
	document.getElementById(selectId).disabled = boolDisable;
}


function enableYearSelect(){
	toggleSelectDisable(CSSNames.yearSelectId,false);
}
function enableMakeSelect(){
	toggleSelectDisable(CSSNames.makeSelectId,false);
}
function enableModelSelect(){
	toggleSelectDisable(CSSNames.modelSelectId,false);	
}
function enableOptionSelect(){
	toggleSelectDisable(CSSNames.optionSelectId,false);	
}

function disableYearSelect(){
	toggleSelectDisable(CSSNames.yearSelectId,true);
}
function disableMakeSelect(){
	toggleSelectDisable(CSSNames.makeSelectId,true);
}
function disableModelSelect(){
	toggleSelectDisable(CSSNames.modelSelectId,true);	
}
function disableOptionSelect(){
	toggleSelectDisable(CSSNames.optionSelectId,true);	
}

function parseJSON(data){
	try {
		return eval(data);
	} 
	catch(e)
	{
		throw "Unable to parse json string";
	}   
}

function getCanvasMaskDiv(size){
	var div = getMaskDivBase(size);	
	div.style.position = "fixed";
	div.style.width = "100%";
	div.style.height = size.height;
	
	var startColor = null;
	var endColor = null;
	
	if(clientInfo.supportsRGBATransparency()){
		startColor = getRGBAString(MaskOptions.getStartColorHexString(),MaskOptions.getStartOpacity());
		endColor = getRGBAString(MaskOptions.getEndColorHexString(),MaskOptions.getEndOpacity());		
	}
	else {
		startColor = maskColors.getStartColorHexString();
		endColor = maskColors.getEndColorHexString();
		div.style.opacity = maskOpacity.getStartOpacity().toString();		
	}
		
	//If rgba is supported use that opacity//
	var canvas = document.createElement('canvas');	
	canvas.style.width = "100%";
	canvas.style.height = "100%";
		
		
	if (canvas.getContext) {  
		var ctx = canvas.getContext("2d");  
				
		var gradient = ctx.createLinearGradient(0,0,0,stripAlphabet(size.width));
		gradient.addColorStop(0,startColor);
		gradient.addColorStop(.1,endColor);	
		ctx.fillStyle = gradient;
		ctx.fillRect (0,0,stripAlphabet(size.width),stripAlphabet(size.height));				
		div.appendChild(canvas); 				
	}
	else{
		var d = document.createElement('div');
		d.innerHTML ="I do not support canvas";
		div.appendChild(d);
	}
	
	return div;
}

function setDataDisplay(notes,tires){
        			
	//append the data table//
	var dataTable = document.getElementById(CSSNames.layoutTableId);	
	var row = document.createElement('tr');
	var cell = document.createElement('td');
	row.appendChild(cell);
	cell.appendChild(DataHolderMethods.getDataTable(tires,notes));	
	dataTable.childNodes[0].appendChild(row);
}

function getVerticalStackSelectBar(){
	var d = createElement('div',CSSNames.selectBarDivId);	
	var t = createElement('table','vertical_select_table');
	var tbody = document.createElement('tbody')
	//var topRow = document.createElement('tr');	
	//var topLeftCell = document.createElement('td');
	//var topRightCell = document.createElement('td');
	
	var yearRow = document.createElement('tr');
	var yearCell = document.createElement('td');	
	var makeRow = document.createElement('tr');
	var makeCell = document.createElement('td');		
	var modelRow = document.createElement('tr');
	var modelCell = document.createElement('td');
	var optionRow = document.createElement('tr');
	var optionCell = document.createElement('td');
		
	d.appendChild(t);
	t.appendChild(tbody);
	tbody.appendChild(yearRow);	
	yearRow.appendChild(yearCell);
	
	tbody.appendChild(makeRow);
	makeRow.appendChild(makeCell);
	
	tbody.appendChild(modelRow);
	modelRow.appendChild(modelCell);
	tbody.appendChild(optionRow);
	optionRow.appendChild(optionCell);
			
	yearCell.width = makeCell.width = modelCell.width = optionCell.width = "100%";
	//topLeftCell.width = topRightCell.width = "50%";
			
	t.setAttribute('width','100%');
			
	//modelCell.colSpan =2;
	//optionCell.colSpan = 2;		
	
	var selectElements = getSelectElements();
	
	for(var i=0; i<selectElements.length; i++){					
		selectElements[i].style.width = "100%";
	}  
		
	yearCell.appendChild(selectElements[0]);
	makeCell.appendChild(selectElements[1]);
	modelCell.appendChild(selectElements[2]);
	optionCell.appendChild(selectElements[3]);
	
	return d;	
}

function getVerticalSelectBar(){
	var d = createElement('div',CSSNames.selectBarDivId);	
	var t = createElement('table','vertical_select_table');
	var tbody = document.createElement('tbody')
	var topRow = document.createElement('tr');
	var topLeftCell = document.createElement('td');
	var topRightCell = document.createElement('td');
	var modelRow = document.createElement('tr');
	var modelCell = document.createElement('td');
	var optionRow = document.createElement('tr');
	var optionCell = document.createElement('td');
		
	d.appendChild(t);
	t.appendChild(tbody);
	tbody.appendChild(topRow);
	
	topRow.appendChild(topLeftCell);
	topRow.appendChild(topRightCell);
	
	tbody.appendChild(modelRow);
	modelRow.appendChild(modelCell);
	tbody.appendChild(optionRow);
	optionRow.appendChild(optionCell);
			
	modelCell.width = optionCell.width = "100%";
	topLeftCell.width = topRightCell.width = "50%";
			
	t.setAttribute('width','100%');
			
	modelCell.colSpan =2;
	optionCell.colSpan = 2;		
	
	var selectElements = getSelectElements();
	
	for(var i=0; i<selectElements.length; i++){					
		selectElements[i].style.width = "100%";
	}  
		
	topLeftCell.appendChild(selectElements[0]);
	topRightCell.appendChild(selectElements[1]);
	modelCell.appendChild(selectElements[2]);
	optionCell.appendChild(selectElements[3]);
	
	return d;	
}
function getHorizontalSelectBar(){
	var d = createElement('div',CSSNames.selectBarDivId);
	var t = document.createElement('table');
	var tbody = document.createElement('tbody');
	var tr = document.createElement('tr');
	var cell1 = document.createElement('td');
	var cell2 = document.createElement('td');
	var cell3 = document.createElement('td');
	var cell4 = document.createElement('td');
	
	d.appendChild(t);
	t.appendChild(tbody);
	tbody.appendChild(tr);
	tr.appendChild(cell1);
	tr.appendChild(cell2);
	tr.appendChild(cell3);
	tr.appendChild(cell4);
	
	var selectElements = getSelectElements();
		
	cell1.appendChild(selectElements[0]);
	cell2.appendChild(selectElements[1]);
	cell3.appendChild(selectElements[2]);
	cell4.appendChild(selectElements[3]);
	
	cell1.style.marginRight = constants.horizontal_select_margin_right;
	cell2.style.marginRight = constants.horizontal_select_margin_right;
	cell3.style.marginRight = constants.horizontal_select_margin_right;
	cell4.style.marginRight = constants.horizontal_select_margin_right;
	
	cell1.setAttribute('width',"20%");
	cell2.setAttribute('width',"20%");
	cell3.setAttribute('width',"25%");
	cell4.setAttribute('width',"35%");
	
	t.setAttribute('width','100%');    
		
	for(var i=0;i<selectElements.length; i++){
	        selectElements[i].style.fontSize = constants.select_font_size; 
			selectElements[i].className = CSSNames.classSelectHolder;
			selectElements[i].style.width = "100%";		        
	    } 				
	
	return d;
}

function getPopupLayout(){		
	var rootDiv = getRootDiv();
	var wrapperDiv = createElement('div','popup_wrapper_div');	
	var closeBar = createElement('div','close_popup_div');
	var d = createElement('div',CSSNames.popupCloseButtonDivId);
	var titleDiv = createElement('div',CSSNames.popupTitleDivId);
		
	wrapperDiv.style.margin = "10px";
	wrapperDiv.style.backgroundColor = StyleOptions.getPopupBackgroundColor();
	wrapperDiv.style.textAlign = "center";	
	closeBar.style.width = "100%";
	closeBar.style.backgroundColor = 'transparent';
	closeBar.style.textAlign = "right";
			
	d.innerHTML = GetCloseButtonText();//"Close";
	
	titleDiv.innerHTML = PopupVariables.getPopupHeaderText();
	titleDiv.style.color = PopupVariables.getPopupHeaderFontColor();
	titleDiv.style.textAlign = "left";
	titleDiv.style.fontWeight = 'bold';
	titleDiv.style.fontFamily = 'Arial Black';
	titleDiv.style.width = "90%";	
	
	assignFloat(titleDiv,"left");
	titleDiv.style.paddingLeft = "5px";
	titleDiv.style.fontSize = "10pt";	
	
	d.style.color = StyleOptions.getPopupCloseButtonTextColor();
	d.style.textDecoration = "underline";
	d.style.fontFamily = "Arial Black";
	d.style.fontWeight = 'bold';

	d.style.fontSize = "10pt";
	d.style.marginRight = "10px";
	
	d.onclick = handlePopupCloseButtonClick;
	d.onmouseover = handleCloseButtonMouseOver;
	d.onmouseout = handleCloseButtonMouseOut;
	
	closeBar.appendChild(titleDiv);
	closeBar.appendChild(d);	
	wrapperDiv.appendChild(closeBar);	
	rootDiv.appendChild(wrapperDiv);		
	rootDiv.style.width = constants.horizontal_popup_width;		
	rootDiv.style.backgroundColor = "transparent"; 
	rootDiv.style.zIndex = '115';
		
	var layoutTable = createElement('table',CSSNames.layoutTableId);
	var tbody = document.createElement('tbody');
	layoutTable.appendChild(tbody);
								
	var selectRow = document.createElement('tr');
	var selectBarCell = document.createElement('td');
	
	if (StyleOptions.getOrientation() == "horizontal") {
		selectBarCell.appendChild(getHorizontalSelectBar());
	}
	else{
		selectBarCell.appendChild(getVerticalSelectBar());
	}		
	
	selectRow.appendChild(selectBarCell);	
	tbody.appendChild(selectRow);	
	layoutTable.setAttribute('width','100%');
	wrapperDiv.appendChild(layoutTable);
	
	if(clientInfo.isIE()){
		rootDiv.style.position = "absolute";
	}
	else{
		rootDiv.style.position = "fixed";
	}
	
	
	return rootDiv;
 	

}	

function getSelectElement(id,defaultOption,changeCallbackFunction){			
    var s = createElement('select',id);        
    s.options.length =1;
    s.options[0] = new Option(defaultOption,"0",true,false);	
	s.onchange = changeCallbackFunction;
	s.disabled = true;
	
	//TODO: Dont add if is set to 100% opacque if/else
	if(!clientInfo.isIE()){
			
		s.style.opacity = StyleOptions.getSelectBarOpacity();		
	}
	//else
		//s.style.filter += "progid:DXImageTransform.Microsoft.Alpha(Opacity="+ (StyleOptions.getSelectBarOpacity() * 100).toString() +")";
	
    return s;
}

function getSelectElements(){
	
    var year = getSelectElement(CSSNames.yearSelectId,GetYearSelectHeaderText(),SelectChangeHandlers.selectedYearChanged);
    var make = getSelectElement(CSSNames.makeSelectId,GetMakeSelectHeaderText(),SelectChangeHandlers.selectedMakeChanged);
    var model = getSelectElement(CSSNames.modelSelectId,GetModelSelectHeaderText(),SelectChangeHandlers.selectedModelChanged);
    var option =getSelectElement(CSSNames.optionSelectId,GetOptionSelectHeaderText(),SelectChangeHandlers.selectedOptionChanged);
    
    year.className = CSSNames.classSelect;
    make.className = CSSNames.classSelect;
    model.className = CSSNames.classSelect;
    option.className = CSSNames.classSelect;
    
    var elements = new Array(4);
    elements[0] = year;
    elements[1] = make;
    elements[2] = model;
    elements[3] = option;
    
    return elements;
}
function getRootDiv(){

	var rootDiv = createElement('div', CSSNames.rootDivId);
	rootDiv.style.clear = "both";
	return rootDiv;
}
function createElement(tagName, id){
	var e = document.createElement(tagName);
	e.setAttribute('id',id);
	return e;
}
function getInlineLayout(){
	var rootDiv = getRootDiv();
	var layoutTable = createElement('table',CSSNames.layoutTableId);
	var tbody = document.createElement('tbody');		
	var selectRow = document.createElement('tr');
	var selectBarCell = document.createElement('td');
	
	if (StyleOptions.getOrientation() == "horizontal") {
		selectBarCell.appendChild(getHorizontalSelectBar());
	}
	else if(StyleOptions.getOrientation() == "verticalStack")
	{
		selectBarCell.appendChild(getVerticalStackSelectBar());		
	}
	else
	{
		selectBarCell.appendChild(getVerticalSelectBar());
	}	
		
	selectRow.appendChild(selectBarCell)
	
	if (ServiceOptions.getMode() == "default") {
		var w = _parentContainer.offsetWidth;
		layoutTable.style.width = w + "px";
	}
	else{
		if(StyleOptions.getOrientation() == "horizontal")
			layoutTable.style.width = constants.horizontal_popup_width;
		else
			layoutTable.style.width = constants.vertical_popup_width;		
	}
	
	layoutTable.setAttribute('align','center');
					
	layoutTable.appendChild(tbody);
	tbody.appendChild(selectRow);	
	rootDiv.appendChild(layoutTable);
	return rootDiv;	
}

function loadJSON(){
	var s = createElement('script','scriptJSON');
	s.setAttribute('src',_jsonPath);
	s.setAttribute('type','text/javascript');
	document.getElementsByTagName('head').item(0).appendChild(s);
}

function createElement(tagName, id){
	var e = document.createElement(tagName);
	e.setAttribute('id',id);
	return e;
}

//Begin MaskOptions
var MaskOptions = {		
	getStartColorHexString: function(){
		if(typeof ti_mask_start_color_hex != _ud)
			return ti_mask_start_color_hex;
		else
			return '#0000FF';
		},
				
	getEndColorHexString: function(){
		if(typeof ti_mask_end_color_hex != _ud)
			return ti_mask_end_color_hex;
		else
			return '#000000';		
		},	
			
	getStartOpacity: function(){
		if(typeof ti_mask_start_opacity != _ud)
			return ti_mask_start_opacity;
		else
			return .80;
		},
		
	getEndOpacity: function(){
		if(typeof ti_mask_end_opacity != _ud)
			return ti_mask_end_opacity;
		else
			return .80;
		}
}
//End MaskOptions

//Begin Constants
var constants = {
    horizontal_popup_width:"650px",
    horizontal_buffer_width:"5px",
    vertical_popup_width:"250px",
	
    vertical_year_select_width:"80px",
	vertical_make_select_width:"93px",
	vertical_model_select_width:"175px",
	vertical_options_select_width:"175px",
	vertical_select_padding_right:"2px",	
	
    horizontal_year_select_width:"100px",
    horizontal_make_select_width:"100px",
    horizontal_model_select_width:"195px",
    horizontal_option_select_width:"195px",
    horizontal_select_margin_right:"2px",	
	vertical_select_margin_bottom:"2px",
	
    select_font_size:"7.5pt"
}
//End Constants

//Begin Reset
var Reset = {                
    select:function(selectId,defaultOption){		
        var select = document.getElementById(selectId);		
        select.options.length=1;
        select.options[0] = new Option(defaultOption,"0",true,false);		
		//select.disabled = true;		               
    },
    dataTable:function(){
		
		//var r = document.getElementById(CSSNames.dataRowId);
		//alert('a');
		var t = document.getElementById(CSSNames.dataTableId);
		
		if(t !=null && typeof t != _ud){			
			//t.parentNode.removeChild(t);
			var p = t.parentNode.parentNode;
			p.parentNode.removeChild(p);						
		}
		
	
    }
};
//End Reset

/**
 * @author jwood
 */
//Begin DataHolderMethods
var DataHolderMethods = {
    //creates a "row"//
    getDataRow:function(sizeDesc,fitment){
		
		var row = document.createElement('tr')
		row.setAttribute('id',CSSNames.dataRowId);
		row.className = CSSNames.tableDataRowClass;
		row.style.backgroundColor = StyleOptions.getDataTableDataRowBackgroundColor();
		
		var sizeDescDataElement = document.createElement('td');
		var fitmentDataElement = document.createElement('td');
		
		sizeDescDataElement.style.fontSize = fitmentDataElement.style.fontSize = "8pt";
		sizeDescDataElement.style.color = fitmentDataElement.style.color = StyleOptions.getDataTableDataRowFontColor();
		sizeDescDataElement.style.paddingRight = "10px"; 
		

		fitmentDataElement.style.width = "35%"
		sizeDescDataElement.style.width = "65%";
					
		
		sizeDescDataElement.innerHTML = sizeDesc;
		fitmentDataElement.innerHTML = fitment;
		
		row.appendChild(sizeDescDataElement);
		row.appendChild(fitmentDataElement);		
		return row;
    },

    getHeaderRow:function(){		
		var row = document.createElement('tr');
		row.className = CSSNames.tableHeaderRowClass; 
		
		var sizeDescHeaderElement = document.createElement('td');
		var fitmentHeaderElement = document.createElement('td');
		
		sizeDescHeaderElement.style.textDecoration = fitmentHeaderElement.style.textDecoration = "underline";
		sizeDescHeaderElement.style.color = fitmentHeaderElement.style.color = StyleOptions.getDataTableHeaderRowFontColor();
		sizeDescHeaderElement.style.backgroundColor = fitmentHeaderElement.style.backgroundColor = StyleOptions.getDataTableHeaderRowBackgroundColor();
		sizeDescHeaderElement.style.fontSize = fitmentHeaderElement.style.fontSize = "10pt";
		sizeDescHeaderElement.style.fontWeight = fitmentHeaderElement.style.fontWeight = "Bold";
		sizeDescHeaderElement.style.width = "50%"
		fitmentHeaderElement.style.width =  "50%";
		sizeDescHeaderElement.style.paddingRight = "10px"; 
		
		sizeDescHeaderElement.innerHTML = GetTireSizeColumnHeaderText();
		fitmentHeaderElement.innerHTML = GetTireFitmentColumnHeaderText();
		
		row.appendChild(sizeDescHeaderElement);
		row.appendChild(fitmentHeaderElement);
		return row;    
    },
	getNotesRow:function(notes){		
		//var notesTable = document.createElement('table',CSSNames.notesTableId);					
		var notesRow = document.createElement('tr');				
		var notesCell = document.createElement('td');
		notesCell.colSpan =2;//notesCell.setAttribute('colspan','2');		
				
		//var notesHolder = createElement('div',CSSNames.dataNotesDivId);
		//notesHolder.innerHTML = notes;
		notesCell.innerHTML = notes;//appendChild(notesHolder);
		notesRow.appendChild(notesCell);		
		//notesTable.appendChild(notesRow);
		
		notesCell.style.backgroundColor = StyleOptions.getNotesDivBackgroundColor();
		notesCell.style.color = StyleOptions.getNotesFontColor();
		notesCell.style.width = notesRow.style.width = "100%";
			
		return notesRow;	
		//return notesTable;
	},
	getDisclaimerRow:function(){
		var row = document.createElement('tr');
		var cell = document.createElement('td');
		cell.colSpan = 2;
		cell.innerHTML = '<hr></hr>DISCLAIMER: THE INFORMATION AND CONTENT CONTAINED HEREIN ARE PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, ACCURACY, COMPLETENESS, AND INFORMATIONAL CONTENT. YOU USE SUCH INFORMATION AND CONTENT SOLELY AT YOUR OWN RISK. YOU ACCEPT FULL RESPONSIBILITY FOR ANY AND ALL DECISIONS MADE BY YOU IN RELIANCE UPON SUCH INFORMATION OR CONTENT.';
		cell.style.fontSize = "7pt";
		cell.style.paddingTop ="5px";		
		cell.style.fontFamily = "Arial";
		cell.style.color = StyleOptions.getDataTableDataRowFontColor();
		cell.style.backgroundColor = StyleOptions.getDataTableHeaderRowBackgroundColor(); 
		cell.style.textAlign="left";
		row.appendChild(cell);
		return row;
	},
	getDataTable:function(tires,notes){
		var dataTable = createElement('table',CSSNames.dataTableId);
		var tbody = document.createElement('tbody');
		dataTable.appendChild(tbody);
			
		var headerRow = DataHolderMethods.getHeaderRow();
		
	
		dataTable.style.width = "100%";
		
		dataTable.style.backgroundColor = StyleOptions.getDataTableBackgroundColor();
		
		if(clientInfo.isIE()){
			dataTable.style.filter += "progid:DXImageTransform.Microsoft.Alpha(Opacity="+ (StyleOptions.getDataTableOpacity() * 100).toString() +")";
		}
		else
			dataTable.style.opacity = StyleOptions.getDataTableOpacity();
			
			
		
		
		tbody.appendChild(headerRow);
		
		
		for(var i=0; i<tires.length;i++){
			//var baseTireDataObject = tires[i].baseTireDataObjectField;
			//var dataRow = DataHolderMethods.getDataRow(baseTireDataObject.sizeDescField,baseTireDataObject.fitmentField);
			var dataRow = DataHolderMethods.getDataRow(tires[i].SizeDescription,tires[i].Fitment)
			tbody.appendChild(dataRow);
		}
		
		if(notes != null && typeof notes != "undefined" && notes.trim() != "" ){
			tbody.appendChild(DataHolderMethods.getNotesRow(notes));			
		}
		
		tbody.appendChild(DataHolderMethods.getDisclaimerRow());
		
		
		return dataTable;
	},
    getDataDisplay:function(tires,notes){			
		var dataHolder = createElement('div',CSSNames.dataContentDivId);
		dataHolder.style.clear = "both";
		var dataTable = DataHolderMethods.getDataTable(tires,notes);		
		dataHolder.appendChild(dataTable);		
		return dataHolder;				

    }
    
}
//Begin DataHolderMethods
/**
 * @author jwood
 */
//Begin SelectChangeHandlers
var SelectChangeHandlers = {
	
	selectedYearChanged:function(){
		var index = document.getElementById(CSSNames.yearSelectId).selectedIndex;
        document.getElementById(CSSNames.makeSelectId).selectedIndex=0;
        document.getElementById(CSSNames.modelSelectId).selectedIndex=0;
        document.getElementById(CSSNames.optionSelectId).selectedIndex=0;
        SelectChangeHandlers.handleSelectedItemChanged();
    
        if (index == 0) {
			enableYearSelect();
			return;
		}
		else {
			var year = document.getElementById(CSSNames.yearSelectId).options[index].text;
			fetch.makes(year,"DataReceiver.makesReceived");
		}
	},
	selectedMakeChanged:function(){
		var index = document.getElementById(CSSNames.makeSelectId).selectedIndex;
        document.getElementById(CSSNames.modelSelectId).selectedIndex=0;
        document.getElementById(CSSNames.optionSelectId).selectedIndex=0;
        SelectChangeHandlers.handleSelectedItemChanged();
        
        if (index == 0) {
			SelectChangeHandlers.selectedYearChanged();
			//document.getElementById(CSSNames.modelSelectId).disabled = true;	
			return;
		}
		else {
			//document.getElementById(CSSNames.modelSelectId).disabled = true;
			var make = document.getElementById(CSSNames.makeSelectId).options[index].text;
			var year = document.getElementById(CSSNames.yearSelectId).options[document.getElementById(CSSNames.yearSelectId).selectedIndex].text;
			fetch.models(year,make, 'DataReceiver.modelsReceived');
		}
	},
	selectedModelChanged:function(){
		var index = document.getElementById(CSSNames.modelSelectId).selectedIndex;
        document.getElementById(CSSNames.optionSelectId).selectedIndex=0;            
        SelectChangeHandlers.handleSelectedItemChanged();
        
        if (index == 0) {
			SelectChangeHandlers.selectedMakeChanged();
			return;
		}
		else {
		
			if (!document.getElementById(CSSNames.modelSelectId).options[index]) 
				return;
			
			var model = document.getElementById(CSSNames.modelSelectId).options[index].text;
			var make = document.getElementById(CSSNames.makeSelectId).options[document.getElementById(CSSNames.makeSelectId).selectedIndex].text;
			var year = document.getElementById(CSSNames.yearSelectId).options[document.getElementById(CSSNames.yearSelectId).selectedIndex].text;
			
			
			fetch.options(year, make, model,'DataReceiver.optionsReceived');
		}
	},
	selectedOptionChanged:function(){
		var index = document.getElementById(CSSNames.optionSelectId).selectedIndex;
		Reset.dataTable();
        SelectChangeHandlers.handleSelectedItemChanged();
        if (index == 0) {
			SelectChangeHandlers.selectedModelChanged();
			return;
		}
		else {
			var option = document.getElementById(CSSNames.optionSelectId).options[index].text;
			var model = document.getElementById(CSSNames.modelSelectId).options[document.getElementById(CSSNames.modelSelectId).selectedIndex].text;
			var make = document.getElementById(CSSNames.makeSelectId).options[document.getElementById(CSSNames.makeSelectId).selectedIndex].text;
			var year = document.getElementById(CSSNames.yearSelectId).options[document.getElementById(CSSNames.yearSelectId).selectedIndex].text;
			fetch.tireInfoObjects(year, make, model, option,'DataReceiver.tireInfoReceived');
		}
	},
	handleSelectedItemChanged:function(){ 
        SetData.cleanupTable();		
		disableYearSelect();
		disableMakeSelect();
		disableModelSelect();
		disableOptionSelect();
		
        if(document.getElementById(CSSNames.yearSelectId).selectedIndex <= 0)
        {
            Reset.select(CSSNames.makeSelectId,GetMakeSelectHeaderText());
            Reset.select(CSSNames.modelSelectId,GetModelSelectHeaderText());
            Reset.select(CSSNames.optionSelectId,GetOptionSelectHeaderText());
            Reset.dataTable();
            return;
        }
        else if(document.getElementById(CSSNames.makeSelectId).selectedIndex <= 0)
        {
            Reset.select(CSSNames.modelSelectId,GetModelSelectHeaderText());
            Reset.select(CSSNames.optionSelectId,GetOptionSelectHeaderText());
            Reset.dataTable();
            return;        
        }
        else if(document.getElementById(CSSNames.modelSelectId).selectedIndex <= 0)
        {
            Reset.select(CSSNames.optionSelectId,GetOptionSelectHeaderText());
            Reset.dataTable();           
            return;
        }
        else if(document.getElementById(CSSNames.optionSelectId).selectedIndex <= 0)
        {
            Reset.dataTable();
            return;
        }
    }
}
//End SelectChangeHandlers

function handlePopupCloseButtonClick(){
	var m = document.getElementById(CSSNames.maskDivId);
	var p = document.getElementById(CSSNames.rootDivId);
	p.style.display = m.style.display = "none";
	
	Reset.select(CSSNames.yearSelectId,GetYearSelectHeaderText());
	
    Reset.select(CSSNames.makeSelectId,GetMakeSelectHeaderText());
    Reset.select(CSSNames.modelSelectId,GetModelSelectHeaderText());
    Reset.select(CSSNames.optionSelectId,GetOptionSelectHeaderText());
	
	if(clientInfo.isIE())
		document.body.style.overflow ="auto";  
            
    SelectChangeHandlers.handleSelectedItemChanged();		
    fetch.years("DataReceiver.yearsReceived");
		
}

function handleCloseButtonMouseOver(){
	document.body.style.cursor = "pointer";
}
function handleCloseButtonMouseOut(){
	document.body.style.cursor = "auto";
}

function getPopupButton(){
	var b = document.createElement('button',CSSNames.popupLaunchButtonId);
	
	b.innerHTML = PopupVariables.getPopupButtonText();
	b.onclick = handlePopupButtonClick;
	return b;
}

function handlePopupButtonClick(){
	var m = document.getElementById(CSSNames.maskDivId);
	//var p = document.getElementById(CSSNames.popupWrapperTableId);
	var p = document.getElementById(CSSNames.rootDivId);
	p.style.display = m.style.display = "block";
	
	var w = document.body.offsetWidth;
	if (w) 
		w = w / 2;
	else {		
		w = 0;
	}
	
	w = w - (p.offsetWidth / 2);
		
	p.style.left = w + "px";
	
	if(clientInfo.isIE())
		document.body.style.overflow ="hidden";
	
	 adjustMaskSize();                          
		
	
}

//Begin ScriptVariables//
var ScriptVariables = {
	getCssPrefix : function(){
		if(typeof ti_css_prefix != _ud)
			return ti_css_prefix;
		else 
			return "ti_";
		}
}
//End ScriptVariables

/**
 * @author jwood
 */
//Begin SetData
var SetData = {
	setTireInfoToTextArea:function(tireInfoObjects)
	{
		enableYearSelect();	
		enableMakeSelect();
		enableModelSelect()
	 	enableOptionSelect(); 
		
		if(ServiceOptions.getReturnTextAreaId() == "")
			return;
		
		var e= document.getElementById(ServiceOptions.getReturnTextAreaId());
		
		if(e == _ud || e == null)
			return;
		
		var notes = tireInfoObjects.Notes
        var tires = tireInfoObjects.OEDataObjects;
		var s = "";
		for(var i=0; i<tires.length; i++){
			s += "SizeDescription: " + tires[i].SizeDescription + " Fitment: " + tires[i].Fitment + "\r\n";			
		}   
		
		s+= notes + "\r\n";
		
		e.innerHTML = s;
	},
    cleanupTable:function()
    {		
        if(ServiceOptions.getMode() == "popup")
            return;
        else
        {
            var d = document.getElementById(CSSNames.dataHolderDivId);
            if(d == null || typeof d == "undefined")
                return;
            else
            {
				
                d.parentNode.removeChild(d);
            }
        }
    },
    setSelectOptions:function(select,options,defaultOption){                
		select.options.length = options.length + 1;		
        select.options[0] = new Option(defaultOption,0,true,false);
		
        for(var i=0; i<options.length; i++)
        {			
            select.options[i+1] = new Option(options[i],options[i],false,false);                
        }
        //select.disabled = false;
    },        
    setYears:function(years){
        var select = document.getElementById(CSSNames.yearSelectId);
        SetData.setSelectOptions(select,years,GetYearSelectHeaderText());
		enableYearSelect();		
    },
    setMakes:function(makes){
						
        var select = document.getElementById(CSSNames.makeSelectId);
        SetData.setSelectOptions(select,makes,GetMakeSelectHeaderText());
		enableYearSelect();	
		enableMakeSelect();
    },
    setModels:function(models){						
        var select = document.getElementById(CSSNames.modelSelectId);
        SetData.setSelectOptions(select,models,GetModelSelectHeaderText());
		enableYearSelect();	
		enableMakeSelect();
		enableModelSelect();
    },
    setOptions:function(options){
        var select = document.getElementById(CSSNames.optionSelectId);
        SetData.setSelectOptions(select,options,GetOptionSelectHeaderText());
		enableYearSelect();	
		enableMakeSelect();
		enableModelSelect()
	 	enableOptionSelect();
    },
    setTireInfo:function(tireInfoObjects){		 
		enableYearSelect();	
		enableMakeSelect();
		enableModelSelect()
	 	enableOptionSelect();             
        var notes = tireInfoObjects.Notes
        var tires = tireInfoObjects.OEDataObjects;                          
		setDataDisplay(notes,tires);        
        return;
    }     
};
//End SetData   

//Begin DataReceiver
//Callback methods that received data from AJAX calls//
var DataReceiver = {
    yearsReceived:function(jsonYears){
            			
            var yearsData = parseJSON(jsonYears);				
			var years= yearsData.Items;
			
			if(yearsData.ErrorMessage != null && (typeof yearsData.ErrorMessage) != "undefined")
			{
				ShowError(yearsData.ErrorMessage);
				return;
			}
			            
            if(yearRequestObject != null){
                yearRequestObject.removeScriptTag();
                yearRequestObject = null;
            }                     
            SetData.setYears(years);            
            
    },
    makesReceived:function(jsonMakes){
            var makesData = parseJSON(jsonMakes);
			var makes = makesData.Items;
			
			if(makesData.ErrorMessage != null && (typeof makesData.ErrorMessage) != "undefined")
			{
				ShowError(makesData.ErrorMessage);
				return;
			}
			
            if(makeRequestObject != null){
                makeRequestObject.removeScriptTag();
                makeRequestObject = null;
            }
            SetData.setMakes(makes);
    },
    modelsReceived:function(jsonModels){
            var modelsData = parseJSON(jsonModels);
			var models = modelsData.Items;
			
			if(modelsData.ErrorMessage != null && (typeof modelsData.ErrorMessage) != "undefined")
			{
				ShowError(modelsData.ErrorMessage);
				return;
			}
			
            if(modelRequestObject != null){
                modelRequestObject.removeScriptTag();
                modelRequestObject = null;
            }            
            SetData.setModels(models);
			
    },
    optionsReceived:function(jsonOptions){
            var optionsData = parseJSON(jsonOptions);
			var options = optionsData.Items;
			
			if(optionsData.ErrorMessage != null && (typeof optionsData.ErrorMessage) != "undefined")
			{
				ShowError(optionsData.ErrorMessage);
				return;
			}
			
			
            if(optionRequestObject != null){
                optionRequestObject.removeScriptTag();
                optionRequestObject.options = null;
            }                            
            SetData.setOptions(options);
    },
    tireInfoReceived:function(jsonResponse){
		
        if(tireInfoRequestObject != null){
            tireInfoRequestObject.removeScriptTag();
            tireInfoRequestObject = null;
        } 
		
		var tireInfoObjects =  parseJSON(jsonResponse);
		
		if(tireInfoObjects.ErrorMessage != null && (typeof tireInfoObjects.ErrorMessage) != "undefined")
		{
				ShowError(tireInfoObjects.ErrorMessage);
				return;
		}
		
		          
        if(ServiceOptions.getReturnURL() == ""){
			if(ServiceOptions.getReturnTextAreaId() == "" || ServiceOptions.getMode() == "popup") 			                     
            	SetData.setTireInfo(tireInfoObjects);
			else
				SetData.setTireInfoToTextArea(tireInfoObjects)
        }		
        else{
            if(ServiceOptions.getReturnURL() == "debug" && _debug)
                debugAlert(jsonResponse);
            else{               
                                        
               var encString = stringifyJSON(jsonResponse);
                document.location = ServiceOptions.getReturnURL() + "?OEDataCollection=" + encodeURI( Base64.encode(encString));
            }
        }
    }
};
//END DataReceiver//
/**
 * @author jwood
 */
//Begin CSSNames
var CSSNames = {                 
        rootDivId : ScriptVariables.getCssPrefix() + "id_div_root",        
		selectBarDivId : ScriptVariables.getCssPrefix() + "id_div_select_bar",
		
        //Popup divs//
		popupLaunchButtonId:ScriptVariables.getCssPrefix() + "id_button_popup_launcher",		        
        popupTitleDivId:ScriptVariables.getCssPrefix() +"id_div_popup_title",
        popupCloseButtonDivId:ScriptVariables.getCssPrefix() +"id_div_close_button",        
        
        //Data Holders//        
        dataHolderDivId:ScriptVariables.getCssPrefix() +"id_div_data_holder",
        dataContentDivId:ScriptVariables.getCssPrefix() +"id_div_data_content",
		dataTableId:ScriptVariables.getCssPrefix() + "id_table_data_content",
		dataRowId:ScriptVariables.getCssPrefix() + "id_data_row",
        
        //Mask//       
        maskDivId:ScriptVariables.getCssPrefix() +"id_div_mask",
                        
        //SELECTS//
        yearSelectId:ScriptVariables.getCssPrefix() +"id_select_year",
        makeSelectId:ScriptVariables.getCssPrefix() +"id_select_make",
        modelSelectId:ScriptVariables.getCssPrefix() +"id_select_model",
        optionSelectId:ScriptVariables.getCssPrefix() +"id_select_option",        

        //TABLE//
		tableDataRowClass:ScriptVariables.getCssPrefix() +"class_table_data_row",
		tableHeaderRowClass:ScriptVariables.getCssPrefix() +"class_table_header_row",
		
		layoutTableId:ScriptVariables.getCssPrefix() +"id_layout_table",					        
        classSelect:ScriptVariables.getCssPrefix() +"class_select"
};
//End CSSNames

/**
 * @author jwood
 */
//Begin StyleOptions//
var StyleOptions = {
	getDataTableOpacity:function(){
		if (typeof ti_data_table_opacity != _ud) {
			return ti_data_table_opacity;
		}
		else 
			return "1";
		
	},
	getOrientation: function(){
		if(typeof ti_orientation != _ud)
			return ti_orientation;
		else
			return "horizontal";
	},
	getDataTableBackgroundColor: function(){
		if(typeof ti_data_table_background_color != _ud)
			return ti_data_table_background_color
		else
			return "transparent";
	},
	getDataTableHeaderRowBackgroundColor:function(){
		if(typeof ti_data_table_header_row_background_color != _ud)
			return ti_data_table_header_row_background_color;
		else
			return "White";
	},
	getDataTableDataRowBackgroundColor:function(){
		if(typeof ti_data_table_data_row_background_color != _ud)
			return ti_data_table_data_row_background_color;
		else
			return "White";		
	},
	getDataTableDataRowFontColor:function(){
		if(typeof ti_data_table_data_row_font_color != _ud)
			return ti_data_table_data_row_font_color;
		else
			return "Black";
	},
	getDataTableHeaderRowFontColor:function(){
		if(typeof ti_data_table_header_row_font_color != _ud)
			return ti_data_table_header_row_font_color;
		else
			return "Black";
	},
	getNotesFontColor:function(){
		if(typeof ti_notes_font_color != _ud)
			return ti_notes_font_color;
		else
			return "Black";
	},
	getNotesDivBackgroundColor:function(){
		if(typeof ti_notes_div_background_color != _ud)
			return ti_notes_div_background_color;
		else
			return "White";	
	},
	getPopupBackgroundColor:function(){
		if(typeof ti_popup_background_color != _ud)
			return ti_popup_background_color;
		else
			return "transparent";
	},
	getPopupCloseButtonTextColor:function(){
		return (typeof ti_popup_close_button_text_color == _ud) ? "White" : ti_popup_close_button_text_color;		
	},
	getSelectBarOpacity:function(){
		return (typeof ti_select_opacity == _ud) ? "1" : ti_select_opacity;
	},
	getLanguage:function(){
		return (typeof ti_language == _ud) ? "English" : ti_language;
	}	
}
//End StyleOptions//

//Begin JSONScriptRequest
// Constructor -- pass a REST request URL to the constructor
function JSONScriptRequest(fullUrl) {
    // REST request path
    this.fullUrl = fullUrl; 
    // Keep IE from caching requests
    this.noCacheIE = '&nc=' + (new Date()).getTime();
    // Get the DOM location to put the script tag
    this.headLoc = document.getElementsByTagName("head").item(0);
    // Generate a unique script tag id
    this.scriptId = 'ti_sid' + JSONScriptRequest.scriptCounter++;
}

// removeScriptTag method
JSONScriptRequest.prototype.removeScriptTag = function () {
    // Destroy the script tag
    
    this.headLoc.removeChild(this.scriptObj);  
}

// addScriptTag method
JSONScriptRequest.prototype.addScriptTag = function () {
    // Create the script tag
    this.headLoc.appendChild(this.scriptObj);
}


// Static script ID counter
JSONScriptRequest.scriptCounter = 1;

// buildScriptTag method
JSONScriptRequest.prototype.buildScriptTag = function () {

    // Create the script tag
    this.scriptObj = document.createElement("script");
    
    // Add script object attributes
    this.scriptObj.setAttribute("type", "text/javascript");
    this.scriptObj.setAttribute("charset", "utf-8");
    this.scriptObj.setAttribute("src", this.fullUrl + this.noCacheIE);
    this.scriptObj.setAttribute("id", this.scriptId);
}
//End JSONScriptRequest

var Validate = {
    isValidCSSName:function(str){
        //ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters,
        // digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").
        var cssPattern = /^[a-z]{1}[a-z1-9.:_-]*$/i;
        var s= str.match(cssPattern);
        if(s==str)
            return true;
        else
            return false;
    },
    text:function(str){
        str=str.replace(/\\/g,'\\\\');
        str=str.replace(/\'/g,'\\\'');
        str=str.replace(/\"/g,'\\"');
        str=str.replace(/\0/g,'\\0');
        return str;
    },
    isColor:function(incomingColor){      
      if(validate.isAlphabeticString(incomingColor))
        return true;
      
      if(validate.isHexColorString(incomingColor))
        return true;
        
      return false;        
    },
    isAlphabeticString:function(str) {
        var alpha = /[a-z]+/i;
        var s = str.toString();
        var b = s.match(alpha);        
        if(str == b)
            return true;
        else
            return false;
    },
    isHexColorString:function(str){
        var shortHex = /^#[a-f0-9]{3,6}$/i
        var s = str.match(shortHex);
        if(s == str)
            return true;
        else
            return false;
    },
    isValidSecurityToken:function(str){
        var securityTokenPattern = /^[\d]{4}-[\d]{4}-[\d]{4}-[\d]{4}$/i
        var s = str.match(securityTokenPattern);
        if(s==str)
            return true;
        else
            return false
    }    
};

//Begin Base64
var Base64 = {
	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",	
	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = Base64._utf8_encode(input);
 
		while (i < input.length) { 
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++); 
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
 
			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
 
			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
		}
		return output;
	},
	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
 
		while (i < input.length) { 
			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));
 
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
 
			output = output + String.fromCharCode(chr1);
 
			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			} 
		} 
		output = Base64._utf8_decode(output);
		return output; 
	}, 
	// private method for UTF-8 encoding
	_utf8_encode : function (istring) {
	    
	    var string =istring.toString();	    
		string = string.replace(/\r\n/g,"\n");
		
		
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
		}
		return utftext;
	},
 
	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
 
		while ( i < utftext.length ) { 
			c = utftext.charCodeAt(i);
 
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			} 
		} 
		return string;
	} 
}

//End Base64

//Begin Fetch
function Fetch(){
	this.getFullPath = function getFullPath(path,callbackName){
		return path + "&method=" + callbackName;
	};
	this.years=function(callback){
            var base64Hostname = Base64.encode(document.location.host);
            var p = this.getFullPath(_tgBaseScriptService +
			 ServiceOptions.getYearsMethod() + "?securityToken=" +
                ServiceOptions.getSecurityToken() + "&base64Hostname=" + encodeURI(base64Hostname),callback);//"dataReceiver.yearsReceived");
                
            yearRequestObject = new JSONScriptRequest(p);
            yearRequestObject.buildScriptTag();
            yearRequestObject.addScriptTag();   
                        
    },
    this.makes=function(year,callback){
			var base64Hostname = Base64.encode(document.location.host);
            var p  = this.getFullPath(_tgBaseScriptService  +
			 ServiceOptions.getMakesMethod() + "?securityToken=" +
			  ServiceOptions.getSecurityToken() + "&year=" + encodeURIComponent(year)+ "&base64Hostname=" + encodeURI(base64Hostname),callback);//"dataReceiver.makesReceived");
			  
            makeRequestObject = new JSONScriptRequest(p);
            makeRequestObject.buildScriptTag();
            makeRequestObject.addScriptTag();
    },
    this.models=function(year,make,callback){
			var base64Hostname = Base64.encode(document.location.host);
            var p = this.getFullPath(_tgBaseScriptService + ServiceOptions.getModelsMethod()
			 + "?securityToken=" + ServiceOptions.getSecurityToken() + "&year=" + encodeURIComponent(year) +
            "&make=" + encodeURIComponent(make) + "&base64Hostname=" + encodeURI(base64Hostname),callback);//"dataReceiver.modelsReceived");
            
            modelRequestObject = new JSONScriptRequest(p);
            modelRequestObject.buildScriptTag();
            modelRequestObject.addScriptTag();
    },
    this.options=function(year,make,model,callback){
			var base64Hostname = Base64.encode(document.location.host);
            var p = this.getFullPath(_tgBaseScriptService  + ServiceOptions.getOptionsMethod() + "?securityToken=" + ServiceOptions.getSecurityToken() +
			 "&year=" + encodeURIComponent(year) + "&make=" + encodeURIComponent(make) + "&model=" + encodeURIComponent(model) + "&base64Hostname=" +
			  encodeURI(base64Hostname),callback);//"dataReceiver.optionsReceived");
            
            optionRequestObject = new JSONScriptRequest(p);
            optionRequestObject.buildScriptTag();
            optionRequestObject.addScriptTag();
    },
    this.tireInfoObjects=function(year,make,model,option,callback){
            var base64Hostname = Base64.encode(document.location.host);
			            
            //var p = this.getFullPath(_tgOEScriptService  + ServiceOptions.getTireInfoMethod() + "?securityToken=" + ServiceOptions.getSecurityToken()
			 //+ "&year=" + encodeURIComponent(year) + "&make=" + encodeURIComponent(make) + "&model=" 
			 //+ encodeURIComponent(model) + "&option=" + encodeURIComponent(option)+ "&base64Hostname=" + encodeURI(base64Hostname) + "&scriptId=" + encodeURI(ServiceOptions.getPlaceHolderScriptName()),callback);//"dataReceiver.tireInfoReceived");
			 
			 var p = this.getFullPath(_tgBaseScriptService  + ServiceOptions.getTireInfoMethod() + "?securityToken=" + ServiceOptions.getSecurityToken()
			 + "&year=" + encodeURIComponent(year) + "&make=" + encodeURIComponent(make) + "&model=" 
			 + encodeURIComponent(model) + "&option=" + encodeURIComponent(option)+ "&base64Hostname=" + encodeURI(base64Hostname) + "&scriptId=" + encodeURI(ServiceOptions.getPlaceHolderScriptName()),callback);//"dataReceiver.tireInfoReceived");
			  
            tireInfoRequestObject = new JSONScriptRequest(p);
            tireInfoRequestObject.buildScriptTag();
            tireInfoRequestObject.addScriptTag();      
    }            
}
//END Fetch

//Begin ServiceOptions//
var ServiceOptions = {

	getSecurityToken : function(){			
		if(typeof ti_security_token == _ud)
			throw "Security Token Is Required";

		if (Validate.isValidSecurityToken(ti_security_token)) 
			return ti_security_token;		
		else 
			throw "Invalid Security Token";
	},
	getReturnURL : function(){
		if(typeof ti_return_url != _ud)
			return ti_return_url;
		else
			return "";
	},
	getReturnTextAreaId : function(){
		if(typeof ti_return_text_area_id != _ud)
			return ti_return_text_area_id;
		else
			return "";
	},
	getMode : function(){
		if(typeof ti_mode != _ud)
			return ti_mode;
		else
			return "default";		
	},
	getPlaceHolderScriptName : function(){
		if(typeof ti_placeholder_script_id != _ud)
			return ti_placeholder_script_id;
		else
			return "scriptTireInfo";
	},
	getYearsMethod: function(){
		return "GetAvailableYears"
	},
	getMakesMethod:function(){ return "GetAvailableMakes"},
	getModelsMethod:function(){ return "GetAvailableModels"},
	getOptionsMethod:function(){ return "GetAvailableOptions"},
	getTireInfoMethod:function(){ return "GetOEDataCollection"}	
}
//End ServiceOptions//

//PopupVariables//
var PopupVariables = {
	getPopupButtonText: function(){
		if(typeof ti_popup_button_text != _ud)
			return ti_popup_button_text;
		else return "Click Here";
		},
	getPopupHeaderText: function(){
		if (typeof ti_popup_header_text != _ud) 
			return ti_popup_header_text;
		else {
			return GetDefaultTireSelectorHeaderText();
		}
	},
	getPopupHeaderFontColor:function(){
		return (typeof ti_popup_header_text_font_color == _ud) ? "White" : ti_popup_header_text_font_color;
	}		
}
/////


//Text Content Methods//
function GetDefaultTireSelectorHeaderText()
{
	switch(StyleOptions.getLanguage().toLowerCase())
	{
		case "french":
			return "Sélecteur de pneus";
		default:
			return "Tire Selector";
	}
}

function GetYearSelectHeaderText()
{
		switch (StyleOptions.getLanguage().toLowerCase()) {
			case "french":
				return "Choisissez l’année";
			default:
				return "Select A Year";
		}
}

function GetMakeSelectHeaderText()
{
		switch (StyleOptions.getLanguage().toLowerCase()) {
			case "french":
				return "Choisissez la marque";
			default:
				return "Select A Make";
		}
}

function GetModelSelectHeaderText()
{
		switch (StyleOptions.getLanguage().toLowerCase()) {
			case "french":
				return "Choisissez le modèle";
			default:
				return "Select A Model";
		}
}

function GetOptionSelectHeaderText()
{
		switch (StyleOptions.getLanguage().toLowerCase()) {
			case "french":
				return "Choisissez la version";
			default:
				return "Select an Option";
		}
}

function GetCloseButtonText(){
	
	switch (StyleOptions.getLanguage().toLowerCase()) {
		case "french":
			return "Fermer";
		default:
			return "Close";
	}
}

function GetTireSizeColumnHeaderText(){
	switch(StyleOptions.getLanguage().toLowerCase()){
		case "french":
			return "Taille du pneu";
		default:
			return "Tire Size";
	}
}

function GetTireFitmentColumnHeaderText(){
	switch(StyleOptions.getLanguage().toLowerCase())
	{
		case "french":
			return "Configuration du pneu";
		default:
			return "Tire Fitment";
	}
}
	
//BEGIN DisplayInfoObject//
function DisplayInfoObject()
{
	this.getPageSizeWithScroll = getPageSizeWithScroll;
	this.getViewportSize = getViewportSize;
}
function SizeObject(w,h){
	
	//TODO: The values need to be validated//
	this.width = w + "px";
	this.height = h + "px";
}		
function getPageSizeWithScroll(){
	if (window.innerHeight && window.scrollMaxY) {// Firefox
		yWithScroll = window.innerHeight + window.scrollMaxY;
		xWithScroll = window.innerWidth + window.scrollMaxX;
	}
	else 
		if (document.body.scrollHeight > document.body.offsetHeight) { // all but Explorer Mac
			yWithScroll = document.body.scrollHeight;
			xWithScroll = document.body.scrollWidth;
		}
		else { // works in Explorer 6 Strict, Mozilla (not FF) and Safari
			yWithScroll = document.body.offsetHeight;
			xWithScroll = document.body.offsetWidth;
		}
	arrayPageSizeWithScroll = new Array(xWithScroll, yWithScroll);			
	return arrayPageSizeWithScroll;
};

function getViewportSize(){
 var viewportwidth;
 var viewportheight;

 // the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight

 if (typeof window.innerWidth != 'undefined')
 {
      viewportwidth = window.innerWidth,
      viewportheight = window.innerHeight
 }
 
 // IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)

 else if (typeof document.documentElement != 'undefined'
     && typeof document.documentElement.clientWidth !=
     'undefined' && document.documentElement.clientWidth != 0)
 {
       viewportwidth = document.documentElement.clientWidth,
       viewportheight = document.documentElement.clientHeight
 }
 
 // older versions of IE
 
 else
 {
       viewportwidth = document.getElementsByTagName('body')[0].clientWidth,
       viewportheight = document.getElementsByTagName('body')[0].clientHeight
 }
 return new SizeObject(viewportwidth,viewportheight);			
}
//END DisplayInfoObject//

//Client Info//
function ClientInfoObject(){
	this.isIE = function(){
		if (navigator.appName == "Microsoft Internet Explorer") 
			return true;
		else 
			return false;
	};
	
	this.getFirefoxVersion = function(){
		if (/Firefox[\/\s](\d+.\d+)/.test(navigator.userAgent)) {
			return new Number(RegExp.$1);
		}
		else 
			return null;
	};
	
	getMozillaVersion = function(){
		if (/Mozilla[\/\s](\d+.\d+)/.test(navigator.userAgent)) {
			return new Number(RegExp.$1);
		}
		else 
			return null;
	};
	this.getWebkitVersion = function(){
		if (/AppleWebKit[\/\s](\d+.\d+)/.test(navigator.userAgent)) {
			return new Number(RegExp.$1);
		}
		else 
			return null;
	};
	this.getOperaVersion = function(){
		if (/Opera[\/\s](\d+.\d+)/.test(navigator.userAgent)) {
			var a = new Number(RegExp.$1);
			
			if (/Version[\/\s](\d+.\d+)/.test(navigator.userAgent)) {
				return new Number(RegExp.$1);
			}
			else 
				return a;
		}
		else 
			return null;
	}
	this.getVersionInteger = function(versionString){
		if (typeof(versionString) != 'string') 
			return null;
		
		var x = versionString.split('.');
		var maj = x[0] | '0';
		var min = x[1] | '0';
		var patch = x[2] | '0';
		
		versionString = String(maj) + String(min) + String(patch);
		return new Number(versionString);
	}
	this.supportsRGBATransparency = function(){
	
		if (this.isIE()) 
			return false;
		
		var v = this.getFirefoxVersion();
		
		if (v != null) {
		
			if (this.getVersionInteger(v.toString()) >= 305) 
				return true;
			else 
				return false;
		}
		
		//If webkit version exists must be safari/khtml/Chrome ??? and should work//
		v = this.getWebkitVersion();
		if (v != null) 
			return true;
		
		v = this.getOperaVersion();
		
		if (v != null) {
		
			if (this.getVersionInteger(v.toString()) >= 1000) 
				return true;
			else 
				return false;
		}
		return false;
	}
};
	




	
///////End ClientInfoObject

//Start//
/*
(function starter(){
	runInit();
})();
function runInit(){
	
	//if (!clientInfo.isIE()) {
		if (document.body)
			init(); 			
		else 
			setTimeout("runInit()", 100);
	//}
	//else		
		//document.body.onload = init;
}
*/


function init(){		
	if(!this.JSON)
		loadJSON();
		
	if(_debug){
		if(clientInfo.isIE()){
			if(_showFirebug){
				loadFirebug();
			}
		}
	}
	
	
	var div = null;	
	var vp =  displayInfoObject.getViewportSize();
	
			
	var divContainer = document.getElementById(ServiceOptions.getPlaceHolderScriptName()).parentNode;
	_parentContainer = divContainer; 	
	
	if (ServiceOptions.getMode() == "default") {
		var layout = getInlineLayout();			
		divContainer.appendChild(layout);
		SelectChangeHandlers.handleSelectedItemChanged();		
		fetch.years("DataReceiver.yearsReceived");
	}
	else {
		if (clientInfo.isIE()) {
			div = getIEMaskDiv(vp);
		}
		else 
			if (clientInfo.getWebkitVersion() == null) {
				div = getCanvasMaskDiv(vp);
			}
			else {
				div = getWebkitMaskDiv(vp);
			}
			
		var d = getPopupLayout();
		
		div.style.display = d.style.display = "none";
						
		document.body.appendChild(div);
		document.body.appendChild(d);
				
		divContainer.appendChild(getPopupButton());
		
		SelectChangeHandlers.handleSelectedItemChanged();
		fetch.years("DataReceiver.yearsReceived");
	}

}

