var numOutstandingRequests = 0;

function setVisibility(name,visible) {
	var obj = getObject(name);
	if(obj) {
		obj.style.visibility = visible;
	}
}

function setHref(name,url) {
	var obj = getObject(name);
	if(obj) {
		obj.href = url;
	}
}

function quoteit(string) {
	return string.replace('"', "''");
}

function TableCellSpec(width, align, cls, bgcolor, fgcolor, title, alt, sort) {
	this.width   = width ? width : false;
	this.align   = align ? align : false;
	this.title   = title ? title : false;
	this.alt     = alt ? alt : false;
	this.sort    = sort ? sort : false;
	this.bgcolor = bgcolor ? bgcolor : false;
	this.fgcolor = fgcolor ? fgcolor : false;
	this.cls     = cls ? cls : false;
}

function getPriceCompareUrl(text) {
	text = text.replace(/\$[\d\,\.]+|[\-\[\]\(\)]|\d+\% (off|up)|at [\w\.]+|@ [\w\.]+/g, ' ');
	url = "http://www.shopzilla.com/buy/superfind.xpml?keyword="+encodeURIComponent(text)+"__rf--xzn000";
	
	return url;
}

function processCellSpec(row, column, cellSpec) {
	return cellSpec;
}

function getCellSpec(row,column) {
	if(this.columns && this.columns[column]) {	
		cellSpec = this.columns[column];
	} else 
		cellSpec = new TableCellSpec();
		
	return this.processCellSpec(row, column, cellSpec);
}

function TableSpec(width, align, padding, spacing, columns) {
	this.width = width ? width : "100%";
	this.align = align ? align : "left";
	this.spacing = spacing ? spacing : 0;
	this.padding = padding ? padding : 0;
	this.columns = columns ? columns : false;
	
	this.getCellSpec = getCellSpec;
	this.processCellSpec = processCellSpec;
}


function badBrowserSupport() {
	location.href = "/badbrowser.html";
}

function getEvent(e) {
	if (!e) var e = window.event;
	return e;
}

function getEventTarget(e) {
	return (e.target) ? e.target : e.srcElement;
}

function addEvent(e, event, callback, noBubble) {
	if(e.addEventListener) {
		e.addEventListener(event, callback, noBubble);
		return true;
	} else if (e.attachEvent) {
		return e.attachEvent("on"+event, callback);
	} else {
		// could not attach event
	}
}

function removeEvent(e, event, callback, noBubble) {
	if(e.removeEventListener) {
		e.removeEventListener(event, callback, noBubble);
		return true;
	} else if (e.detachEvent) {
		return e.detachEvent("on"+event, callback);
	} else {
		// could not remove event
	}
}

function getSelection()
{
	var txt = '';
	var foundIn = '';
	
	if (window.getSelection)
	{
		txt = window.getSelection();
		foundIn = 'window.getSelection()';
	}
	else if (document.getSelection)
	{
		txt = document.getSelection();
		foundIn = 'document.getSelection()';
	}
	else if (document.selection)
	{
		txt = document.selection.createRange().text;
		foundIn = 'document.selection.createRange()';
	}
	
	return txt;
}


function setContent(id, text) 
{
	if (document.getElementById)
	{
		x = document.getElementById(id);
		if(x) {
			x.innerHTML = '';
			x.innerHTML = text;
		}
	}
	else if (document.all)
	{
		x = document.all[id];
		if(x) {
			x.innerHTML = text;
		}
	}
	else if (document.layers)
	{
		x = document.layers[id];
		if(x) {
			text2 = '<P CLASS="testclass">' + text + '</P>';
			x.document.open();
			x.document.write(text2);
			x.document.close();
		}
	}
}


function getObject(name) {

	if(document.getElementById) {
		return document.getElementById(name);
	} else if(document.all) {
		return document.all[name];
	} else if(document.layers) {
		badBrowserSupport();
	}	
	
	return false;
}

function isAlien(a) {
   return isObject(a) && typeof a.constructor != 'function';
}
function isArray(a) {
    return isObject(a) && a.constructor == Array;
}
function isBoolean(a) {
    return typeof a == 'boolean';
}
function isEmpty(o) {
    var i, v;
    if (isObject(o)) {
        for (i in o) {
            v = o[i];
            if (isUndefined(v) && isFunction(v)) {
                return false;
            }
        }
    }
    return true;
}
function isFunction(a) {
    return typeof a == 'function';
}
function isNull(a) {
    return typeof a == 'object' && !a;
}
function isNumber(a) {
    return typeof a == 'number' && isFinite(a);
}
function isObject(a) {
    return (a && typeof a == 'object') || isFunction(a);
}
function isString(a) {
    return typeof a == 'string';
}
function isUndefined(a) {
    return typeof a == 'undefined';
} 

function confirmlink(msg, link) {
	if(confirm(msg)) {
		window.location = link;
	}
}

function clearfield(field) {
	field.value = '';
}

function gET(seconds) {
	var months = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
	
	var dt = new Date();
	var sec = Math.round((dt.getTime() / 1000) -  seconds);
	if (sec >= 86400*15) {
		var olddt = new Date();
		olddt.setTime(seconds*1000)
		return olddt.getDate()+" "+months[olddt.getMonth()]+" "+olddt.getYear();
	}  else if (sec < 0) {
		return "recent";
	} else if (sec > 0 && sec < 60) {
		return sec+"s ago";
	} else if (sec >= 60 && sec < 3600) {
		return Math.round(sec/60)+"m ago";
	} else if (sec >= 3600 && sec < 86400) {
		return Math.round(sec/3600)+"h ago";
	} else if (sec >= 86400) {
		return Math.round(sec/86400)+"d ago";
	}
	
	return "recent";
}

function getFormInputValue(input) {
	if(!input) return "";
	
	var type = input.type;
	if(type == "text" || type == "hidden" || type == "password" || type == "textarea") return input.value;
	if(type == "checkbox" || type == "radio") return input.checked ? (input.value ? input.value : input.name) : "";
	if(type == "select" || type == "select-one") return input.options ? input.options[input.selectedIndex].value : "";
	if(type == "submit" || type == "button") return input.value ? input.value : input.name; 
	
	return "";
}


function getFormContent(form) {
	var inputs = form.elements;
	var retarr = [];
	
	for (var i = 0; i < inputs.length; i++) {
	  value = getFormInputValue(inputs[i]);
	  current = retarr[inputs[i].name];
	  if(current && !isArray(current)) {
		retarr[inputs[i].name] = [current];
		current = retarr[inputs[i].name];
	  }
	  if(isArray(current)) {
		retarr[inputs[i].name][retarr[inputs[i].name].length] = value;
	  } else {
		retarr[inputs[i].name] = value;
	  }
	}
	
	return retarr;	
}

function showLoadingStatus(status) {
	if(status) {
		var statusdiv = getObject(status);
		if(statusdiv) statusdiv.style.visibility="visible";
	}
}

function hideLoadingStatus(status) {
	if(status) {
		var statusdiv = getObject(status);
		if(statusdiv) statusdiv.style.visibility="hidden";
	}
}

function sendXMLRequest(id, url, content, result, error, status, show) {
	var req = null;
	
	function processReqChange() {
		if(!req) return;
		
		if(req.readyState == 4) {
			hideLoadingStatus(status);
			numOutstandingRequests--;
		
			if (req.status == 200) {
				if(result) result(id, req.responseText);
			} else {
				if(error) error(id, req.status);
			}
			
			req = false;
		}
	}	
	
	if(content) { 
		method = "POST";
		if(isArray(content)) {
			var temp = "";
			for(key in content) {
				if(!isArray(content[key])) {
					temp += escape(key)+"="+escape(content[key])+"&";
				} else {
					for(i = 0; i < content[key].length; i++) {
						temp += escape(key)+"="+escape(content[key][i])+"&";
					}
				}
			}
			content = temp;
		}
	} else {
		method = "GET";
	}

	if(show) showLoadingStatus(status);
	req = getRequest();
	
	if(!req) {
		if (error) {
			error(id, -1); 
		}
		return;
	} 
	req.open(method, url, true);
	if(method == "POST") req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
	req.onreadystatechange = processReqChange;
	req.send(content);	
	numOutstandingRequests++;		
}

function getRequest() {
	req = false;
	
    // branch for native XMLHttpRequest object
    if(window.XMLHttpRequest) {
    	try {
			req = new XMLHttpRequest();
        } catch(e) {
			req = false;
        }
    // branch for IE/Windows ActiveX version
    } else if(window.ActiveXObject) {
       	try {
			req = new ActiveXObject("Msxml2.XMLHTTP");
      	} catch(e) {
        	try {
				req = new ActiveXObject("Microsoft.XMLHTTP");
        	} catch(e) {
          		req = false;
        	}
		}
    }
    
    return req;
}

function createTableData(string) {
	var result = new Array();
	var rows = string.split("\n");
	for(i = 0; i < rows.length; i++) {
		var cells = rows[i].split("\t");
		result[i] = cells;
	}
	return result;
}

function createTable(tabledata, tablespec) {
	var output = "";
	if(!tablespec) {
		tablespec = new TableSpec("100%", "left");
	}
	output += "<table align=\""+tablespec.align+"\" width=\""+tablespec.width+"\" border=\"0\" cellpadding=\""+tablespec.padding+"\" cellspacing=\""+tablespec.spacing+"0\">\n";
	for(i = 0; i < tabledata.length; i++) {
		var row = tabledata[i];
		output += "<tr>\n";
		for(j = 0; j < row.length; j++) {
			var cell = row[j];
			var cellspec = tablespec.getCellSpec(i, j);
			output += "<td ";
			if(cellspec.align)   output += "align = \""+cellspec.align+"\" ";
			if(cellspec.width)   output += "width = \""+cellspec.width+"\" ";
			if(cellspec.bgcolor) output += "bgcolor = \""+cellspec.bgcolor+"\" ";
			if(cellspec.fgcolor) output += "fgcolor = \""+cellspec.fgcolor+"\" ";
			if(cellspec.cls)     output += "class = \""+cellspec.cls+"\" ";
			output += ">\n";
			data = false;
			data = cell.split('|');
			if(data[1]) {
				target = "";
				if(data[2]) target = "target=\""+data[2]+"\"";
				output += "<a href=\""+data[1]+"\" "+target+">";
			}
			output += data[0];
			if(data[1]) {
				output += "</a>";
			}
			output += "</td>\n";
		}
		output += "</tr>\n";
	}
	output += "</table>\n";
	
	return output;
}

function addEngine()
{
  if ((typeof window.sidebar == "object") && (typeof window.sidebar.addSearchEngine == "function")) {
    window.sidebar.addSearchEngine(
      "http://www.roosster.com/nr/roosster.src",
      "http://www.roosster.com/nr/roosster.png", "Roosster", "Shopping" );
  } else
	if ((typeof window.external == "object") && (typeof window.external.AddSearchProvider == "function")) {
	window.external.AddSearchProvider('http://www.roosster.com/nr/roosster-osd.pxml');
    } else 
		alert("You will need a Mozilla based browser OR Internet Explorer 7+ to install a search plugin.");
}

function writeEngine() {
  if ((typeof window.sidebar == "object") && (typeof window.sidebar.addSearchEngine == "function")) {
		document.write('<div class="searchplugin"><a href="javascript:addEngine()"><img src="/img/rstr/firefox-logo-19x19.png" alt="Add Firefox Search Plugin" title="Add Firefox Search Plugin"/></a></div>');
  } else
	if ((typeof window.external == "object") && (typeof window.external.AddSearchProvider == "function")) {
		document.write('<div class="searchplugin"><a href="javascript:addEngine()"><img src="/img/rstr/ie-icon.gif" alt="Add IE Search Plugin" title="Add IE Search Plugin"/></a></div>');
	}
}

function resizeImage(img, maxwidth, maxheight) {
	currentwidth = img.width;
	currentheight = img.height;
	
	changefactor = Math.max(1,Math.max(currentwidth/maxwidth, currentheight/maxheight));
	
	img.width = Math.round(currentwidth/changefactor);
	img.height = Math.round(currentheight/changefactor);
	
	return img;
}

function getImageHtml(img, force) {
	var html = new Array('<img src="',img.src,'"');
	var top = 3;
	
	if(img.complete || force == true) {
		resizeImage(img, this.maxwidth, this.maxheight);
		html[top++] = ' width="';
		html[top++] = img.width;
		html[top++] = '" height="';
		html[top++] = img.height;
		html[top++] = '"';
	} else {	
		html[top++] = ' onLoad="resizeImage(this, ';
		html[top++] = this.maxwidth;
		html[top++] = ' , ';
		html[top++] = this.maxheight;
		html[top++] = ')"';
	}
	
	html[top++] = ' border="0">';
	
	return html.join("");
}

function trimString(str, maxLength) {
	if(str==null) return str;
	if(str.length <= maxLength) return str;
	
	return str.substring(0,maxLength-3)+'...';
}

function createImage(src, width, height) {
	var img = new Image();
	img.src = src;
	img.width = width;
	img.height = height;
	
	return img;
}


<!--
//
//  Cookie Functions -- "Night of the Living Cookie" Version (25-Jul-96)
//
//  Written by:  Bill Dortch, hIdaho Design <bdortch@hidaho.com>
//  The following functions are released to the public domain.
//
//  This version takes a more aggressive approach to deleting
//  cookies.  Previous versions set the expiration date to one
//  millisecond prior to the current time; however, this method
//  did not work in Netscape 2.02 (though it does in earlier and
//  later versions), resulting in "zombie" cookies that would not
//  die.  DeleteCookie now sets the expiration date to the earliest
//  usable date (one second into 1970), and sets the cookie's value
//  to null for good measure.
//
//  Also, this version adds optional path and domain parameters to
//  the DeleteCookie function.  If you specify a path and/or domain
//  when creating (setting) a cookie**, you must specify the same
//  path/domain when deleting it, or deletion will not occur.
//
//  The FixCookieDate function must now be called explicitly to
//  correct for the 2.x Mac date bug.  This function should be
//  called *once* after a Date object is created and before it
//  is passed (as an expiration date) to SetCookie.  Because the
//  Mac date bug affects all dates, not just those passed to
//  SetCookie, you might want to make it a habit to call
//  FixCookieDate any time you create a new Date object:
//
//    var theDate = new Date();
//    FixCookieDate (theDate);
//
//  Calling FixCookieDate has no effect on platforms other than
//  the Mac, so there is no need to determine the user's platform
//  prior to calling it.
//
//  This version also incorporates several minor coding improvements.
//
//  **Note that it is possible to set multiple cookies with the same
//  name but different (nested) paths.  For example:
//
//    SetCookie ("color","red",null,"/outer");
//    SetCookie ("color","blue",null,"/outer/inner");
//
//  However, GetCookie cannot distinguish between these and will return
//  the first cookie that matches a given name.  It is therefore
//  recommended that you *not* use the same name for cookies with
//  different paths.  (Bear in mind that there is *always* a path
//  associated with a cookie; if you don't explicitly specify one,
//  the path of the setting document is used.)
//  
//  Revision History:
//
//    "Toss Your Cookies" Version (22-Mar-96)
//      - Added FixCookieDate() function to correct for Mac date bug
//
//    "Second Helping" Version (21-Jan-96)
//      - Added path, domain and secure parameters to SetCookie
//      - Replaced home-rolled encode/decode functions with Netscape's
//        new (then) escape and unescape functions
//
//    "Free Cookies" Version (December 95)
//
//
//  For information on the significance of cookie parameters, and
//  and on cookies in general, please refer to the official cookie
//  spec, at:
//
//      http://www.netscape.com/newsref/std/cookie_spec.html    
//
//******************************************************************
//
// "Internal" function to return the decoded value of a cookie
//
function getCookieVal (offset) {
  var endstr = document.cookie.indexOf (";", offset);
  if (endstr == -1)
    endstr = document.cookie.length;
  return unescape(document.cookie.substring(offset, endstr));
}
//
//  Function to correct for 2.x Mac date bug.  Call this function to
//  fix a date object prior to passing it to SetCookie.
//  IMPORTANT:  This function should only be called *once* for
//  any given date object!  See example at the end of this document.
//
function FixCookieDate (date) {
  var base = new Date(0);
  var skew = base.getTime(); // dawn of (Unix) time - should be 0
  if (skew > 0)  // Except on the Mac - ahead of its time
    date.setTime (date.getTime() - skew);
}
//
//  Function to return the value of the cookie specified by "name".
//    name - String object containing the cookie name.
//    returns - String object containing the cookie value, or null if
//      the cookie does not exist.
//
function GetCookie (name) {
  var arg = name + "=";
  var alen = arg.length;
  var clen = document.cookie.length;
  var i = 0;
  while (i < clen) {
    var j = i + alen;
    if (document.cookie.substring(i, j) == arg)
      return getCookieVal (j);
    i = document.cookie.indexOf(" ", i) + 1;
    if (i == 0) break; 
  }
  return null;
}
//
//  Function to create or update a cookie.
//    name - String object containing the cookie name.
//    value - String object containing the cookie value.  May contain
//      any valid string characters.
//    [expires] - Date object containing the expiration data of the cookie.  If
//      omitted or null, expires the cookie at the end of the current session.
//    [path] - String object indicating the path for which the cookie is valid.
//      If omitted or null, uses the path of the calling document.
//    [domain] - String object indicating the domain for which the cookie is
//      valid.  If omitted or null, uses the domain of the calling document.
//    [secure] - Boolean (true/false) value indicating whether cookie transmission
//      requires a secure channel (HTTPS).  
//
//  The first two parameters are required.  The others, if supplied, must
//  be passed in the order listed above.  To omit an unused optional field,
//  use null as a place holder.  For example, to call SetCookie using name,
//  value and path, you would code:
//
//      SetCookie ("myCookieName", "myCookieValue", null, "/");
//
//  Note that trailing omitted parameters do not require a placeholder.
//
//  To set a secure cookie for path "/myPath", that expires after the
//  current session, you might code:
//
//      SetCookie (myCookieVar, cookieValueVar, null, "/myPath", null, true);
//
function SetCookie (name,value,expires,path,domain,secure) {
  document.cookie = name + "=" + escape (value) +
    ((expires) ? "; expires=" + expires.toGMTString() : "") +
    ((path) ? "; path=" + path : "") +
    ((domain) ? "; domain=" + domain : "") +
    ((secure) ? "; secure" : "");
}

//  Function to delete a cookie. (Sets expiration date to start of epoch)
//    name -   String object containing the cookie name
//    path -   String object containing the path of the cookie to delete.  This MUST
//             be the same as the path used to create the cookie, or null/omitted if
//             no path was specified when creating the cookie.
//    domain - String object containing the domain of the cookie to delete.  This MUST
//             be the same as the domain used to create the cookie, or null/omitted if
//             no domain was specified when creating the cookie.
//
function DeleteCookie (name,path,domain) {
  if (GetCookie(name)) {
    document.cookie = name + "=" +
      ((path) ? "; path=" + path : "") +
      ((domain) ? "; domain=" + domain : "") +
      "; expires=Thu, 01-Jan-70 00:00:01 GMT";
  }
}

//
//  Examples - Unremark if you want to see how this code works
/*
var expdate = new Date ();
FixCookieDate (expdate); // Correct for Mac date bug - call only once for given Date object!
expdate.setTime (expdate.getTime() + (24 * 60 * 60 * 1000)); // 24 hrs from now 
SetCookie ("ccpath", "http://www.hidaho.com/colorcenter/", expdate);
SetCookie ("ccname", "hIdaho Design ColorCenter", expdate);
SetCookie ("tempvar", "This is a temporary cookie.");
SetCookie ("ubiquitous", "This cookie will work anywhere in this domain",null,"/");
SetCookie ("paranoid", "This cookie requires secure communications",expdate,"/",null,true);
SetCookie ("goner", "This cookie must die!");
document.write (document.cookie + "<br>");
DeleteCookie ("goner");
document.write (document.cookie + "<br>");
document.write ("ccpath = " + GetCookie("ccpath") + "<br>");
document.write ("ccname = " + GetCookie("ccname") + "<br>");
document.write ("tempvar = " + GetCookie("tempvar") + "<br>");
*/
// -->
