
// javascript functions go here

var allPopOuts = new Object();

function superPopOut(id)
{
	var omnitureOnClickDescription = "Download selector";
	omniture_OnClickLogProps(omnitureOnClickDescription, "o", {prop29: omnitureOnClickDescription, evar23: omnitureOnClickDescription}, "event28");
	
	var el = document.getElementById(id);
	
	if(!allPopOuts[id])
	{
		new UvumiDropdown(id, {duration: 100, delay: 50});
		
		allPopOuts[id] = true;
	}
}

// "filteredTable" class

var filteredTable_allTables = new Object();

function filteredTable_New(id)
{
	var ft = new filteredTable(id);
	
	filteredTable_allTables[id] = ft;
	
	return ft;
}

function filteredTable(id)
{
	// methods
	
	this.MapColumn = function(colName, htmlPosition, dataType, sortable, hidden)
	{
		var cm = {colName: colName, htmlPosition: htmlPosition, dataType: dataType, sortable: sortable, th: this.ths[htmlPosition]};
		
		if(sortable)
		{
			var _this = this; // "this" pass-through

			cm.th.onclick = function() {_this.sortColumn(colName);}
		}

		this.columnMappings[colName] = cm;
	}
	
	this.AddFilter = function(colName, filterID, onDemandURL)
	{
		
		var filterEls = document.getElementsByName(filterID);
		var filterEl = (filterEls.length > 1) ? filterEls[0] : document.getElementById(filterID);

		var elName = filterEl.nodeName.toLowerCase();
		var elType = filterEl.type.toLowerCase();
		
		var _this = this; // "this" pass-through

		if(elName == "input" && elType == "text")
		{
			filterEl.onkeydown = function(_event) {return _this.handleKeywordSearch(_event, colName, filterID);}
		}
		if(elName == "input" && elType == "checkbox")
		{
			for(var i = 0; i < filterEls.length; i++)
			{
				filterEls[i].onclick = function() {_this.filterTable(colName, filterID);}
			}
		}
		if(elName == "a")
		{
			for(var i = 0; i < filterEls.length; i++)
			{
				filterEls[i].onclick = function() {_this.filterTable(colName, filterID, this); return false;}
			}
		}
		else
		{
			filterEl.onchange = function() {_this.filterTable(colName, filterID);}
		}

		// make it sexy!
		if(elName == "select") {SexySelect_New(filterID);}
		
		this.filters[colName] = {id: filterID, colName: colName, filterEl: filterEl, elName: elName, elType: elType, currVal: "", filterEls: filterEls};
		
		if(onDemandURL && onDemandURL != "")
		{
			this.filters[colName].onDemandURL = onDemandURL;
		}
	}
	
	// private methods/functions

	this.sortColumn = function(colName)
	{
		pleaseWait(this.id, true);

		var _this = this;
		
		setTimeout(function() {_this.sortColumn2(colName);}, this.pleaseWaitMillisecs);
	}

	this.sortColumn2 = function(colName)
	{
		var cm = this.columnMappings[colName];
		
		// set current sorting
		
		if(this.currSortColName != colName)
		{
			if(this.currSortColName != null)
			{
				replaceClass(this.columnMappings[this.currSortColName].th, "sort_(none|asc|desc)", "sort_none");
			}
			
			this.currSortColName = colName;
			this.currSortOrderASC = true;
		}
		else
		{
			this.currSortOrderASC = !this.currSortOrderASC;
		}

		replaceClass(cm.th, "sort_(none|asc|desc)", this.currSortOrderASC ? "sort_asc" : "sort_desc");
		
		// sort rows
		
		var rows = new Array()
		
		for(var i = 1; i < this.table.rows.length; i++)
		{
			var row = this.table.rows[i];
			var tr = row.cloneNode(true);
			
			var sortVal = cellValue(row.cells[cm.htmlPosition]);

			var id = row.id + "_selector";
			var chk1 = ebus_getChildByID(row, id);
			
			if(chk1 && chk1.checked)
			{
				var chk2 = ebus_getChildByID(tr, id);
				
				chk2.checked = true;
			}
			
			rows.push({pos: i, tr: tr, sortVal: sortVal});
		}
		
		var sortedRows = rows.sort(function sortHandler(row1, row2) {return compareRows(row1, row2, cm.dataType);});
		
		var from = this.currSortOrderASC ? 0 : sortedRows.length - 1;
		var to = this.currSortOrderASC ? sortedRows.length : -1;
		var step = this.currSortOrderASC ? 1 : -1;
		
		var rowPos = 1;

		for(var i = from; i != to; i += step)
		{
			var tr = this.table.rows[rowPos];

			tr.parentNode.replaceChild(sortedRows[i].tr, tr);
			
			rowPos++;
		}

		this.colorRows();
		
		// TEMPORARY: force recreation of all superPopOuts
		allPopOuts = new Object();

		pleaseWait(this.id, false);
	}
	
	this.handleKeywordSearch = function(_event, colName, filterID)
	{
		// kill pending timeout
		if(this.autoSearchTimeoutHandler) {clearTimeout(this.autoSearchTimeoutHandler);}

		// handle keystroke
		if(!_event && event) {_event = event;}
		
		var keyCode = _event.keyCode;
		
		if(keyCode == 13) // "Enter" key: run search immediately
		{
			this.filterTable(colName, filterID);
			
			return false; // stops form being submitted
		}
		else // start autosearch delay
		{
			var _this = this;
			
			this.autoSearchTimeoutHandler = setTimeout(function() {_this.filterTable(colName, filterID)}, this.autoSearchDelayMillisec);
		}
		
		return true;
	}
	
	this.filterTable = function(colName, filterID , element)
	{
		// save filter value
		
		var filter = this.filters[colName];
		var filterEl = filter.filterEl;
		
		var isSelect = (filter.elName == "select");
		var isLink = (filter.elName == "a");
		var isCheckbox = (filter.elType == "checkbox");
		
		var typedVal = "";
		
		if(isSelect)
		{
			typedVal = filterEl.options[filterEl.selectedIndex].value;
		}
		else if(isCheckbox)
		{
			for(var i = 0; i < filter.filterEls.length; i++)
			{
				var el = filter.filterEls[i];
				
				if(el.checked)
				{
					typedVal += (typedVal == "" ? "" : ",") + el.value;
				}
			}
		}
		else if(isLink)
		{
			typedVal = element.getAttribute('value');
			for(var i = 0; i < filter.filterEls.length; i++)
			{
				var el = filter.filterEls[i];
				
				el.parentNode.className = '';
			}
			element.parentNode.className = 'active';
		}
		else
		{
			typedVal = filterEl.value;
		}
		
		if(!isSelect && !isCheckbox && !isLink && typedVal.length < 3) {typedVal = "";} // ignore too short searches
		
		filter.currVal = cleanText(typedVal);
		
		if(!this.skipFiltering)
		{
			// filter the table
			this.applyAllFilters();
		}
	}

	this.applyAllFilters = function()
	{
		// first, update on-demand content
		
		if(document.getElementById("onDemandContentBlock"))
		{
			for(var i in this.filters)
			{
				var filter = this.filters[i];
				
				if(filter.onDemandURL)
				{
					updateOnDemandBlock(filter);
				}
			}
		}

		// then refresh the table
		
		pleaseWait(this.id, true);

		var _this = this;
		
		setTimeout(function() {_this.applyAllFilters2();}, this.pleaseWaitMillisecs);
	}
	
	this.applyAllFilters2 = function()
	{
		// gather active filter
		
		var activeFilters = new Array();
		
		for(var j in this.filters)
		{
			var filter = this.filters[j];

			if(filter.currVal != "")
			{
				activeFilters.push(filter);
			}
		}

		// filter each rows
		
		for(var i = 1; i < this.table.rows.length; i++)
		{
			var hidden = false;
			
			for(var j = 0; j < activeFilters.length && !hidden; j++)
			{
				var filter = activeFilters[j];
				
				var exact = (filter.elName == "select" || filter.elType == "checkbox" || filter.elName == "a");
				var text = cleanText(cellValue(this.table.rows[i].cells[this.columnMappings[filter.colName].htmlPosition]));
				
				if(keywordMatch(filter.currVal, text, exact) == 0)
				{
					hidden = true;
				}
			}

			if(hidden)
			{
				ebus_addClass(this.table.rows[i], "row_hidden");
				
				if(this.SelectorEnabled)
				{
					var checkbox = document.getElementById(this.table.rows[i].id + "_selector");
					
					if(checkbox && checkbox.checked)
					{
						checkbox.checked = false;
					}
				}
			}
			else
			{
				ebus_removeClass(this.table.rows[i], "row_hidden");
			}
		}

		// Force Shadow DIV position style to static then back to relative to fix IE7 bug
		// IE7 needs to have it's styles re-rendered to pick up the tables' new height after filtering - Don't ask!!
		var tableNextSibling = document.getElementById(this.table.id).parentNode.nextSibling;

		if(tableNextSibling.className == 'shad-right')
		{
			tableNextSibling.style.position = 'static';
			tableNextSibling.style.position = 'relative';
		}
		
		// re-color
		this.colorRows();

		pleaseWait(this.id, false);
	}
	
	this.clearFilters = function()
	{
		// reset all filters but do not filter the table
		
		this.skipFiltering = true;

		for(var j in this.filters)
		{
			var filter = this.filters[j];
			var filterEl = filter.filterEl;
			var isSelect = (filter.elName == "select");
			var isCheckbox = (filter.elType == "checkbox");
			var isLink = (filter.elName == "a");
			
			if(isSelect)
			{
				filterEl.selectedIndex = 0;
				filterEl.onchange();
			}
			else if(isCheckbox)
			{
				for(var i = 0; i < filter.filterEls.length; i++)
				{
					var el = filter.filterEls[i];
					
					el.checked = false;
					el.onclick();
				}
			}
			else if(isLink)
			{
				for(var i = 0; i < filter.filterEls.length; i++)
				{
					var el = filter.filterEls[i];
					
					el.parentNode.className = '';
				}
				//filterEl.value = "";
				filter.currVal = "";
			}
			else
			{
				filterEl.value = "";
				filter.currVal = "";
			}
		}
		
		// clear selectors
		
		if(this.SelectorEnabled)
		{
			var els = document.getElementsByName(this.id + "_selector");
			
			for(var i = 0; i < els.length; i++)
			{
				els[i].checked = false;
			}
		}

		this.skipFiltering = false;

		// filter eventually
		this.applyAllFilters();
	}
	
	this.colorRows = function()
	{
		var visibleCount = 0;
		
		for(var i = 1; i < this.table.rows.length; i++)
		{
			if(!checkClass(this.table.rows[i], "row_hidden"))
			{
				replaceClass(this.table.rows[i], "row_(0|1)", "row_" + visibleCount % 2);
				
				visibleCount++;
			}
		}

		if(visibleCount == 0)
		{
			this.noEntriesMsg.style.display = "block";
		}
		else
		{
			this.noEntriesMsg.style.display = "none";
		}
	}
	
	function compareRows(row1, row2, dataType)
	{
		var val1 = row1.sortVal;
		var val2 = row2.sortVal;
		
		if(dataType == "number" || dataType == "price" || dataType == "priceChange")
		{
			val1 = parseFloat(val1);
			val2 = parseFloat(val2);
		}
		else if(dataType == "date")
		{
			val1 = new Date(val1);
			val2 = new Date(val2);
		}
		
		var ret = val1 < val2 ? -1 : 1;
		
		return ret;
	}
	
	function cellValue(cell)
	{
		var val = cell.innerHTML;
		
		// get inner element if present
		if(cell.childNodes[0] && cell.childNodes[0].innerHTML)
		{
			val = cell.childNodes[0].innerHTML;
		}

		return val;
	}
	
	function keywordMatch(search, keywords, exact)
	{
		var score = 0;
		
		search = search.toLowerCase();
		keywords = keywords.toLowerCase();

		if(exact && search == keywords)
		{
			// quick win!
			score = 1;
		}
		else
		{
			if(!exact) // keyword search
			{
				search = search.replace(/ +/gi, ",");
			}
			
			var searchBits = search.split(",");
			var keywordRegex = new RegExp("^(" + keywords.replace(/,/gi, "|") + ")$");
			
			//TODO: this stop at the first match (it won't sort the result by score)
			for(var i = 0; i < searchBits.length && score == 0; i++)
			{
				score += keywordRegex.test(searchBits[i]) ? 1 : 0;
			}
		}
		
		return score;
	}
	
	function updateOnDemandBlock(filter)
	{
		if(filter.currVal == "")
		{
			document.getElementById("onDemandContentBlock").innerHTML = "";
			
			this.currentOnDemandURL = null;
		}
		else
		{
			var url = filter.onDemandURL.replace(/\[filter\-value\]/g, filter.currVal).replace(/amp;/g, "");
			
			if(url != this.currentOnDemandURL)
			{
				// load content
				
				var xmlhttp = null;
				
				if(window.XMLHttpRequest)
				{
					xmlhttp = new XMLHttpRequest();
				}
				else if(window.ActiveXObject)
				{
					xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
				}
				
				if(xmlhttp != null)
				{
					xmlhttp.open("GET", url, false);
					xmlhttp.send(null);
					
					var text = xmlhttp.responseText;
					
					if(text.indexOf("*NO_CONTENT") != -1) {text = "";}
					
					// inject
					document.getElementById("onDemandContentBlock").innerHTML = text;
				}
				
				// save url
				this.currentOnDemandURL = url;
			}
		}
	}
	
	this.saveStatus = function()
	{
		// save filters
		
		var filters = "";
		var delim = "";
		
		for(var j in this.filters)
		{
			var filter = this.filters[j];

			if(filter.currVal != "")
			{
				filters += (delim + filter.colName + "=" + filter.currVal);
				
				delim = "&";
			}
		}
		
		// save selectors
		
		var els = document.getElementsByName(this.id + "_selector");
		
		var selectors = "";
		var delim = "";
		
		for(var i = 0; i < els.length; i++)
		{
			if(els[i].checked)
			{
				selectors += (delim + els[i].id);
				
				delim = ",";
			}
		}
		
		// save to cookie
		ebus_createCookie(this.id + "_filters", filters);
		ebus_createCookie(this.id + "_selectors", selectors);
	}
	
	this.SelectorSubmit = function(errorMessage)
	{
		this.saveStatus();
		
		var els = document.getElementsByName(this.id + "_selector");
		
		var count = 0;
		var ids = "";
		var delim = "";
		
		for(var i = 0; i < els.length; i++)
		{
			if(els[i].checked)
			{
				ids += (delim + els[i].value);
				
				delim = ",";
				count++;
			}
		}

		if(count > 1)
		{
			// go to comparison page
			document.location.href = this.SelectorSubmitURL + "?ids=" + ids;
		}
		else
		{
			alert(errorMessage);
		}
	}
	
	this.CheckMaxChoices = function()
	{
		var els = document.getElementsByName(this.id + "_selector");
		
		var count = 0;
		
		for(var i = 0; i < els.length; i++)
		{
			if(els[i].checked)
			{
				count++;
			}
		}

		return (count <= this.SelectorMaxChoices);
	}
	
	this.Init = function(forceFilters)
	{
		if(forceFilters == "true")
		{
			this.clearFilters();
		}

		// initialize selectors
		
		var ckIDs = ebus_readCookie(this.id + "_selectors");
		
		if(this.SelectorEnabled && ckIDs)
		{
			var ids = ckIDs.split(",");
			
			for(var i = 0; i < ids.length; i++)
			{
				var el = document.getElementById(ids[i]);
				
				if(el) {el.checked = true;}
			}
		}
	
		// initialize filters from querystring or cookies
		
		var qsVals = qstring();
		var ckVals = ebus_readCookie(this.id + "_filters");

		var filterVals = (qsVals ? qsVals : "")
			+ (qsVals ? "&" : "")
			+ (ckVals ? ckVals : "");

		if(filterVals != "")
		{
			this.skipFiltering = true;

			var qsFound = false;

			for(var i in this.filters)
			{
				var filter = this.filters[i];
				var qs = qstring(filter.colName, filterVals);
				
				if(qs != null && qs != "")
				{
					var filterEl = filter.filterEl;
					var isSelect = (filter.elName == "select");
					var isCheckbox = (filter.elType == "checkbox");
					var isLink = (filter.elName == "a");
					
					if(isSelect)
					{
						for(j = 0; j < filterEl.options.length; j++)
						{
							if(filterEl.options[j].value == qs)
							{
								filterEl.options[j].selected = true;
							}
						}

						filterEl.onchange();
					}
					else if(isCheckbox)
					{
						for(var i = 0; i < filter.filterEls.length; i++)
						{
							var el = filter.filterEls[i];
							
							if(("," + qs + ",").indexOf(el.value) != -1)
							{
								el.checked = true;
								el.onclick();
							}
						}
					}
					else if(isLink)
					{	
						for(var i = 0; i < filter.filterEls.length; i++)
						{
							var el = filter.filterEls[i];
							
							if(("," + qs + ",").indexOf(el.getAttribute('value')) != -1)
							{
								el.parentNode.className = 'active';
								el.onclick();
							}
						}
						filter.currVal = qs;
					}
					else
					{
						filterEl.value = qs;
						filter.currVal = qs;
					}
					
					qsFound = true;
				}
			}
			
			this.skipFiltering = false;
			
			if(qsFound) {this.applyAllFilters();}
		}
		
		// initialize any sorting from querystring
		
		if(qstring('sort')){
			for(var i in this.columnMappings){
				if(this.columnMappings[i].colName.toLowerCase() == qstring('sort').toLowerCase()){
					this.sortColumn(this.columnMappings[i].colName);
				}
			}
		}
	}

	// class properties & initialization
	
	this.id = id;
	this.table = document.getElementById(id);
	this.columnMappings = new Object();
	this.filters = new Object();

	this.ths = this.table.rows[0].cells;
	this.noEntriesMsg = document.getElementById(this.id + "_noEntriesMessage");

	this.currSortColName = null;
	this.currSortOrderASC = false;
	this.skipFiltering = false;
	this.pleaseWaitMillisecs = 500;
	this.autoSearchDelayMillisec = 1500;
	this.autoSearchTimeoutHandler = null;
	this.currentOnDemandURL = null;
	
	this.SelectorEnabled = false;
	this.SelectorSubmitURL = null;
	this.SelectorMaxChoices = 10;
	
	// enable clear filters button
	
	var btn = document.getElementById(this.id + "_clearFiltersBtn");
	
	if(btn)
	{
		var _this = this; // "this" pass-through

		btn.onclick = function() {_this.clearFilters();}
	}
}

