//Hank's Helper Main Interface JS
//Copyright Nathan Stretch (craigshelper.com)

//Window Functions
window.onresize = resize;
window.onscroll = resize;

//Variable declarations
var tabstop = 1,
currentTab = 0,
currentTab2 = 'welcome',
Tabs = new Array(),
//***Remember this must match sitecodes in sitecodes.php
Sitenames = { eb: 'Ebay Motors', at: 'AutoTrader.Com', cc: 'Cars.Com', ac: 'Automotive.Com' , cd: 'CarsDirect.Com' , oo: 'Oodle.Com' , cl: 'Craigslist.org' },
cdchecked=0,
ebchecked=0,
makecookie='',
modelcookie='',
focused='makemodel',

siteboxes_all = new Array('l_eb','l_cd','m_cl','l_at','m_oo','l_cc','l_ac'),
siteboxes_rec = new Array('l_eb','l_cd','m_cl','l_at','l_cc'),
siteboxes_ebcl = new Array('l_eb','m_cl'),
siteboxes_large = new Array('l_eb','l_at','l_cc','l_ac','l_cd'),
siteboxes_mash = new Array('m_cl','m_oo'),
siteboxes_niche = new Array(),

bodystyles = new Array('convertible', 'coupe', 'hatchback', 'minivan', 'sedan', 'suv', 'truck', 'van', 'wagon'),

tooltips,
modelSlider,
theseModels, //array of the models for the currently chosen make
oldhash; //for tracking when hash changes (ie user presses back button or opens up a new hank's bookmark while viewing hankshelper)

window.addEvent('domready',function(){
	init();
});


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// KEYPRESS LISTENER
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//submits form when enter key pressed
window.addEvent('keydown', function(e) {
	if (e.key=='enter') { //Enter key pressed
		checkForm();
	}
});

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//MAKE OBJECT CLASS
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function Model (args) 
{
	this.name = args[0];
	this.id = args[1];
	this.listed = new Object;

	for (var siteid in Sitenames)
	{
		if (args[2][siteid] == 1) {
			this.listed[siteid] = 1;
		} else {
			this.listed[siteid] = 0;
		}
	}
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TAB OBJECT CLASS
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var TAB_ARGS = new Array('make', 'model', 'modelkeys', 'minyear', 'maxyear', 'minprice', 'maxprice', 'minmiles', 'maxmiles', 'radius', 'zip', 'inclus', 'keywords'),
HIDDEN_TAB_ARGS = new Array('body', 'prefbody', 'saleby', 'trans');
var Tab = new Class({
	initialize: function(num, site){
		var i, arg;

		this.site = site;
		for (i=0; i<TAB_ARGS.length; i++)
		{
			arg = TAB_ARGS[i];
			this[arg] = $(arg).value; //this notation is like writing this.arg, but lets us use a variable - ie in JS, dot notation is the same as array notation
		}
		for (i=0; i<HIDDEN_TAB_ARGS.length; i++)
		{
			arg = HIDDEN_TAB_ARGS[i];
			this[arg] = $('hid_'+arg).value; //this notation is like writing this.arg, but lets us use a variable - ie in JS, dot notation is the same as array notation
		}

		if (num != 'newwin') {
			this.tabdiv = new Element('div', {'id': 'tabdiv'+num, 'class': 'tabdiv', styles: {width: '100%'}}).injectInside($('hankdiv'));
			this.frame = new Element('iframe', {'id': 'hankframe'+num, 'name': 'hankframe'+num, styles: {width: '100%', height: 0, border: 0, display: 'block'}}).injectInside(this.tabdiv);
		}
	},
	
	getargs: function() {
		var i, ref = '',
		args = TAB_ARGS.concat(HIDDEN_TAB_ARGS);
		for (i=0; i<args.length; i++)
		{
			ref += '&'+args[i]+'='+escape(this[args[i]]);
		}
		return ref;
	},
	
	doload: function() {
		var targ = arguments[0],
		browse, ref, tabd, notice, i;

		if (navigator.appName=="Microsoft Internet Explorer") {
			browse='ie';
		} else {
			browse='other';
		}
		
		ref = 'site='+this.site;
		ref += this.getargs();
		ref += '&targ='+targ+'&browse='+browse;

		if (targ == 'win' || !this.frame) {
			window.open('./results.php?'+ref);
		} else {
			// if (this.site == 'cd' && cdchecked == 0){
				// notice = "<div id=\"cdnotice\" style=\"clear:left;margin:10px;margin-top:0;display:none\"><span style=\"font-size:large;color:red;background-color:inherit;\"><span style=\"font-weight:bold;\">Note</span>: ";
				// notice += "I have decided to include CarsDirect in HanksHelper because it is one of the bigger cars sites out there; however, their method for filtering by year, mileage, etc, is a bit messed up.  If you find no filtering is done at all, try refreshing the tab by pressing <img src='images/refresh1.jpg' /> above. Click <a href='faq.php#carsdirect'>here</a> for more info.</span><br /> ";
				// notice += "<input type=\"checkbox\" name=\"cdclearnotice\" id=\"cdclearnotice\" value=\"1\" onclick=\"clearnotice1('cd');\" /><label for=\"cdclearnotice\" id=\"cdcbtext\" style=\"font-size:small\">Don't&nbsp;show&nbsp;notice&nbsp;again</label></input></div>";
				// } else if (this.site == 'eb' && ebchecked == 0){
				// notice = "<div id=\"ebnotice\" style=\"clear:left;margin:10px;margin-top:0;display:none\"><span style=\"font-size:large;color:red;background-color:inherit;\"><span style=\"font-weight:bold;\">Note</span>: ";
				// notice += "eBay does not allow their car ads to be opened in frames - therefore if you just click on an ad, you will lose your other results.  Instead, <a href=\"helpme.php#tips\">middle-click to open ads in new tabs!</a></span><br /> ";
				// notice += "<input type=\"checkbox\" name=\"ebclearnotice\" id=\"ebclearnotice\" value=\"1\" onclick=\"clearnotice1('eb');\" /><label for=\"ebclearnotice\" id=\"ebcbtext\" style=\"font-size:small\">Don't&nbsp;show&nbsp;notice&nbsp;again</label></input></div>";
			// } else {
				notice = "";
			// }

			if (this.site == 'go') {
				this.frame.set('src', "./goog.php");
			} else {
				this.frame.set('src', "./results.php?"+ref);
			}
		}
	},
	
	seturl: function() {
		oldhash = location.hash = '?' + this.getargs().slice(1);
	},
	
	remove: function() {
		this.tabdiv.destroy();
	}
});


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//COOKIES, other UTILITY FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function setcookie60(name, value) {
	Cookie.write(name, value, {duration: 60});
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//CATEGORY SELECTION AND OTHER SHOW/HIDE
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function clearBox(element) {
	if (element.value == "Enter optional keywords...") {
		element.value = "";
	}
}

function unClearBox() {
	d = $('keywords');
	if (d.value == '') {
		d.value = "Enter optional keywords...";
	}
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//SELECTION BOX POPULATION
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function init()
{
	unClearBox();
	
	//Have to set up the model slider before loadmodels (technically before the loadmodels ajax callback, but safer to just get it done first)
	//loadmodels uses the show/hide nature of the slider to tell whether to show it.  (Because normally we wouldn't show until a model is chosen.)
	//basically just saves doing this if statement again in load models if it's called from init
	modelSlider = new Fx.Slide('modelkeysdiv',{mode:'vertical',duration:150});
	if ($('modelkeys').value == '' && modelcookie == '') {
		modelSlider.hide();
	}
	$('modelkeysdiv').setStyle('display','block');

	loadmakes();

	if ($('site').value != 'custom') sitechanged('init'); //to set the hidden fields - if it's custom they're already stored in cookies

	checkcookies();
	
	tooltips = new Tips('.toolTip',{'className':'tip-wrap'});
	
	zipblurred();
	
	var checkhash = function() {
		var newhash = location.href.slice(location.href.indexOf('#')+1);
		if (location.hash.length > 0 && newhash != oldhash) {
			console.log('n'+newhash);
			console.log('o'+oldhash);
			location.href = './'+newhash;
		}
	}
	checkhash.periodical(500);
}

function checkcookies()
{
	Cookie.write('test',1);
	if(Cookie.read('test') != 1) {
		$('nocookies').style.display='block';
	}
	Cookie.dispose('test');
}

function loadmakes() {
	var box = $('make'),
	i, jsonRequest;

	jsonRequest = new Request.JSON({url: "getMakes.php", onSuccess: function(makes){
		for (i=0; i < makes.length; i++)
		{
			//index 0 is name, index 1 is id
			box.options[i+1] = new Option(makes[i][0], makes[i][1]);
			if (makecookie == makes[i][1]) {
				box.selectedIndex = i+1;
			}
		}

		loadmodels('init');

	}}).send();
}

function loadmodels() {
	var makebox = $('make'),
	box = $('model'),
	make = makebox.value,
	models, site, j, oldmodel, selectedsites,  mod, i, flag, add, k, jsonRequest, calledby,
	checkRunFn;
	
	calledby=arguments[0];
	
	//this function is defined internally here so we can reuse the code and it can make use of the local variables of the loadmodels function
	checkRunFn = function() {
		//If the page has just loaded and the runsearch cookie is set (because we've opened a bookmark with arguments), run the search
		if (calledby == 'init' && Cookie.read('runsearch')) {
			Cookie.dispose('runsearch');
			checkForm();
		}
	}

	if (make == '') {
		box.options.length=0;
		box.options[0] = new Option("Any Model", '');
		$('modelkeys').value = '';
		checkRunFn();
		return false;
	}

	jsonRequest = new Request.JSON({url: "getModels.php", onSuccess: function(models){
		theseModels = new Array();
		for (i=0; i < models.length; i++)
		{
			theseModels[i] = new Model(models[i]);
		}
	
		models = theseModels;
		
		site = $('site').value;
		j=1;
		
		if (calledby=='init') {
			oldmodel = modelcookie;
		} else {
			oldmodel = box.value;
		}
		
		//create an array of all the sites we're searching
		selectedsites = new Array();
		if (site != 'custom') {
			selectedsites = eval('siteboxes_'+site);
		} else {
			for (i=0; i<siteboxes_all.length; i++)
			{
				if ($('hid_site_'+siteboxes_all[i]).value != 0) {
					selectedsites.push(siteboxes_all[i]);
				}
			}
		}
		
		//loop through all available models for this make, and check if any of the sites we're searching (above) includes that model.  If so, add it to the box
		//flag is set if we find the old model id in the new list of models (and therefore set it to selected)
		flag=0;
		for (i=0; i < models.length; i++)
		{
			add = 0;
			if (i==models.length-1 || site == 'all' || $('hid_site_m_cl').value != 0 || $('hid_site_l_eb').value != 0) {
				add = 1; //if i==models.length-1, this is the 'All Acura Models' or whatever model, so always add
				//if craigslist or ebay selected, we can search for anything , so include all models, ditto if we've chosen 'all sites'
			} else {
				for (k=0; k<selectedsites.length; k++)
				{
					if (models[i].listed[selectedsites[k].substr(2)] == 1) {
						add = 1;
						break;
					}
				}
			}
			
			//add the model to the box
			if (add == 1) {
				box.options[j] = new Option(models[i].name, models[i].id);
				if (oldmodel == models[i].id) {
					flag = 1;
					box.selectedIndex = j;
				}
				j++;
			}
		}
		//clear the rest of the box if the list shrunk in length
		while (j<box.options.length)
		{
			box.options[j] = null;
		}
		
		//if we've just changed the site and the old model is no longer in the list, need to tell user why it's no longer selected
		//this will be removed once we set up alt models
		if (flag == 0 && calledby == 'sitechanged') {
			mod = 0;
			for (i = 0; i < models.length; i++)
			{
				if (models[i].id == oldmodel) {
					mod = models[i];
					break;
				}
			}
			if (mod != 0) {
				alert('The model you had selected ('+mod.name+') is not listed in any of the new assortment of sites.  Please choose a new model.\n\nNote: Some models are listed by different names on different sites.  IE: look for BMW 330 as well as 330i, 3-series, etc.');
			}
		}
		
		modelinfo();

		//when we first select a make, don't show the keywords, as it'll be confusing.  (Wait until a model is chosen.)  But if they're already showing, might as well update them with the new make.
		//in init, it decides whether to show the box based on whether there's a model or model keys saved.  If so, when we call loadmodels in init, we'll do this.
		if (modelSlider.open) {
			getModelKeys();
		} else {
			$('modelkeys').value = '';
		}

		checkRunFn();
	}}).get({'make': make});
}

function makeChanged() {
	loadmodels('makechanged');
}

function modelChanged() {
	modelinfo();
	getModelKeys();
}

function getModelKeys() {
	var myRequest = new Request({method: 'post', url: 'modelkeys.php', onSuccess: function(val) {
		setcookie60('modelkeys', val);
		setcookie60('make', $('make').value);
		setcookie60('model', $('model').value);
		$('modelkeys').value = val;
		modelSlider.slideIn();
	}});
	myRequest.send('make='+escape($('make').value)+'&model='+escape($('model').value));
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//FORM VALIDATION
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ZIP/DISTANCE STUFF
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//this calls zipblurred to show the checkbox when the user has finished typing in the thing.
function zippressed()
{
	var zip = $('zip').value.replace(/[^0-9A-Za-z]/g,"");
	if(zip.charAt(0)>=0 && zip.charAt(0)<=9) {
		if (zip.length == 5) {
			zipblurred();
			return(0);
		}
	} else {
		if (zip.length == 6) {
			zipblurred();
			return(0);
		}
	}
}

//Called when user finishes entering a zip or postal code
function zipblurred(mode)
{
	var zip = $('zip').value.replace(/[^0-9A-Za-z]/g,""),
	show=0;
	
	if (zip.match(/^[0-9][0-9][0-9][0-9][0-9]$/)) {
		//show crossborderdiv
		show='zip';
	} else if (zip.match(/^[a-zA-Z][0-9][a-zA-Z]\s?[0-9]?[a-zA-Z]?[0-9]?\s*$/)) {
		//show crossborderdiv
		show='postal';
	}
	
	if (show == 'postal') {
		$('inclusdiv').setStyle('display','block');
		if (!Cookie.read('gotpostal')) {
			if ($('site').value != 'ebcl') {
				$('site').value = 'ebcl';
				alert('Please note: Only Craigslist and eBay support Canadian postal codes at this point.  Hankshelper has been automatically set to search these two sites.  To search other sites, please enter a US zip code.');
			}
			Cookie.write('gotpostal',1);
		}
	} else if (show == 'zip') {
		$('inclusdiv').setStyle('display','none');
		Cookie.dispose('gotpostal');
	}
}

//checks that all necessary fields are filled, then opens results tabs
function checkForm()
{
	var zip, site, minp, maxp, minm, maxm, totab, individual, selectedsites, showsites,
	flag, args, arg, i, mods, modid, mod, j, siteid, tabnum;
	
	$('zip').value = $('zip').value.replace(/[^A-Za-z0-9]/g, ""); //remove all unwanted characters from zip or postal

	var zip = $('zip').value;

	if (zip == '' && $('zipstar').style.display == 'none') {
		$('zipstar').setStyle('display','inline');
		return false;
	}
	
	//zip/distance mode
	if (zip.match(/^[a-zA-Z][0-9][a-zA-Z]\s?[0-9]?[a-zA-Z]?[0-9]?\s*$/)) {
		$('site').value = 'ebcl';
		Cookie.write('gotpostal',1);
	} else if (!zip.match(/^[0-9][0-9][0-9][0-9][0-9]$/)) {
		$('zipstar').setStyle('display','inline');
		alert('Please enter a valid US Zip Code or Canadian Postal Code.');
		return false;
	} else {
		Cookie.dispose('gotpostal');
	}
	$('zipstar').setStyle('display','none');

	clearBox($('keywords'));

	if (arguments[0]) {
		site = arguments[0];
	} else {
		site = $('site').value;
	}

	minp = $('minprice').value;		
	maxp = $('maxprice').value;
	
	if (minp != 'Any' && isNaN(minp)) {
		alert('Sorry, the minimum price ($'+minp+') is not a recognized number.\nPlease enter a numeric price (ie: 5000).');
		return false;
	}    

	if (maxp != 'Any' && isNaN(maxp)) {
		alert('Sorry, the maximum price ($'+maxp+') is not a recognized number.\nPlease enter either a number (ie: 5000) or "Any".');
		return false;
	}

	if (minp=='' || minp == 'Any') {
		minp = 0;
	}

	if (maxp=='') {
		maxp = 'Any';
	}

	if (maxp != 'Any' && parseInt(minp) > parseInt(maxp)) {
		alert('The minimum price ($'+minp+') is greater than the maximum price ($'+maxp+').');
		return false;
	}    

	maxm = $('maxmiles').value;
	minm = $('minmiles').value;
	
	if (maxm != '' && parseInt(maxm) < parseInt(minm)) {
		alert('The minimum mileage ('+minm+') is greater than the maximum mileage ('+maxm+').');
		return false;
	}    

	rad = $('radius').value;

	if (!(rad > 0 && rad < 100000) && rad != 'any') {
		alert('Please enter a numeric value for the distance from your zip code.');
		return false;
	}

	totab = tabstop;
	individual = 0;
	selectedsites = new Array();
	showsites = new Array();

	//determine which sites are selected to search
	if (Cookie.read('gotpostal')) {
		selectedsites[0] = 'm_cl'; //***hack to only search CL in canada mode
	} else if (site == 'all' || site == 'rec' || site == 'ebcl') {
		selectedsites = eval('siteboxes_'+site);
	} else if (site == 'custom') {
		flag = 0;
		for (i=0; i<siteboxes_all.length; i++)
		{
			if ($('hid_site_'+siteboxes_all[i]).value != 0) {
				flag = 1;
				selectedsites.push(siteboxes_all[i]);
			}
		}
		if (flag == 0) {
			alert('You have chosen \'Custom Selection...\' from the \'Sites to Search\' dropdown, but no sites have been selected in the dialog.\n\nPlease select a group of sites using the dropdown, or click the \'More Options\' link to choose individual sites.');
			return false;
		}
	} else {
		showsites[0] = site;
		individual = 1;
	}

	//Save cookies

	//All values entered in the main form are saved here
	//Anything entered in the more options box is stored when it is comitted.
	//Also make model and modelkeys are saved when the model dropdown is changed.
	//but should be set here as well, to prevent the cookies from expiring and in case they model keywords have been changed manually
	setcookie60('site', $('site').value);
	
	for (i=0; i<TAB_ARGS.length; i++)
	{
		arg = TAB_ARGS[i];
		setcookie60(arg, $(arg).value);
	}
	
	//if we're not only showing one site (by clicking its icon in the model info box)
	//need to make a list of sites to search based on the sites selected to search
	//only actually search the ones that include the model being searched for.  Also need to modify the codes, since selected sites have the l_ m_ etc prefix
	//to tell which category they're in, but when we search them, we only care about their id itself, without prefix.
	
	//if we're only searching one site, none of this is necessary - the site to show is already set above
	if (individual == 0) {
		if ($('make').value == "") {
			for (i=0; i<selectedsites.length; i++)
			{
				showsites[i] = selectedsites[i].substr(2); //remove the l_ (or whichever category) from the start to get just the ie "eb"
			}
		} else {
			mods = theseModels;
			modid = $('model').value;
			
			mod = 0;
			//this is because in javascript (for now) makes and models are stored as simple number-indexed arrays instead of objects
			//change to objects and only get one at a time, using ajax + json - search for 'makes[' ***
			for (j = 0; j < mods.length; j++)
			{
				if (mods[j].id == modid) {
					mod = mods[j];
					break;
				}
			}
			
			if (j == mods.length) {
				j--;
				mod = mods[j];  //if model not found, set to "Other X Models" at end of list
			}
			
			//Only open the sites for which the selected model exists
			for (i=0; i<selectedsites.length; i++)
			{
				siteid = selectedsites[i].substr(2); //remove the l_ (or whichever category) from the start to get just the ie "eb";
				//if j = length-1, it's the last model (Other Buick Models) - open it in all sites
				//also always show craigslist and ebay since we can search the model using keywords if we don't have a code for it
				if (mod && mod.listed[siteid] == 1 || j==mods.length-1 || siteid=='cl' || siteid=='eb') showsites.push(siteid); 
			}
		}
	}
	
	//Open the actual tabs.  Slight delay between each one
	//OpenTab decides whether to reuse a tab (if that option is set) or to open a new one
	//either way, returns the index of the tab opened.
	tabnum = openTab(showsites[0]);
	for (i=1;i<showsites.length;i++)
	{
		setTimeout('openTab("'+showsites[i]+'");', 1000*i);
		//openTab(showsites[i]);
	}

	setScroll(0);  
	//if we're opening in tabs (not in new windows - configuration setting), open the first tab (whose index we got from above)
	//for the first search this will always be the first tab, but in subsequent searches if only some sites are searched again or if tabs
	//aren't reused, it might be different
	if ($('hid_whereOpen').value != 'win') {
		tabsel(tabnum);
	}
	
	//Add parameters to URL
	Tabs[tabnum].seturl();
	
	return false;
}


function yearchanged(which) 
{
	var miny = $('minyear').value,
	maxy = $('maxyear').value;

	if (miny != 'any' && maxy != 'any') {
		if (which == 'min' && maxy < miny) {
			maxy=miny.value;
		} else if (which == 'max' && maxy < miny) {
			miny=maxy;
		}
	}
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TAB FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function openTab(site)
{
	if ($('hid_whereOpen').value=='win') {
		Tabs['newwin'] = new Tab('newwin', site);
		Tabs['newwin'].doload('win');
		return('newwin');
	} else if ($('hid_reuse').value==1) {
		return(repTab(site));
	} else {
		return(addTab(site));
	}
}

function genTopTabs()
{
	var tabtext = '';
	var disp;

	for (var i=1;i<Tabs.length;i++)
	{

		if(Tabs[i]) {
			var un = "un";
			disp = "none";
			if (currentTab == i) {
				un = "";
				disp = "inline";
			}
			//hack because we loop through this array elsewhere
			Sitenames['go'] = 'Google';
			tabtext += '<li class="tab '+un+'selectedtab_l"/><li id="tab'+i+'" class="tab '+un+'selectedtab" style="display: block;"><img id="refresh'+i+'" src="images/refresh1.jpg" onclick="refresh('+i+');" style="float:left;margin:3px -4px -4px 3px;display:'+disp+'" alt="Refresh" title="Refresh" /><span id="tab'+i+'_title" onclick="tabsel(\''+i+'\');">'+Sitenames[Tabs[i].site]+'</span><img id="newwin'+i+'" src="images/newwin.bmp" onclick="newwin('+i+');" style="display:'+disp+';margin:3px 3px -1px -4px;" onmouseover="mouseover(\'newwin\', '+i+')" onmouseout="mouseout(\'newwin\', '+i+')" alt="Open in New Window" title="Open in New Window" /><img id="close'+i+'" src="images/close.bmp" style="display:'+disp+';margin:3px 3px -1px 0;" onmouseover="mouseover(\'close\', '+i+')" onmouseout="mouseout(\'close\', '+i+')" onclick="remTab('+i+')" alt="Close" title="Close" /></li><li class="tab '+un+'selectedtab_r"/>';
			delete(Sitenames['go']);
		}
	}

	var un = "un";
	if (currentTab == 0) un = "";

	disp = 'none';
	if (tabtext != '') disp = 'inline';

	var tabspace = $('tabspace');
	var writein ='<li class="tab leftspace"></li><li class="tab '+un+'selectedtab_l" /><li id="tab0" class="tab '+un+'selectedtab" style="display: block;">';
	writein += '<span id="search_tab_title" title="Search" onclick="tabsel(0);">Search Parameters</span></li><li class="tab '+un+'selectedtab_r" />';
	writein += '<li class="tab spacer" />';
	writein += tabtext;
	writein += '<li class="tab spacer" /><li id="addtab" class="tab unselectedtab"><span class="tabstar" onclick="startab()">*</span></li><li class="tab spacer" /><li id="tab_closeall" class="tab addtab" style="display:'+disp+'"><a class="toptext" style="font-weight:bold;" onclick="closeall();return false;" href="#">&lt;&lt; Close All</a></li><li id="addstuff" class="tab"></li>';

	tabspace.innerHTML = writein;
}

function mouseover(button, num) {
	$(button+num).src="images/"+button+"over.bmp";
}

function mouseout(button, num) {
	$(button+num).src="images/"+button+".bmp";
}

function addTab(site) 
{
	Tabs[tabstop] = new Tab(tabstop, site);
	Tabs[tabstop].doload(); //using Tabs array

	//easiest to just recreate all the top tabs from the tabs array when we need a new one
	genTopTabs();

	var tabstopold = tabstop;
	tabstop++;
	$('tab_closeall').style.display='inline'; 
	return(tabstopold); //return the id of the newly created tab (which was the old tab stop)
}  

function repTab(site) 
{
	for (var i=1;i<tabstop;i++)
	{
		if (Tabs[i] && Tabs[i].site && Tabs[i].site == site) {
			break;
		}
	}

	if (i == tabstop) {
		return(addTab(site));
	}  

	Tabs[i].remove();
	Tabs[i] = new Tab(i, site);
	Tabs[i].doload();

	return(i); //return the id of the replaced tab
}  

function remTab(num) 
{
	//find the next tab in the list to show - if there isn't one, find the previous one
	var showtab=0;
	for (i=num+1;i<Tabs.length;i++)
	{
		if(Tabs[i]) {
			showtab = i;
			break;
		}
	}
	if (showtab == 0) {
		for (i=num-1;i>0;i--)
		{
			if(Tabs[i]) {
				showtab = i;
				break;
			}
		}
	}

	tabsel(showtab);

	Tabs[num].remove();
	Tabs[num] = null;
	resize(); //need a resize here to fix an ie bug where it leaves a small margin where the removed frame was

	genTopTabs();

}  

function closeall() {
	tabsel(0);
	tabstop = 1;
	currentTab = 0;
	Tabs = new Array();
	$('hankdiv').innerHTML='';
	genTopTabs();
}

////////////////////////////////////////////////////////////////////////////////
//WINDOW MANAGEMENT FUNCTIONS
////////////////////////////////////////////////////////////////////////////////
function clearnotice1(which) {
	var cb = $(which+'clearnotice');
	var cbtext=$(which+'cbtext');
	if (cdchecked==0 && which == 'cd' || ebchecked == 0 && which == 'eb') {
		if (which == 'cd') cdchecked=1;
		else ebchecked=1;
		cbtext.innerHTML="<a href=\"#\" onclick=\"clearnotice2('"+which+"');return false;\">Click to Confirm</a>";
	} else {
		if (which == 'cd') cdchecked=0;
		else ebchecked=0;
		cbtext.innerHTML="Don't&nbsp;show&nbsp;notice&nbsp;again";
	}
}
function clearnotice2(which) {
	setcookie60(which+'notice','1'); 

	var nt = $(which+'notice');
	nt.style.display = "none";
}


function getScroll()
{
	//Determines how far down the page is scrolled
	var extra;
	if (document.documentElement && document.documentElement.scrollTop) {
		extra = document.documentElement.scrollTop;
		//if (extra>maxScroll) document.documentElement.scrollTop=maxScroll;
		
	} else if (document.body && document.body.scrollTop) {
		extra = document.body.scrollTop;
	} else if (window.pageYOffset) {
		extra = window.pageYOffset;
	} else {
		extra = 0;
	}
	return (extra);
} 

function setScroll(extra)
{
	if (window.scrollTo) {
		window.scrollTo(0,extra);
		resize();
		if (getScroll() != extra) setScroll(extra);
	}
}

function refresh(num)
{
	tabsel(0);
	Tabs[num].doload();
	tabsel(num);
}

function newwin(num)
{
	Tabs[num].doload('win');
}

function tabsel(tabnum)
{
	if (tabnum == currentTab) {
		return 0;
	}

	var ct, nt, hd, theHeight, theBorder, rightBorder;

	if (currentTab == 0) {
		ct = $('bigtable');
	} else {
		ct = $('hankframe'+currentTab);
	}

	hd = $('hankdiv');
	if (tabnum == 0) {
		nt = $('bigtable');
		hd.style.padding = '0px';
	} else {
		nt = $('hankframe'+tabnum);
		hd.style.padding = '10px';
	}

	theHeight = ct.style.height;
	nt.style.height = theHeight; //temporary to keep page from shrinking and
	//scrolling to the top.  Resize will fix.
	ct.style.height = '0px';

	if (currentTab == 0) ct.style.display='none';

	if (tabnum == 0){
		nt.style.display='block';
		nt.style.height="100%";
	}

	// var cdnote=$('cdnotice');
	// if (cdnote && cdnote.style.display) {
		// if (Tabs[tabnum] && Tabs[tabnum].site == 'cd' && cdchecked == 0) {
			// cdnote.style.display='block';
		// } else {
			// cdnote.style.display='none';
		// }
	// }

	// var ebnote=$('ebnotice');
	// if (ebnote && ebnote.style.display) {
		// if (Tabs[tabnum] && Tabs[tabnum].site == 'eb' && ebchecked == 0) {
			// ebnote.style.display='block';
		// } else {
			// ebnote.style.display='none';
		// }
	// }

	if (tabnum == 0  ) {
		nt.style.display='block';
		nt.style.height="100%";
	}

	theBorder = ct.style.border;
	rightBorder = ct.style.borderRight;
	ct.style.border = 0;
	ct.style.borderRight = 0;
	nt.style.border = theBorder;
	nt.style.borderRight = rightBorder;

	//highlight the proper tab up top
	$('tab'+tabnum).className = 'tab selectedtab';
	$('tab'+currentTab).className = 'tab unselectedtab';


	if (currentTab > 0) {  //if fails, was search tab
		$('refresh'+currentTab).style.display="none";
		$('newwin'+currentTab).style.display="none";
		$('close'+currentTab).style.display="none";
	}

	if (tabnum > 0) {  //if fails, was search tab
		$('refresh'+tabnum).style.display="block";
		$('newwin'+tabnum).style.display="inline";
		$('close'+tabnum).style.display="inline";
	}
	currentTab=tabnum;
	//Actual display of the current Tab happens in resize
	resize();
}

//Select one of the tabs in the welcome/model info/help section - unrelated to the main tabs with results from the sites
function tabsel2(tab)
{
	if (tab == currentTab2) {
		return 0;
	}

	var ct = $(currentTab2+'tab');
	var nt = $(tab+'tab');
	var cd = $(currentTab2+'infodiv');
	var nd = $(tab+'infodiv');

	cd.style.display='none';
	nd.style.display='block';
	nt.className = 'tab selectedtab';
	ct.className = 'tab unselectedtab';

	currentTab2 = tab;
}


/*
* Runs when page is resized or scrolled to put hankframe in the right place
*/
function resize() 
{
	var ct = $('hankframe'+currentTab),
	winSize, theHeight, scrollSize, extra, o, oTop, setHeight;
	
	if (!ct) {
		//alert('No ct error');
		return(-1);
	}

	//Gets the size of the window (contents space)
	winSize = Window.getSize();
	theHeight = winSize.y;

	//Determines how far down the page is scrolled
	scrollSize = Window.getScroll();
	extra = scrollSize.y;

	//oTop is distance from top of frame to top of page
	o = ct;
	oTop = o.offsetTop; // Add parent top position
	while(o.getOffsetParent()!=null) { // Parse the parent hierarchy up to the document element
		o = o.getOffsetParent();  // Get parent object reference
		oTop += o.offsetTop; // Add parent top position
	}

	if (extra <= 60) {
		setHeight = theHeight+extra-oTop-12;
	} else {
		setHeight = theHeight+60-oTop-12;
	}

	setHeight > 0? ct.style.height = setHeight+'px': ct.style.height = '0px';
}

////////////////////////////////////////////////////////////////////////////////
// OTHER / UNSORTED FUNCTIONS
////////////////////////////////////////////////////////////////////////////////

function highlightSelect(boxes, onoff)
{
	var color, boxels;
	if (onoff == 'on') {
		color = '#ddf8cc';
		highlightSelect(focused, 'off');
	} else {
		color = '#ffffff';
	}
	
	focused = boxes; //global to remember which one to turn off next time this is called
	boxels = new Array();
	
	switch(boxes) {
	case 'keys':
		boxels[0] = $('keydiv');
		break;
	case 'makemodel':
		boxels[0] = $('makediv');
		boxels[1] = $('modeldiv');
		boxels[2] = $('modelkeysdiv');
		boxels[3] = $('missingmodel');
		break;
	case 'year':
		boxels[0] = $('minyeardiv');
		boxels[1] = $('maxyeardiv');
		break;
	case 'price':
		boxels[0] = $('minpricediv');
		boxels[1] = $('maxpricediv');
		break;
	case 'miles':
		boxels[0] = $('minmilesdiv');
		boxels[1] = $('maxmilesdiv');
		break;
	case 'zip':
		boxels[0] = $('zipdiv');
		boxels[1] = $('inclustr');
		break;
	case 'search':
		boxels[0] = $('searchdiv');
		break;
	case 'options':
		boxels[0] = $('opsdiv');
		break;
	default:
		alert('error highlighting');
		return;
	}

	for (var i=0; i<boxels.length; i++)
	{
		boxels[i].style.backgroundColor=color;
	}
}

//when the user clicks the 'star' to open a google tab
function startab()
{
	addTab('go');
	tabsel(tabstop-1);
}

function modelinfo()
{
	var make = $('make').value,
	mt = $('modeltab'),
	modcode, modid, ms, mods, mod, i, picname;
	
	if (make == "") {
		if (currentTab2 == 'model') tabsel2('welcome');
		mt.style.display='none';
		return false;
	}

	mt.style.display='block';
	$('makespan').innerHTML = $('make').options[$('make').selectedIndex].text;

	modid = $('model').value;
	ms = $('modelspan');

	if (modid == "") {
		ms.innerHTML = "None Selected";
		for (siteid in Sitenames)
		{
			$(siteid+'pic').style.display='none';
		}
		$('nomodels').style.display='inline';
		return true;
	}

	mods = theseModels;

	mod = 0;
	for (i = 0; i < mods.length; i++)
	{
		if (mods[i].id == modid) {
			mod = mods[i];
			break;
		}
	}

	if (mod==0) {
		ms.innerHTML = "Model Error!  Please Contact Webmaster.";
	} else {
		ms.innerHTML = mod.name;
		$('nomodels').style.display='none';
		for (siteid in Sitenames)
		{
			if (siteid == 'cl' || siteid == 'eb' || mod.listed[siteid] == 1 || i==mods.length-1) { //always show craigslist
				picname = siteid+'pic';
				$(picname).style.display='inline';
			} else {
				$(siteid+'pic').style.display='none';
			}
		}
	}

	tabsel2('model');

}

function sitechanged()
{
	var to = $('site').value;
	if (Cookie.read('gotpostal') && to != 'ebcl') {
		to = $('site').value = 'ebcl';
		alert('Please note: Only Craigslist and eBay support Canadian postal codes at this point.  Hankshelper has been automatically set to search these two sites.  To search other sites, please enter a US zip code.');
	}
	
	if (to != 'custom') {
		for (var i=0; i<siteboxes_all.length; i++)
		{
			$('hid_site_'+siteboxes_all[i]).value=0;
		}

		var boxes = eval('siteboxes_'+to);
		for (var i=0; i<boxes.length; i++)
		{
			$('hid_site_'+boxes[i]).value='checked';
		}
		if (arguments[0] != 'init') loadmodels('sitechanged');
	} else {
		showModal();
		switchtab('sitestosearch');
	}
}