/* if no console exists, build dummy funcs */
if (!window.console) {
	(function() {
		var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
		window.console = {};
		
		for (var i = 0; i < names.length; ++i) {
			window.console[names[i]] = function() {};
		}
	}());
}

function $_GET(key) {
	key = key.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
	var regexS = "[\\?&]" + key + "=([^&#]*)";
	var regex = new RegExp(regexS);
	var results = regex.exec(window.location.href);
	
	if (results === null) {
		return "";
	} 
	
	return decodeURIComponent(results[1].replace(/\+/g, " "));
}

function isNumeric(n) {
	return !isNaN(parseFloat(n)) && isFinite(n);
}

/**
*
*  MD5 (Message-Digest Algorithm)
*  http://www.webtoolkit.info/
*
**/
 
var MD5 = function (string) {
 
	function RotateLeft(lValue, iShiftBits) {
		return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
	}
 
	function AddUnsigned(lX,lY) {
		var lX4,lY4,lX8,lY8,lResult;
		lX8 = (lX & 0x80000000);
		lY8 = (lY & 0x80000000);
		lX4 = (lX & 0x40000000);
		lY4 = (lY & 0x40000000);
		lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
		if (lX4 & lY4) {
			return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
		}
		if (lX4 | lY4) {
			if (lResult & 0x40000000) {
				return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
			} else {
				return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
			}
		} else {
			return (lResult ^ lX8 ^ lY8);
		}
 	}
 
 	function F(x,y,z) {return (x & y) | ((~x) & z);}
 	function G(x,y,z) {return (x & z) | (y & (~z));}
 	function H(x,y,z) {return (x ^ y ^ z);}
	function I(x,y,z) {return (y ^ (x | (~z)));}
 
	function FF(a,b,c,d,x,s,ac) {
		a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
		return AddUnsigned(RotateLeft(a, s), b);
	};
 
	function GG(a,b,c,d,x,s,ac) {
		a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
		return AddUnsigned(RotateLeft(a, s), b);
	};
 
	function HH(a,b,c,d,x,s,ac) {
		a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
		return AddUnsigned(RotateLeft(a, s), b);
	};
 
	function II(a,b,c,d,x,s,ac) {
		a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
		return AddUnsigned(RotateLeft(a, s), b);
	};
 
	function ConvertToWordArray(string) {
		var lWordCount;
		var lMessageLength = string.length;
		var lNumberOfWords_temp1=lMessageLength + 8;
		var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
		var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
		var lWordArray=Array(lNumberOfWords-1);
		var lBytePosition = 0;
		var lByteCount = 0;
		while ( lByteCount < lMessageLength ) {
			lWordCount = (lByteCount-(lByteCount % 4))/4;
			lBytePosition = (lByteCount % 4)*8;
			lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
			lByteCount++;
		}
		lWordCount = (lByteCount-(lByteCount % 4))/4;
		lBytePosition = (lByteCount % 4)*8;
		lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
		lWordArray[lNumberOfWords-2] = lMessageLength<<3;
		lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
		return lWordArray;
	};
 
	function WordToHex(lValue) {
		var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
		for (lCount = 0;lCount<=3;lCount++) {
			lByte = (lValue>>>(lCount*8)) & 255;
			WordToHexValue_temp = "0" + lByte.toString(16);
			WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
		}
		return WordToHexValue;
	};
 
	function Utf8Encode(string) {
		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;
	};
 
	var x=Array();
	var k,AA,BB,CC,DD,a,b,c,d;
	var S11=7, S12=12, S13=17, S14=22;
	var S21=5, S22=9 , S23=14, S24=20;
	var S31=4, S32=11, S33=16, S34=23;
	var S41=6, S42=10, S43=15, S44=21;
 
	string = Utf8Encode(string);
 
	x = ConvertToWordArray(string);
 
	a = 0x67452301;b = 0xEFCDAB89;c = 0x98BADCFE;d = 0x10325476;
 
	for (k=0;k<x.length;k+=16) {
		AA=a;BB=b;CC=c;DD=d;
		a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
		d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
		c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
		b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
		a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
		d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
		c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
		b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
		a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
		d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
		c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
		b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
		a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
		d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
		c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
		b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
		a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
		d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
		c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
		b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
		a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
		d=GG(d,a,b,c,x[k+10],S22,0x2441453);
		c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
		b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
		a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
		d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
		c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
		b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
		a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
		d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
		c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
		b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
		a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
		d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
		c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
		b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
		a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
		d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
		c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
		b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
		a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
		d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
		c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
		b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
		a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
		d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
		c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
		b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
		a=II(a,b,c,d,x[k+0], S41,0xF4292244);
		d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
		c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
		b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
		a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
		d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
		c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
		b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
		a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
		d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
		c=II(c,d,a,b,x[k+6], S43,0xA3014314);
		b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
		a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
		d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
		c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
		b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
		a=AddUnsigned(a,AA);
		b=AddUnsigned(b,BB);
		c=AddUnsigned(c,CC);
		d=AddUnsigned(d,DD);
	}
 
	var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
 
	return temp.toLowerCase();
}

/***************
 * These functions set up the skeleton for image rollovers and input onfocus changes.
 ***************/

function rolloverReplace(o, suffix) {
	var srcstring = o.getAttribute('src');
	var newsrcstring = srcstring.replace(/_((down)|(off)|(on))\./, suffix);
	o.setAttribute('src', newsrcstring);
}

function rolloverOn(ev) {
	var evtarget = YAHOO.util.Event.getTarget(ev);
	rolloverReplace(evtarget, '_on.');
}

function rolloverOff(ev) {
	var evtarget = YAHOO.util.Event.getTarget(ev);
	rolloverReplace(evtarget, '_off.');
}

function rolloverDown(ev) {
	var evtarget = YAHOO.util.Event.getTarget(ev);
	rolloverReplace(evtarget, '_down.');
}

function resetButtonNoId(el) {
	try {
		if (!el) {
			throw ('element required');
		}
		el.setAttribute('src', old_button_src);
		el.style.height = old_button_height + 'px';
	} catch (e) {
		//    alert(e);
	}
}

function resetButton(button_id) {
	try {
		if (!button_id) {
			throw ('button id required');
		}
		var button = document.getElementById(button_id);
		resetButtonNoId(button);
	} catch (e) {
		//    alert(e);
	}
}

//global variables for old button, to be reset in case of failure
var old_button_src = '';
var old_button_height = 0;
//keep this together with setLoader function

function doLoader(element) {
	old_button_src = element.getAttribute('src').replace(/(_on|_off|_down)\.(.{2,3})/, '_off.$2');
	old_button_height = element.clientHeight;

	var old_width = element.clientWidth;

	if (!document.getElementById("loginSubmitButton") && (!document.getElementById("head_search_submit"))) {
		element.setAttribute('src', "/images/icons/loader.gif");
		element.style.width = old_width + 'px';
		element.style.height = '20px'; //current height of loader;
	}

}

function setLoader(element) {
	//don't touch the render or cart checkout button or cart recalculate button
	//the form validation goes first, so we're going to fire this manually from there
	if (!element) {
		return;
	} else if (element.id && (element.id == 'render_submit' || element.id == "cart_checkout_button" || element.id == "update")) {
		return;
	}
	//comment this last condition list the file and the function + why
	//IS_VALID_NO_LOADER_IMG is a global boolean to prevent the loader image when the form isn't valid
	//else if(element.id == 'login' && defined(IS_VALID_NO_LOADER_IMG) && IS_VALID_NO_LOADER_IMG == false){ //false and 0 //(also do the isset on this)
	//return;
	//}
	doLoader(element);
}

function rolloverClick(ev) {
	var evtarget = YAHOO.util.Event.getTarget(ev);
	setLoader(evtarget);
}

function setupRolloverHandlers(el) {
	var rollbuttons = preloadRollovers(el);
	var container = el ? YAHOO.util.Dom.get(el) : document;
	YAHOO.util.Event.addListener(rollbuttons, "mouseover", rolloverOn);
	YAHOO.util.Event.addListener(rollbuttons, "mouseout", rolloverOff);
	YAHOO.util.Event.addListener(rollbuttons, "mousedown", rolloverDown);
	var theseneedloader = YAHOO.util.Dom.getElementsByClassName('image_button', '*', container);
	YAHOO.util.Event.addListener(theseneedloader, "click", rolloverClick);
}

function preloadRollovers(el) {
	// If a container isn't passed, we run through everything
	if (!el) {
		var loader = new Image();
		loader.src = "/images/icons/loader.gif";
		var container = document;
	} else {
		var container = YAHOO.util.Dom.get(el);
	}
	// get image and input collections
	var imgcol = new Array();
	imgcol[imgcol.length] = container.getElementsByTagName('img');
	imgcol[imgcol.length] = container.getElementsByTagName('input');

	var pics = new Array();
	var rolloverEls = new Array();
	for (var j = 0; j < imgcol.length; j++) {
		for (var i = 0; i < imgcol[j].length; i++) {
			// preload images
			if (imgcol[j][i].src.match('_off.')) {
				rolloverEls[rolloverEls.length] = imgcol[j][i];
				// Preload the _on state
				pics[pics.length] = new Image();
				pics[pics.length - 1].src = imgcol[j][i].src.replace(/_(off)\./, '_on.');
				// Preload the _down state
				pics[pics.length] = new Image();
				pics[pics.length - 1].src = imgcol[j][i].src.replace(/_(off)\./, '_down.');
			}
		}
	}
	return rolloverEls;
}

function externalLinks() {
	if (!document.getElementsByTagName) return;
	var anchors = document.getElementsByTagName("a");
	for (var i = 0; i < anchors.length; i++) {
		var anchor = anchors[i];
		if (anchor.getAttribute("href") && anchor.getAttribute("rel") == "external") anchor.target = "_blank";
	}
}

function initTypeNav() {
	var typeNav_img = null;
	if (typeNav_img = document.getElementById('typeNav_img')) {
		typeNav_img.onmouseover = function () {
			try {
				this.src = '/images/typeNav/typeNav_on.gif';
			} catch (e) { //alert(e);
			}
		};
		typeNav_img.onmouseout = function () {
			try {
				this.src = '/images/typeNav/typeNav_off.gif';
			} catch (e) { //alert(e);
			}
		};
		typeNav_img.onmousedown = function () {
			try {
				this.src = '/images/typeNav/typeNav_down.gif';
			} catch (e) { //alert(e);
			}

		};
	}

}
YAHOO.util.Event.addListener(window, "load", externalLinks);
YAHOO.util.Event.addListener(window, "load", initTypeNav);
// @name      The Fade Anything Technique
// @namespace http://www.axentric.com/aside/fat/
// @version   1.0-RC1
// @author    Adam Michela
// @license	  http://creativecommons.org/licenses/by-sa/2.0/
var Fat = {
	make_hex: function (r, g, b) {
		r = r.toString(16);
		if (r.length == 1) r = '0' + r;
		g = g.toString(16);
		if (g.length == 1) g = '0' + g;
		b = b.toString(16);
		if (b.length == 1) b = '0' + b;
		return "#" + r + g + b;
	},
	fade_all: function () {
		var a = document.getElementsByTagName("*");
		for (var i = 0; i < a.length; i++) {
			var o = a[i];
			var r = /fade-?(\w{3,6})?/.exec(o.className);
			if (r) {
				if (!r[1]) r[1] = "";
				if (!o.id) o.id = YAHOO.util.Event.generateId(o);
				if (o.id) Fat.fade_element(o.id, null, null, "#" + r[1]);
			}
		}
	},
	fade_element: function (id, fps, duration, from, to) {
		if (!fps) fps = 30;
		if (!duration) duration = 3000;
		if (!from || from == "#") from = "#FFFF33";
		if (!to) to = this.get_bgcolor(id);

		var frames = Math.round(fps * (duration / 1000));
		var interval = duration / frames;
		var delay = interval;
		var frame = 0;

		if (from.length < 7) from += from.substr(1, 3);
		if (to.length < 7) to += to.substr(1, 3);

		var rf = parseInt(from.substr(1, 2), 16);
		var gf = parseInt(from.substr(3, 2), 16);
		var bf = parseInt(from.substr(5, 2), 16);
		var rt = parseInt(to.substr(1, 2), 16);
		var gt = parseInt(to.substr(3, 2), 16);
		var bt = parseInt(to.substr(5, 2), 16);

		var r, g, b, h;
		while (frame < frames) {
			r = Math.floor(rf * ((frames - frame) / frames) + rt * (frame / frames));
			g = Math.floor(gf * ((frames - frame) / frames) + gt * (frame / frames));
			b = Math.floor(bf * ((frames - frame) / frames) + bt * (frame / frames));
			h = this.make_hex(r, g, b);

			setTimeout("Fat.set_bgcolor('" + id + "','" + h + "')", delay);

			frame++;
			delay = interval * frame;
		}
		setTimeout("Fat.set_bgcolor('" + id + "','" + to + "')", delay);
	},
	set_bgcolor: function (id, c) {
		try {
			var o = document.getElementById(id);
			o.style.backgroundColor = c;
		} catch (e) {
			//lots of places where this gets called and for
			//some reason o is null
			//so just ignore these errors
		}
	},
	get_bgcolor: function (id) {
		var o = document.getElementById(id);
		while (o) {
			var c;
			if (window.getComputedStyle) c = window.getComputedStyle(o, null).getPropertyValue("background-color");
			if (o.currentStyle) c = o.currentStyle.backgroundColor;
			if ((c != "" && c != "transparent") || o.tagName == "BODY") {
				break;
			}
			o = o.parentNode;
		}
		if (c == undefined || c == "" || c == "transparent") c = "#FFFFFF";
		var rgb = c.match(/rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/);
		if (rgb) c = this.make_hex(parseInt(rgb[1]), parseInt(rgb[2]), parseInt(rgb[3]));
		return c;
	}
}
YAHOO.util.Event.addListener(window, "load", Fat.fade_all);

function isLocalLink(a_object) {
	var href_pathname = a_object.href.match(/^http:\/\/([\w\.\-]*)(\/.*)#.*$/);
	if ((href_pathname) && (href_pathname[2] == window.location.pathname) && (a_object.href.indexOf('#top') == -1)) {

		return true;
	} else {
		return false;
	}
}

function getWrapperId() {
	if (document.getElementById('wide_container')) {
		return 'wide_container';
	} else if (document.getElementById('container')) {
		return 'container';
	} else {
		//error
	}

}

function linkClick() {
	var wrapper_id = getWrapperId();
	document.getElementById(wrapper_id).style.overflow = "visible";
}

function getHash(element) {
	var re = /#(.*)$/;
	var href = element.getAttribute('href');
	if (href) {
		var hash = href.match(re);
		if (hash) {
			return hash[1];
		}
	}
	return null;
}

function getElementFromEvent(e_e, e_this) {

	/************
	 teh weirdness
	 
	 sometimes e is event, sometimes it's element
	 
	 seems to be a firefox bug where e is usually event, and this is element
	 but when url has a hash, e is element and this is window
	 
	 so...
	 
	 the purpose of this function is to take e and this from a
	 callback, and return the correct this
	 
	 ************/

	if (e_e.target || e_e.srcElement) {
		//e is event, therfore this is element
		return e_this;
	} else {
		return e_e;
	}
}

function linkBlur(e) {
	var element = getElementFromEvent(e, this);
	var wrapper_id = getWrapperId();

	if (needsRemedy) {
		document.getElementById(wrapper_id).style.overflow = "hidden";
	}

	var hash = getHash(element);
	//only fade if that id exists
	if (hash && document.getElementById(hash)) {
		Fat.fade_element(hash);
	}
}

function initLinks() {
	var anchors = document.getElementsByTagName('a');
	var once = false;
	/*
	time for some jiggetty jiggety browser sniffing....
    safari likes mousedown/mouseup
    others are sweet on click/blur
    */
	if (window.navigator.userAgent.indexOf('Safari') != -1) {
		var downEvt = "mousedown";
		var upEvt = "mouseup";
	} else {
		var downEvt = "click";
		var upEvt = "blur";
	}

	for (var i = 0; i < anchors.length; i++) {
		if (isLocalLink(anchors[i])) {
			if (needsRemedy) {
				YAHOO.util.Event.addListener(anchors[i], downEvt, linkClick);
			}
			YAHOO.util.Event.addListener(anchors[i], upEvt, linkBlur);
		}
	}
}

function urlAnchor() {
	if (window.location.hash) {
		return true;
	} else return false;
}

function getPixFromTop(element) {
	if (element.offsetParent) {
		return (element.offsetTop + getPixFromTop(element.offsetParent));
	} else {
		return element.offsetTop;
	}
}

function getPixFromLeft(element) {
	if (element.offsetParent) {
		return (element.offsetLeft + getPixFromLeft(element.offsetParent));
	} else {
		return element.offsetLeft;
	}
}

function setHashFocus(hash) {
	var anchor = null;
	if (!(anchor = document.getElementById(hash))) {
		var anchors = document.getElementsByTagName('a');
		for (var i = 0; i < anchors.length; i++) {
			if (anchors[i].name == hash) {
				var pix = getPixFromTop(anchors[i]) - (anchors[i].offsetHeight * 2);
				break;
			}
		}
	} else {
		var pix = getPixFromTop(anchor) - (anchor.offsetHeight * 2);
	}

	window.scrollTo(0, pix);
}

function scriptLinks(html) {
	var r = new RegExp('<a (href="(' + window.location.pathname + window.location.search + ')?#.+") ?>', 'g');
	return html.replace(r, '<a $1 onclick="linkClick();" onblur="linkBlur(this);">');
}

function handleUrlAnchor() {
	var hash = window.location.hash.substr(1);
	var html = document.body.innerHTML;
	if (needsRemedy) {
		document.body.innerHTML = '';
		document.body.innerHTML = scriptLinks(html);

		setHashFocus(hash);
	}

	try {
		if (document.getElementById(hash)) {
			Fat.fade_element(hash);
		}
	} catch (e) {
		//    alert(e);
	}
}

function initWindow() {
	try {
		initLinks();
		if (urlAnchor()) {
			handleUrlAnchor();
		}
	} catch (e) {
		//    alert(e);
	}
}

//global
var needsRemedy = false;

try {
	if ((window.navigator.userAgent.indexOf('Gecko') != -1 || // limit to gecko browsers (eg firefox)
	window.navigator.userAgent.indexOf('MSIE 7') != -1) //and ie7
	&& window.navigator.userAgent.indexOf('Safari') == -1) { //but not safari
		needsRemedy = true;
	}
	YAHOO.util.Event.addListener(window, "load", initWindow);
} catch (e) {
	//  alert(e);
}

function swapRenderLoader(render_id, loader_id, param) {
	if (param == 1) {
		//alert("1: " +render_id);
		document.getElementById(render_id).style.display = "block";
		document.getElementById(loader_id).style.display = "none";
	} else if (param == 2) {
		//alert("2: " +render_id);
		document.getElementById(render_id).style.display = "none";
		document.getElementById(loader_id).style.display = "block";
	}
}

function swapAllRenderLoaders() {
	var images = document.getElementsByTagName("img");
	var img_id = "";

	//set loaders
	for (var i = 0; i < images.length; i++) {
		img_id = images[i].id;
		if (img_id.substring(0, 13) == "render_loader") images[i].style.display = "block";
	}

	//set images
	for (var i = 0; i < images.length; i++) {
		img_id = images[i].id;
		if (img_id.substring(0, 10) == "render_img") images[i].style.display = "block";
		if (img_id.substring(0, 13) == "render_loader") images[i].style.display = "none";
	}
}

function strpos(haystack, needle, offset) {
	var i = (haystack + '').indexOf(needle, offset);
	if (i === -1) {
		return false;
	}

	return i;
}

function showHide(object, className) {
	if (object.className == 'hide') {
		object.className = 'show';
	} else {
		object.className = 'hide';
	}
}

function bgChange(object, color) {
	if (object.style.backgroundColor == '') {
		object.style.backgroundColor = color;
	} else {
		object.style.backgroundColor = '';
	}
}

function arrowSwitch(object) {
	if (object.innerHTML.charCodeAt(0) == '9654') {
		object.innerHTML = '&#9660;';
	} else {
		object.innerHTML = '&#9654;';
	}
}

function cleanWhitespace(element) {
	element = document.getElementById(element) || element
	var node = element.firstChild;
	while (node) {
		var nextNode = node.nextSibling;
		if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) element.removeChild(node);
		node = nextNode;
	}
	return element;
}

function validateEmailAddress(email) {
	emailStr = email;
	var checkTLD = 1;

	/* The following is the list of known TLDs that an e-mail address must end with. */

	/* 11/14/08 JC: added .cat TLD. Not really a country TLD so fails two-letter country
	domain test later on in this function, so it needs to be added here. */

	var knownDomsPat = /^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum|cat)$/;

	/* The following pattern is used to check if the entered e-mail address
	fits the user@domain format.  It also is used to separate the username
	from the domain. */
	var emailPat = /^(.+)@(.+)$/;

	/* The following string represents the pattern for matching all special
	characters such as ( ) < > @ , ; : \ " . [ ] */
	var specialChars = "\\(\\)><@,;:\\\\\\\"\\.\\[\\]";

	/* The following string represents the range of characters allowed in a 
	username or domainname.*/
	var validChars = "\[^\\s" + specialChars + "\]";

	/* The following pattern applies if the "user" is a quoted string (in
	which case, there are no rules about which characters are allowed
	and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
	is a legal e-mail address. */
	var quotedUser = "(\"[^\"]*\")";

	/* The following pattern applies for domains that are IP addresses,
	rather than symbolic names.  E.g. joe@[123.124.233.4] is a legal
	e-mail address. NOTE: The square brackets are required. */
	var ipDomainPat = /^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;

	/* The following string represents an atom */
	var atom = validChars + '+';

	/* The following string represents one word in the typical username.
	For example, in john.doe@somewhere.com, john and doe are words.*/
	var word = "(" + atom + "|" + quotedUser + ")";

	// The following pattern describes the structure of the user
	var userPat = new RegExp("^" + word + "(\\." + word + ")*$");

	/* The following pattern describes the structure of a normal symbolic
	domain, as opposed to ipDomainPat, shown above. */
	var domainPat = new RegExp("^" + atom + "(\\." + atom + ")*$");

	/* Begin with the coarse pattern to simply break up user@domain into
	different pieces that are easy to analyze. */
	var matchArray = emailStr.match(emailPat);

	if (matchArray == null) {
	/* Too many/few @'s or something; basically, this address doesn't
	even fit the general mould of a valid e-mail address. */

		return false;
	}

	var user = matchArray[1];
	var domain = matchArray[2];

	// Start by checking that only basic ASCII characters are in the strings (0-127).
	for (i = 0; i < user.length; i++) {
		if (user.charCodeAt(i) > 127) {
			return false;
		}
	}

	for (i = 0; i < domain.length; i++) {
		if (domain.charCodeAt(i) > 127) {
			return false;
		}
	}

	// See if "user" is valid 
	if (user.match(userPat) == null) {
		return false;
	}

	/* if the e-mail address is at an IP address (as opposed to a symbolic
	host name) make sure the IP address is valid. */

	var IPArray = domain.match(ipDomainPat);

	if (IPArray != null) {
		for (var i = 1; i <= 4; i++) {
			if (IPArray[i] > 255) {
				return false;
			}
		}

		return true;
	}
}

function footerSubscribe(email) {
	if (validateEmailAddress(email) == false) {
		j('#footer_email_error').html('&#9650; Invalid email address.');
		j('#iidlui-iidlui').keypress(function () {
			j('#footer_email_error').html('');
		});
		return false;
	} else {
		var url = '/fonts/footer_subscribe.php';
		var query_string = 'email=' + j('#iidlui-iidlui').val();

		j('#footer_email_success').fadeIn(2000);
		j('#footer_email_success').html('<span style="color:black">Please wait...</span>');

		j.post(url, query_string, function (data) {
			j('#footer_email_success').html(data);
			j('#iidlui-iidlui').val('Enter email address');
			j('#footer_email_success').fadeIn(2000);
			setTimeout("j('#footer_email_success').fadeOut(2000);", 1000);
			setTimeout("j('#footer_email_success').hide();", 3000);

			return false;
		})

		return false;
	}
}

function RGBtoHex(R, G, B) {
	return toHex(R) + toHex(G) + toHex(B)
}

function toHex(N) {
	if (N == null) return "00";
	N = parseInt(N);
	if (N == 0 || isNaN(N)) return "00";
	N = Math.max(0, N);
	N = Math.min(N, 255);
	N = Math.round(N);
	return "0123456789ABCDEF".charAt((N - N % 16) / 16) + "0123456789ABCDEF".charAt(N % 16);
}

//parseUri 1.2.2
//(c) Steven Levithan <stevenlevithan.com>
//MIT License

function parseUri(str) {
	var o = parseUri.options,
		m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
		uri = {},
		i = 14;

	while (i--) uri[o.key[i]] = m[i] || "";

	uri[o.q.name] = {};
	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
		if ($1) uri[o.q.name][$1] = $2;
	});

	return uri;
};

parseUri.options = {
	strictMode: false,
	key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"],
	q: {
		name: "queryKey",
		parser: /(?:^|&)([^&=]*)=?([^&]*)/g
	},
	parser: {
		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
		loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
	}
};

var addthis_config = {
	services_compact: 'email, twitter, facebook, wordpress, digg, delicious, stumbleupon, more',
	services_exclude: 'favorites, print',
	data_track_linkbacks: true,
	ui_click: true,
	ui_hover_direction: -1,
	ui_header_background: "#DDD"
}
var addthis_share = {
	templates: {
		twitter: 'Check this out: {{url}} (shared from @FontShop)'
	}
}

String.prototype.trim = function () {
	this.replace(/^\s+|\s+$/g, '');
}
String.prototype.addslashes = function () {
	return (this + '').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
}
String.prototype.stripslashes = function () {
	return (this + '').replace(/\\(.?)/g, function (x, n1) {
		switch (n1) {
		case '\\':
			return '\\';
		case '0':
			return '\u0000';
		case '':
			return '';
		default:
			return n1;
		}
	});
}

function setCookie(cookieName, value, expires, path, domain, secure) {
	// expires=days
	var now = new Date();
	now.setTime(now.getTime());

	if (expires) {
		expires = (60 * 60 * 24 * expires) * 1000; // milliseconds!
	}
	
	var dateExpires = new Date(now.getTime() + (expires));

	document.cookie = cookieName + "=" + escape(value) + ((expires) ? ";expires=" + dateExpires.toGMTString() : "") + ((path) ? ";path=" + path : "") + ((domain) ? ";domain=" + domain : "") + ((secure) ? ";secure" : "");
}

function getCookie(thisCookie) {
	var cookieArray = document.cookie.split(';');
	var arrayTempCookie = '';
	var cookieName = '';
	var cookieVal = '';
	var foundCookie = false;

	for (i = 0; i < cookieArray.length; i++) {
		arrayTempCookie = cookieArray[i].split('=');
		cookieName = arrayTempCookie[0].replace(/^\s+|\s+$/g, '');

		if (cookieName == thisCookie) {
			foundCookie = true;

			if (arrayTempCookie.length > 1) {
				cookieVal = unescape(arrayTempCookie[1].replace(/^\s+|\s+$/g, ''));
			}

			return cookieVal;

			break;
		}

		arrayTempCookie = null;
		cookieName = '';
	}

	if (!foundCookie) {
		return null;
	}
}

function deleteCookie(cookieName, path, domain) {
	if (getCookie(cookieName)) {
		document.cookie = cookieName + "=" + ((path) ? ";path=" + path : "") + ((domain) ? ";domain=" + domain : "") + ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
	}
}

function stripslashes(str) {
	return (str + '').replace(/\\(.?)/g, function (s, n1) {
		switch (n1) {
		case '\\':
			return '\\';
		case '0':
			return '\u0000';
		case '':
			return '';
		default:
			return n1;
		}
	});
}

function getFormValues(ids) {
	var v = {};
	for (var i = 0; i < ids.length; i++) {
		var el = document.getElementById(ids[i]);
		if (el && el.value) {
			v[ids[i]] = encodeURIComponent(el.value);
		}
	}

	return v;
}

function Url(url) {
	this.request = url ? url : document.URL;
	this.path = this.request;
	this.params = {};
	var bits = this.request.split('?');
	this.query = (bits.length > 1) ? decodeURI(bits[1]) : '';

	if (this.query.length > 0) {
		this.path = this.path.substr(0, this.path.indexOf('?'));
		var vars = this.query.split('&');
		for (var v = 0; v < vars.length; ++v) {
			bits = vars[v].split('=');
			if (bits.length === 2) {
				this.params[bits[0]] = bits[1];
			}
		}
	}
	this.addParams = function (add) {
		for (var i = 0; i < add.length; i++) {
			this.params[i] = add[i];
		}
	};
	this.getQuery = function () {
		var vars = [];
		for (var i = 0; i < this.params.length; i++) {
			vars.push(i + '=' + this.params[i]);
		}
		return (vars.length > 0) ? vars.join('&') : '';
	};
	this.toString = function () {
		return this.path + '?&' + this.getQuery();
	};
}

// login widget
j(document).ready(function () {
	j("#header_login").click(function () {
		if (window.location.href.indexOf('widget_register') === -1) {
			if (window.location.pathname.indexOf('/fonts/login.php') === 0) {
				document.getElementById('email_address_login').focus();
				return false;
			}
		}

		if (j("#login_widget").is(":visible")) {
			j("#login_widget").fadeOut(200);
		} else {
			j("#login_widget").fadeIn(200);
			j("#login_widget #signin_widget_email").focus();
		}
		return false;
	});
});

// jquery ui buttons
j(document).ready(function () {
	var buttons = j('input[rel="buttonize"]');

	for (i = 0; i < buttons.length; i++) {
		try {
			j(buttons[i]).button();
		} catch (err) {
			console.error('button() failed');
		}
	}
});

// free font download eula display
j(document).ready(function () {
	// find all buy buttons with the class name download
	j('div[class^="download_"]').each(function () {
		var div = this;

		// hook click evt to the first a href in the div
		j(this).find('a').click(function (evt) {
			var self = this;
			var id = div.className.replace('download_', '');

			// pass wrapper id: download_[123_456]
			j.getJSON('/service/getEula.php', {
				wid: id
			}, function (data) {
				// fill the dummy element with eula text, then dialog it
				j('#eula_dialog_placeholder_' + id).html(data.eula_text).dialog({
					height: 500,
					width: 500,
					modal: true,
					closeOnEscape: true,
					resizable: false,
					dialogClass: 'eula_dialog',
					title: '<img src="' + data.logo + '" style="width:25px; height:25px;" /> End User License Agreement',
					buttons: {
						"Agree and download": function () {
							// close dialog and continue to the href
							window.location = self.href;
							j(this).dialog("close");
						},
						"Cancel": function () {
							// do nothing
							j(this).dialog("close");
							return false;
						}
					}
				});
			});
			// stop the event (window.location) from occurring
			evt.preventDefault();
		});
	});
});

// volker: change background per qa environment
j(document).ready(function ()  {
	var b = null;
	
	switch(MD5(window.location.hostname)) {
		case "c7acbb86c5f61c233ebeac07ea2fd15d": // staging
			b = 'orange';
			break;			
		case "595c1a14e5492929c72ad0ca8d1dbd54": // codeqa
			b = 'red';
			break;			
		case "e52e477779e14a83f0984010ea7b865f": // prodqa
			b = 'green';
			break;
		case "83d94e612334bbc57ed63ad859cf629d": // import
			b = 'blue';
			break;
		default:
			break;
	}
	
	if (b) {j('body, #container, #wide_container').css({'background': b});}
});

j(document).ready(function () {
	j('#yellow').click(function () {
		j("link[type='text/css'][href^='/css/grey_theme.css']").remove();
		console.log('back to yellow');
		j('#theme-toggle').removeClass('grey');
		
		if (getCookie('theme')) {
			setCookie('theme', '', 0, '/');
		}
		
		return false;
	});
	
	j('#grey').click(function () {
		if (j("link[type='text/css'][href^='/css/grey_theme.css']").length == 0) {
			j('head').append('<link rel="stylesheet" href="/css/grey_theme.css" type="text/css" />');
		}
		j('#theme-toggle').addClass('grey');
		
		setCookie('theme', 'grey', 364, '/');
		
		return false;
	});
});




/**
 * Google Click Tracking Functions | written as jQuery extension
 * @author Bernhard Schmidt <bernhard@fontshop.com>,
 * @author Inez Korczynski <inez@wikia.com>
 * http://trac.wikia-code.com/browser/wikia/trunk/skins/common/jquery/jquery.wikia.tracker.js
 */

// Port of getTarget and resolveTextNode function (altogether) from YUI Event lib
// @author: Inez Korczynski <inez@wikia.com>
// @TODO: Move it to some more general place because it is not realted only to tracking
function getTarget(ev) {
    var t = ev.target || ev.srcElement;
    if(t && 3 == t.nodeType) {
        t = t.parentNode;
    }
    return t;
}

jQuery.tracker = function() {
	if (typeof initTracker == 'function') {
		initTracker();
	}
};

jQuery.tracker.byStr = function(message) {
	j.tracker.track(message);
};

jQuery.tracker.byId = function(e) {
	j.tracker.track(this.id);
};

jQuery.tracker.trackStr = function(str, account) {
	// TODO: insure that we're not in debug mode (gaq will be undefined)
	if (typeof _gaq === "undefined") {
		console.warn("_gaq undefined in jQuery.tracker.trackStr");
		return;
	}
	
	if(typeof account != 'undefined') {
		_gaq.push(['_setAccount', account]);
	}
	_gaq.push(['_trackPageview', str]);
	var userTrackerMessage = '';
	if (_gaq.FSUserID != undefined) {
		// shorten the name for better displaying in Real-Time Analytics
		var userTrackerStr = str.replace('clicktracking/', 'click/');
		_gaq.push(['user._trackPageview', '/' + _gaq.FSUserID + userTrackerStr]);
		userTrackerMessage = 'user-';
	}
	console.log(userTrackerMessage +'tracker: ' + str);
};

// for specific user tracking
jQuery.tracker.track = function(fakeurl) {
	fakeurlArray = fakeurl.split('/');
	var username = ''; // @todo fill in username or make anon
	j.tracker.trackStr('/clicktracking/' + fakeurl);
	//j.tracker.trackStr('/clicktracking/' + username + '/' + fakeurl);
};

// simple click tracking
// usage: j('#foo').clickTrack('feature/foo');
jQuery.fn.trackClick = function(fakeUrl) {
	this.click(function(ev) {
		jQuery.tracker.byStr(fakeUrl);
	});
};

j(document).ready(j.tracker);

/*
  * Test whether argument elements are parents of the first matched element
  * This is part of jQuery 1.5, FontShop is missing it for effective click tracking 
  * http://blogs.bluehazetech.net/2010/11/19/custom-hasparents-function-to-check-if-an-element-has-a-specific-parent-element/
  * @return boolean
  * @param objs
  *   a jQuery selector, selection, element, or array of elements
*/


j.fn.hasParent = function(objs) {
	// ensure that objs is a jQuery array
	objs = j(objs);
	var found = false;
	j(this[0]).parents().andSelf().each(function() {
		if (j.inArray(this, objs) != -1) {
			found = true;
			return false; // stops the each...
		}
	});
	return found;
};


/**
 * gets all attributes of a jQuery DOM object
 * returns attributes as an object attr-name -> value
 */

jQuery.fn.getAttributes = function() {
	var attributes = {}; 

	if(!this.length) {
		return this;
	}
	
	jQuery.each(this[0].attributes, function(index, attr) {
		attributes[attr.name] = attr.value;
	}); 

	return attributes;
};

/**
 * $('img.photo',this).imagesLoaded(myFunction)
 * execute a callback when all images have loaded.
 * needed because .load() doesn't work on cached images
 * mit license. paul irish. 2010.
 * webkit fix from Oren Solomianik. thx!
 *
 * callback function is passed the last image to load
 * as an argument, and the collection as `this`
**/

jQuery.fn.imagesLoaded = function(callback){
	var elems = this.filter('img'),
	len   = elems.length,
	blank = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
      
	elems.bind('load.imgloaded',function(){
		if (--len <= 0 && this.src !== blank){ 
			elems.unbind('load.imgloaded');
			callback.call(elems,this); 
		}
	}).each(function(){
		// cached images don't fire load sometimes, so we reset src.
		if (this.complete || this.complete === undefined){
			var src = this.src;
			// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
			// data uri bypasses webkit log warning (thx doug jones)
			this.src = blank;
			this.src = src;
		}  
	}); 

	return this;
};

// TODO: place this in a more appropriate file
j(document).ready(function() {
	j("#mainDescReadMore").click(function() {
	    j("#pad, #moreDesc, #readMoreText, #readLessText").toggle();
	});
});
