/**
   Prototype snippet with header
**/

/*--------------------------------------------------------------------------
 *  Prototype: an object-oriented Javascript library, version 1.2.1
 *  (c) 2005 Sam Stephenson <sam@conio.net>
 *
 *  THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff
 *  against the source tree, available from the Prototype darcs repository. 
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *
 *  For details, see the Prototype web site: http://prototype.conio.net/
 *
/*--------------------------------------------------------------------------*/

var Prototype = { Version: '1.2.1' }

var Class = {
  create: function() {
    return function() { 
      this.initialize.apply(this, arguments);
    }
  }
}

//I hacked this actually, previous looked like utter rubbish
if (!Function.prototype.apply) {
  
  Function.prototype.apply = function(object, parameters) {
    var parameterStrings = "";
    if (!object)     object = window;
    if (!parameters) parameters = new Array();
    
    for (var i = 0; i < parameters.length; i++) {
    	parameterStrings += parameter[i];
		if (i != parameters.length) {
			 parameterStrings += ", ";
		}
	}
    
    object.__apply__ = this;
    var result = eval('object.__apply__(' + parameterStrings + ')');
    object.__apply__ = null;
    
    return result;
  }
}

Object.prototype.extend = function(object) {
  for (property in object) {
    this[property] = object[property];
  }
  return this;
}

Function.prototype.bind = function(object) {
  var method = this;
  return function() {
    method.apply(object, arguments);
  }
}

//mine
Function.prototype.bindWith = function(object, argArray) {
	var method = this;
	return function() {
		method.apply(object, argArray);
	}
}

Function.prototype.bindAsEventListener = function(object) {
  var method = this;
  return function(event) {
    method.call(object, event || window.event);
  }
}

Number.prototype.toColorPart = function() {
  var digits = this.toString(16);
  if (this < 16) return '0' + digits;
  return digits;
}

var Try = {
  these: function() {
    var returnValue;
    
    for (var i = 0; i < arguments.length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) {}
    }
    
    return returnValue;
  }
}




/*--------------------------------------------------
 *
 *  End of imported prototype stuff, it's all my stuff now!
 *
 *--------------------------------------------------*/ 


 var Browser = {
 		isWin: function() { return navigator.platform.indexOf("Win") != -1;},
 		isOpera: function() { return navigator.userAgent.indexOf("Opera") != -1;},
 		isIE: function() { return this.isWin() && navigator.appName.indexOf("Microsoft") != -1 && !this.isOpera();},
 		isGecko: function() { return navigator.userAgent.indexOf("Gecko") != -1;},
		isSafari: function() { return navigator.appVersion.indexOf("AppleWebKit") != -1;},
		needsPNGHack: function() {return this.isIE() && navigator.appVersion.indexOf("7") != -1;}
 };
 
var Assets = {
	blankGIF : "images/blank.gif"
};





/****************************************************************************************
*****************************************************************************************
*** Onload and initialization ***********************************************************
*****************************************************************************************
*****************************************************************************************/

function Runner() {
	this.runnables = new Array();
	this.priorityRunnables = new Array();
}

Runner.prototype = {
	
	add: function(newFuncRef) {				
		this.runnables.push(newFuncRef);
	},

	addPriority: function(newFuncRef) {	
		this.priorityRunnables.push(newFuncRef);
	},

	addLater: function(newFuncRef, later) {
		this.add(
			function() {
				setTimeout(newFuncRef, later);
			}
		);
	},

	run: function() {	
		for (var i = 0; i < this.priorityRunnables.length; i++) {
			this.priorityRunnables[i]();
		}	
		for (var j = 0; j < this.runnables.length; j++) {
			this.runnables[j]();
		}	
	}
};

var INITIALIZER = new Runner();
var FINALIZER = new Runner();

window.onload = INITIALIZER.run.bind(INITIALIZER);
window.onunload = FINALIZER.run.bind(FINALIZER);


/**********************************

	Core object extras

**********************************/

if (!Array.prototype.push) {
	Array.prototype.push = function(value) {
    	this[this.length] = value; 
	}
}

Array.prototype.getIndexOfValue = function(value) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == value) return i;
	}
	return -1;
}

String.prototype.trim = function() {
	if (this.length == 0) return this;
	
	var startAt = 0;
	var endAt  = this.length;

	while (this.charAt(startAt) == ' ' && startAt < endAt) {
		startAt++;
	}

	while (this.charAt(endAt-1) == ' ' && endAt > startAt) {
		endAt--;
	}

	return ((startAt > 0 || endAt < this.length)?this.substring(startAt, endAt):this);
}

String.prototype.endsWith = function(ref) {
	if (this.length == 0) return false;
	if (!ref || ref.length == 0) return false;
    if (this.length < ref.length) return false;
	if (this == ref) return true;//trivially

	return (this.substr(this.length - ref.length) == ref);
}


/********
 debug
********/

var Debug = {
	on: false,
	id: "debugElementId",

	setOn: function(on) {
		this.on = on;
	},

	isOn: function() {
		return this.on;
	},

	setup: function() {
		if (!this.on) return;

		var debugPanel = this.getPanel();		
		
		this.print("****************************");
		this.print("*** Welcome to the debug ***");
		this.print("****************************");
		this.print(navigator.appName);
		this.print(navigator.userAgent);
			
		this.print("IE ? " + Browser.isIE());
		//this.print("IE6CSS ? " + isIE6CSS);
		this.print("Gecko ? " + Browser.isGecko());
	},

	getPanel: function() {
		var panel = document.getElementById(this.id);
		if (panel == null) {		
			panel= document.createElement("DIV");
			panel.id = this.id;	
			document.body.appendChild(panel);				
		}
		return panel;
	},

	print: function(msg) {		
		if (this.on != true) return;
		
		var textNode = document.createTextNode(msg);
		var breakNode = document.createElement("br");
		
		var panel = this.getPanel();
		//alert(panel);
		panel.appendChild(textNode);
		panel.appendChild(breakNode);	
		panel.scrollTop = 3000000;
	}
}

INITIALIZER.add(Debug.setup.bind(Debug));


/****************************************************************************************
***	PNG support for IE ******************************************************************
****************************************************************************************/
var IE = {};

IE.PNG = {
		init: function() {
			this.doDescendentImages(document);
			this.doDescendentBackgrounds(document.body);
		},

		doDescendentImages: function(root) {
			if (!Browser.needsPNGHack()) return;
	
			//images
			var imgs = root.getElementsByTagName("IMG");
			//and thyself
			if (root.tagName == "IMG") {
				this._doImage(root);
			}
	
			for (var i=0; i < imgs.length; i++) {
				this._doImage(imgs[i]);		
			}
		},		

		doDescendentBackgrounds: function (root) {
			if (!Browser.needsPNGHack()) return;

			//background images (eek!)
            
            var all = root.all;
	
			this._doBackground(root);

			for (var i=0; i < all.length; i++) {
				this._doBackground(all[i]);		
			}
		},

		_doImage: function(elemRef) {
			if (elemRef.src.indexOf(".png") != -1) {
				Debug.print("-----------------------------");
				Debug.print("img png hack");
				Debug.print("src = " + elemRef.src);
				elemRef.style.filter = this._toAlphaLoaderString(elemRef.src);				
				elemRef.src = Assets.blankGIF;
			}
		},

		_doBackground: function(elemRef) {

			if (elemRef.currentStyle.filter != "") {
				elemRef.style.backgroundImage = "";
			}

			if (
				elemRef.currentStyle && 			
				elemRef.currentStyle.backgroundImage != 'none'
			) { 			


				//alert("block 1");
				var backUrl = elemRef.currentStyle.backgroundImage.toString();			

				//alert("block 2");
				if (backUrl.indexOf('.png') == -1) return;

				Debug.print("-----------------------------");
				Debug.print("background png div hack");

				//alert("block 3");
				var imgURL = backUrl.substring(5, backUrl.length-2);

				var preloadImage = new Image();
				preloadImage.src = imgURL;


				//alert("block 4");
				var sizingMethod = "crop";
				var elemStyle = elemRef.currentStyle;

				if (
					elemStyle.backgroundRepeat == 'repeat-y' || 
					elemStyle.backgroundRepeat == 'repeat-x'	||
					elemStyle.backgroundRepeat == 'repeat'
				) {
					sizingMethod = "scale";
				}

				if (
					elemStyle.backgroundPositionX != '0px' ||
					elemStyle.backgroundPositionY != '0px'
				) {

					

					//Debug.print("oh gawd, we need to do a hack with a div, positioned just so...");
					Debug.print("bg pos x: " + elemStyle.backgroundPositionX);
					Debug.print("bg pos y: " + elemStyle.backgroundPositionY);
					var div = document.createElement("DIV");
					div.appendChild(document.createElement("BR"));
					var divStyle = div.style;

					divStyle.position = "absolute";			
					divStyle.width = preloadImage.width;
					divStyle.height = preloadImage.height;				

					if (
						elemStyle.backgroundPositionY &&
						elemStyle.backgroundPositionY.indexOf("px") != -1
					) {
						divStyle.marginTop = elemStyle.backgroundPositionY;
					} else {				
						switch (elemStyle.backgroundPositionY) {					
							case 'bottom': 
								divStyle.marginTop =  'auto';
								divStyle.marginBottom =  preloadImage.height + 'px';
							break;


							case 'top':
								divStyle.marginTop = '0px';
								divStyle.marginBottom = 'auto';
							break;

							default:
								divStyle.marginTop = '0px';				
								divStyle.marginBottom = '0px';
							break;
						}
					}

					if (
						elemStyle.backgroundPositionX &&
						elemStyle.backgroundPositionX.indexOf("px") != -1
					) { 				
						divStyle.marginLeft = elemStyle.backgroundPositionX;
					} else {				
						switch (elemStyle.backgroundPositionX) {
							case '50%':
								divStyle.marginLeft = 'auto';
								divStyle.marginRight = 'auto';
							break;

							default: 
								divStyle.marginLeft = '0px';
								divStyle.marginRight = '0px';
							break;  
						}
					}

					Debug.print("new div width = " + divStyle.width);
					Debug.print("new div height = " + divStyle.height);
					Debug.print(
						"new div margin = " + 
						divStyle.marginTop + " " + 
						divStyle.marginRight + " " +
						divStyle.marginBottom + " " +
						divStyle.marginLeft
					);		


					divStyle.filter = this._toAlphaLoaderString(imgURL, sizingMethod);

					//if (elem.hasChildNodes()) {
					//	Debug.print("has children");
					//	elem.insertBefore(div, elem.childNodes[0]);				
					//} else {
						elemRef.appendChild(div);
					//}
				} else {		
					//alert("block 5");
					elemRef.style.filter = this._toAlphaLoaderString(imgURL, sizingMethod);
				}

				//alert("block 6");
				elemRef.style.backgroundImage = "none";//"url(style/images/blank.gif)";		


				Debug.print("PNGed: " + imgURL);
				Debug.print("sizing method is " + sizingMethod);
			}
		},

		_toAlphaLoaderString: function (imgURL, sizingMethod) {
			var sm = (sizingMethod?sizingMethod:"crop");

			return "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+ imgURL + "', sizingMethod='" + sm + "')";
		}
}

//INITIALIZER.addPriority(IE.PNG.init.bind(IE.PNG));

/*********************************************
* Background image preloader for stylesheets *
*********************************************/

var Preloader = {};

Preloader.CSSImages = {

	load:function() {
		var backgroundImages = new Array();

		try {
			var ___dummy = document.styleSheets.length;
		} catch (e) {
			Debug.print("document.styleSheets is unsupported");
			return;
		}

		for (var i=0; i < document.styleSheets.length; i++) {

			var sheet = document.styleSheets[i];
			var lastSlash = sheet.href.lastIndexOf("/");
			var rules = (Browser.isIE()?sheet.rules:sheet.cssRules);

			for (var j=0; j < rules.length; j++) {
				var bgURL = rules[j].style.backgroundImage;			
				if (bgURL && bgURL != 'none') {
					bgURL = bgURL.substring(4, bgURL.length-1);
					bgURL = sheet.href.substring(0, lastSlash) + "/" + bgURL;
					backgroundImages.push(bgURL);
				}
			}
		}

		Debug.print("-------------------------------");
		Debug.print(backgroundImages.length + " images to preload");

		for (var k=0; k < backgroundImages.length; k++) {
			var img = new Image();
			var imgURL = backgroundImages[k];

			Debug.print("Preloading image : " + imgURL);
			img.onerror = this.onError.bind(img);
			img.onload = this.onLoad.bind(img);
			img.src = imgURL;		
		}
	},

	onError: function() {
		Debug.print("Error loading " + this.src);
	},
	
	onLoad: function() {
		Debug.print("Finished loading " + this.src);
	}
}

//INITIALIZER.addLater(Preloader.CSSImages.load.bind(Preloader.CSSImages), 2000);



/*function disableTransHacks() {
	var divs = getDivByClass("transHack");

	if (!divs) return;

	for (var i=0; i < divs.length; i++) {
		divs[i].disabled = true;
		Debug.print("transHack disabled " + divs[i].id);
	}
}

INITIALIZER.addInit(disableTransHacks);
*/


/******************

	MENU NUMBERING

******************/

/*function doMenuNumbering() {


	var menus = getElementsByTagAndClass("DIV", "subMenu");

	for (var i=0; i < menus.length; i++) {
		var subMenu = menus[i];
		
		var ul = findChildByTag(subMenu, "UL");
		if (ul == null) continue;

		var listCounter = 0;
		for (var j=0; j < ul.childNodes.length; j++) {
			var li = ul.childNodes[j];
			if (li.tagName != "LI") continue;

			li.id = subMenu.id + listCounter;
			listCounter++;
		}
	}
}

INITIALIZER.add(doMenuNumbering);	  */


/**********************************

	Util

**********************************/

var EventUtil = {

	getEvent: function(evt) {
		return (evt)? evt: ((event)? event: null);
	},

	getEventSrc: function(evt) {
		var elem = null;
		evt = this.getEvent(evt);
		if (evt) {
			elem = (evt.target? evt.target : ((evt.srcElement) ? evt.srcElement : null));
		}
		return elem;
	},


	cancelEvent: function(evt) {
		if (evt.preventDefault) {
			evt.preventDefault();		
		} 
		else if (evt.returnValue) {
			evt.returnValue = false;
		}
	},

	cancelBubble: function(evt) {
		if (evt.stopPropagation) {
			evt.stopPropagation();
		}
		else {
			evt.cancelBubble = true;
		}
	},
	
	multicast: function(funcA, funcB) {
		if (!funcA) return funcB;
		if (!funcB) return funcA;
	
		return function(evt) {		
			evt = (evt != null?evt:window.event);		
			funcA.call(this, evt);
			funcB.call(this, evt);
		};
	},

	//these two half-inched from prototype (renamed and modded slighlty)
	addListener: function(elemRef, name, listener, useCapture) {    	
		useCapture = useCapture || false;
		
		if (name == 'keypress') {
			if (Browser.isSafari()) {
				elemRef.addEventListener('keydown', listener, useCapture);
				return;
			}

			if (elemRef.addEventListener) {
				elemRef.addEventListener('keypress', listener, useCapture);
			} else if (elemRef.attachEvent) {
				elemRef.attachEvent('onkeydown', listener);
			}
		} else {
			if (elemRef.addEventListener) {
				elemRef.addEventListener(name, listener, useCapture);
			} else if (elemRef.attachEvent) {
				elemRef.attachEvent('on' + name, listener);
			}
		}
	},

	removeListener: function(elemRef, name, listener, useCapture) {		
		useCapture = useCapture || false;

		if (name == 'keypress') {
			if (Browser.isSafari()) {
				elemRef.removeEventListener('keydown', listener, useCapture);
				return;
			}
			if (elemRef.removeEventListener) {
				elemRef.removeEventListener('keypress', listener, useCapture);
			} else if (elemRef.detachEvent) {
				elemRef.detachEvent('onkeydown', listener);
			}
		} else {
			if (elemRef.removeEventListener) {
				elemRef.removeEventListener(name, listener, useCapture);
			} else if (element.detachEvent) {
				elemRef.detachEvent('on' + name, listener);
			}
		}
	}
}

var Util = {

	fromSomething: function(something, value) {
		var index = value.indexOf(something);
		if (index == -1) return value;

		return value.substring(0, index) + value.substring(index+something.length, value.length);
	},

	toSomething: function(something, value) {
		return value + something;	
	},

	fromSmall:function(value) {
		return this.fromSomething("_small", value);
	},

	fromPX:function(value) {
		//Debug.print("fromPX doing " + value);
		var index = value.indexOf("px");
		if (index == -1) return value;

		return value.substring(0, index);
	},

	toPX: function(value) {
		return value + "px";
	}
}

/*function setClassSelected(elemRef, className) {
	replaceClass(elemRef, className, toSomething("Selected", className));
}

function setClassUnSelected(elemRef, className) {
	replaceClass(elemRef, toSomething("Selected", className), className);
}*/

document.getElementsByTagAndClass = function(tag, className) {
	var elems = this.getElementsByTagName(tag);
	var elemsOut = new Array();
	for (var i=0; i < elems.length; i++) {
		if (Element.isClass(elems[i], className)) {
			elemsOut.push(elems[i]);
		}
	}
	return elemsOut;
}

document.getDivByClass = function(className) {
	var divs = this.getElementsByTagName("DIV");
	var divOut = null;
	for (var i = 0; i < divs.length; i++) {
		if (Element.isClass(divs[i], className)) {
			divOut = divs[i];
			break;
		}
	}
	return divOut;
}

function findFirstTextChild(elemRef) {	
	return findChildByTag(elemRef, "#text");
}

function findChildByTag(elemRef, tagName) {
	if (elemRef && elemRef.childNodes.length != 0) {
		var nodes = elemRef.childNodes;
		for (var i=0; i < nodes.length; i++) {
			if (nodes[i].nodeName && nodes[i].nodeName == tagName) {
				return nodes[i];
			}
		}
	}
	return null;
}

function findChildByClass(elemRef, cName) {
	if (elemRef && elemRef.childNodes.length != 0) {
		var nodes = elemRef.childNodes;
		for (var i = 0; i < nodes.length; i++) {
			var node = nodes[i];
			if (nodes[i].className && node.className == cName) {
				return node;
			}
		}
	}
	return null;
}
var Element = {

// Retrieve the x coordinate of a positionable object
	getLeft:function(elemRef)  {
		var result = 0;
		var obj = elemRef;
	
		while (obj.offsetParent) {
			result += obj.offsetLeft;
			obj = obj.offsetParent;
		}

		if (Browser.isIE()) {
			result += document.body.offsetLeft;
		}

    	return parseInt(result);
	},

// Retrieve the y coordinate of a positionable object
 	getTop: function(elemRef)  {   
    
		var result = 0;
		var obj = elemRef;

		while (obj.offsetParent) {
			result += obj.offsetTop;
			obj = obj.offsetParent;
		}	
	
		//Debug.print("getElemTop: pre parseInt: " + result);
    	return parseInt(result);
    },


// Retrieve the rendered width of an element
 	getWidth:function(elemRef)  {        
		var result = 0;
		result = elemRef.offsetWidth;
    	return parseInt(result);
	},

// Retrieve the rendered height of an element
	getHeight:function(elemRef)  {
    	var result = 0;
		if (elemRef == null) return result;
		result = elemRef.offsetHeight;		
    	return parseInt(result);
	},

	getComputedStyle: function(elemRef) {
		if (window.getComputedStyle) return window.getComputedStyle(elemRef, "");
		if (elemRef.currentStyle) return elemRef.currentStyle;

		return null;
	},

	isClass: function(elemRef, className) {
		return (elemRef.className.search('(^|\\s)' + className + '(\\s|$)') != -1);
	},

	replaceClass: function(elemRef, oldClass, newClass) {
		var fullClass = elemRef.className;
		var pos = fullClass.indexOf(oldClass);
		if (pos == -1) return;

		var newFullClass = 
			fullClass.substring(0, pos) +
			newClass +
			fullClass.substr(pos + oldClass.length);

		elemRef.className = newFullClass;
	},

	setClassTo: function(elemRef, something) {
		this.replaceClass(elemRef, elemRef.className, Util.toSomething(something, elemRef.className));
	},

	setClassFrom: function(elemRef, something) {
		this.replaceClass(elemRef, elemRef.className, Util.fromSomething(something, elemRef.className));
	},

	setOpacity: function(elemRef, percentOpacity) {
		if (Browser.isIE()) {
			elemRef.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + percentOpacity + ",style=0)";
		//} else if (isGecko) {
		} else if (elemRef.style.opacity) {
			elemRef.style.opacity = percentOpacity/100;
		//Safari < 1.2 && Konqueror
		} else if (elemRef.style.KHTMLOpacity) {			
			elemRef.style.KHTMLOpacity = percentOpacity/100;
		//old mozilla and firefox
		} else if (elemRef.style.MozOpacity) {
			elemRef.style.MozOpacity = percentOpacity/100;
		} else {
			//need to add more browser support, if none then round to visible or not, PNG -> GIF stylee			
			elemRef.style.visibility = percentOpacity > 50?"visible":"hidden";			
		}	
	}
}





/****************************************************************************************
*** Timer controlled menus **************************************************************
*****************************************************************************************/


var Menu = {
		STYLE_DELAY: 1000,
		selectors: new Array(),
		createSelector: function(tag, className, something) {
			this.selectors.push(new Menu.Selector(tag, className, something));
		},
		clearSelectors: function() {			
			Debug.print("Menu.clearSelectors");
			for (var i =0; i < this.selectors.length; i++) {
				this.selectors[i].runStyleSetter();
			}
		},
		clearSelectorsExcept: function(current) {
			for (var i=0; i < this.selectors.length; i++) {
				if (this.selectors[i] == current) continue;
				this.selectors[i].runStyleSetter();
			}
		}	
	};

EventUtil.addListener(window, "click", Menu.clearSelectors.bind(Menu));

Menu.Selector = Class.create();
Menu.Selector.prototype = {

	initialize: function(tag, className, something) {
		this.tag = tag;
		this.className = className;
		this.something = something;
		this.currentElemRef = null;		
		this.currentTimerRef = null;


		var elems = document.getElementsByTagAndClass(tag, className);
		for (var i=0; i < elems.length; i++) {
			var elem = elems[i];
			EventUtil.addListener(elem, "mouseover" , this.setOver.bindWith(this, [elem]));
			EventUtil.addListener(elem, "mouseout" ,this.setOut.bindWith(this, [elem]));			
			//init
			//elem.className = this.className;
		}

		
	},

	runStyleSetter: function() {				
		if (this.currentElemRef != null) {
			Debug.print("runStyleSetter for id: " + this.currentElemRef.id + " and class: " + this.className);
			this.currentElemRef.className = this.className;			
			this.currentElemRef = null;
			this._clearTimerRef();
		}		
	},

	_clearTimerRef: function() {
		if (this.currentTimerRef != 0) {
			Debug.print("clear timeout");
			clearTimeout(this.currentTimerRef);
			this.currentTimerRef = 0;
		}
	},
	
	setOver: function(elemRef) {
		//var elemRef = EventUtil.getEventSrc(evt);		
		Debug.print("-----");
		Debug.print("setOver : " + elemRef.id + " with style " + this.className + this.something);
		//always clear any timers
		//Menu.clearSelectorsExcept(this);
		this._clearTimerRef();
		//clears out the old one, it is exists.
		//if old one is null, or different element then we do it.
		if (!this.currentElemRef || this.currentElemRef !== elemRef) {
			Debug.print("no currentElem(" + (!this.currentElemRef) + ") or current and elemRef different");
			//do old one
			this.runStyleSetter();			
			elemRef.className = this.className + this.something;
		} else {
			Debug.print("currentElem that is the same");
		}
	},

	setOut: function(elemRef) {
		//var elemRef = EventUtil.getEventSrc(evt);
		Debug.print("setOut : " + elemRef.id + " with style " + this.className);
		this.currentElemRef = elemRef;				
		Debug.print("Set timeout");
		this.currentTimerRef = setTimeout(this.runStyleSetter.bind(this), Menu.STYLE_DELAY);
	}
}


