/*  Prototype JavaScript framework
 *  (c) 2005 Sam Stephenson <sam@conio.net>
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://prototype.conio.net/
/*--------------------------------------------------------------------------*/

//note: modified & stripped down version of prototype, to be used with moo.fx by mad4milk (http://moofx.mad4milk.net).
// modified by troels@kyberfabrikken.dk
function bind(object, fnc) {
	if (typeof(fnc) == "string") {
		fnc = object[fnc];
	}
	var args = [];
	for (var i=2; i<arguments.length; ++i) {
		args.push(arguments[i]);
	}
	return function() {
		var args2 = [];
		for (var i = 0; i < arguments.length; i++) {
			args2.push(arguments[i]);
		}
		return fnc.apply(object, args.concat(args2));
	}
}

function bindAsEventListener(object, fnc) {
	if (typeof(fnc) == "string") {
		fnc = object[fnc];
	}
	return function(event) {
		return fnc.apply(object, [event || window.event]);
	}
}

function allChildNodes(elm) {
	var result = [];
	for (var i = 0, c = elm.childNodes; i < c.length; ++i) {
		result.push(c[i]);
		if (c[i].childNodes && c[i].childNodes.length > 0) {
			for (var child in allChildNodes(c[i])) {
				result.push(child);
			}
		}
	}
	return result;
}


var Class = {
	create: function() {
		return function() {
			this.initialize.apply(this, arguments);
		}
	}
}

Object.extend = function(destination, source) {
	for (property in source) destination[property] = source[property];
	return destination;
}

Function.prototype.bind = function(object) {
	var __method = this;
	return function() {
		return __method.apply(object, arguments);
	}
}

Function.prototype.bindAsEventListener = function(object) {
var __method = this;
	return function(event) {
		__method.call(object, event || window.event);
	}
}

if (!window.Element) var Element = new Object();

Object.extend(Element, {
	remove: function(element) {
		element = $(element);
		element.parentNode.removeChild(element);
	},

	hasClassName: function(element, className) {
		element = $(element);
		if (!element) return;
		var hasClass = false;
		$i(element.className.split(' ')).each(function(cn){
			if (cn == className) hasClass = true;
		});
		return hasClass;
	},

	addClassName: function(element, className) {
		element = $(element);
		Element.removeClassName(element, className);
		element.className += ' ' + className;
	},

	removeClassName: function(element, className) {
		element = $(element);
		if (!element) return;
		var newClassName = '';
		$i(element.className.split(' ')).each(function(cn, i){
			if (cn != className){
				if (i > 0) newClassName += ' ';
				newClassName += cn;
			}
		});
		element.className = newClassName;
	},

	cleanWhitespace: function(element) {
		element = $(element);
		$i(element.childNodes).each(function(node){
			if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) Element.remove(node);
		});
	},

	find: function(element, what) {
		element = $(element)[what];
		while (element.nodeType != 1) element = element[what];
		return element;
	}
});

function $() {
	if (arguments.length == 1) return get$(arguments[0]);
	var elements = [];
	$i(arguments).each(function(el){
		elements.push(get$(el));
	});
	return elements;

	function get$(el){
		if (typeof el == 'string') el = document.getElementById(el);
		return el;
	}
}

document.getElementsByClassName = function(className) {
	var children = document.getElementsByTagName('*') || document.all;
	var elements = [];
	$i(children).each(function(child){
		if (Element.hasClassName(child, className)) elements.push(child);
	});
	return elements;
}
$c = document.getElementsByClassName;

//useful array functions
function $i(array){
	var nArray = [];
	nArray.each = function(func){
		for(var i=0;ob=this[i];i++) func(ob, i);
	}
	for (i=0;el=array[i];i++) nArray.push(el);
	return nArray;
}

function popwin(anchor, height, width) {
	if (typeof(height) == "undefined") {
		height = 346;
	}
	if (typeof(width) == "undefined") {
		width = 489;
	}
	var d = window.open(anchor.href, "puppy", "toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width="+width+",height="+height);
	d.focus();
	return false;
}

function getAjax(url, callback) {
	var httpRequest = false;

	if (window.XMLHttpRequest) {
		httpRequest = new XMLHttpRequest();
//		if (httpRequest.overrideMimeType) httpRequest.overrideMimeType('text/xml');
		if (httpRequest.overrideMimeType) httpRequest.overrideMimeType('text/html');
	} else if (window.ActiveXObject) {
		try {
			httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try {
				httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e) {}
		}
	}

	if (!httpRequest) return false;

	httpRequest.onreadystatechange = function() {
		if (httpRequest.readyState == 4) {
			if (httpRequest.status == 200) {
				eval(callback);
			} else {
				alert('Error: ' + httpRequest.status);
			}
		}
	}
	httpRequest.open('GET', url, true);
	httpRequest.send(null);
}

/**
  * @package Position
  *
  * Contains various crossbrowser adapters and low-level utilities
  */
if (typeof Position == "undefined") {
	Position = {};
}

/** This function will return an Object with x and y properties of the element */
Position.getPosition = function(elm) {
	var offset = Position.cumulativeOffset(elm);
	return { x : offset[0], y : offset[1] }
};

Position.cumulativeOffset = function(element) {
	var valueT = 0, valueL = 0;
	do {
		valueT += element.offsetTop  || 0;
		valueL += element.offsetLeft || 0;
		element = element.offsetParent;
	} while (element);
	return [valueL, valueT];
};

/** Surprisingly it returns the x,y position of the mouse */

Position.getMousePosition = function(e) {
	if (!e) var e = window.event;
	if (e.pageX || e.pageY) {
		return {
			x : e.pageX,
			y : e.pageY
		}
	} else if (e.clientX || e.clientY) {
		return {
			x : e.clientX + Math.max(document.body.scrollLeft, document.documentElement.scrollLeft),
			y : e.clientY + Math.max(document.body.scrollTop, document.documentElement.scrollTop)
		}
	}
	return {
		x : 0,
		y : 0
	}
};

/**
  * The inner dimensions of the window or frame.
  * Straight out of : http://www.quirksmode.org/viewport/compatibility.html
  */
Position.getScreenDimensions = function() {
	var x,y;
	if (self.innerHeight) {
		// all except Explorer
		x = self.innerWidth;
		y = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) {
		// Explorer 6 Strict Mode
		x = document.documentElement.clientWidth;
		y = document.documentElement.clientHeight;
	}
	else if (document.body) {
		// other Explorers
		x = document.body.clientWidth;
		y = document.body.clientHeight;
	}
	return {
		width : x,
		height : y
	}
}

/**
  * The inner dimensions of the document.
  * Straight out of : http://www.quirksmode.org/viewport/compatibility.html
  */
Position.getPageDimensions = function() {
	var x,y;
	var test1 = document.body.scrollHeight;
	var test2 = document.body.offsetHeight
	if (test1 > test2) {
		// all but Explorer Mac
		x = document.body.scrollWidth;
		y = document.body.scrollHeight;
	} else {
		// Explorer Mac;
		//would also work in Explorer 6 Strict, Mozilla and Safari
		x = document.body.offsetWidth;
		y = document.body.offsetHeight;
	}
	return {
		width : x,
		height : y
	}
}

/**
  * This function will return an Object with width and height properties of the element.
  * Messaurements does NOT include borders and padding. (content-box)
  */
Position.getDimensions = function(elm) {
	var bp = Position.getBorderPadding(elm);
	return {
		width  : elm.offsetWidth - (bp.borderWidth + bp.paddingWidth),
		height : elm.offsetHeight - (bp.borderHeight + bp.paddingHeight)
	}
};

/**
  * Returns the actual border and padding of an element.
  * @param elm HTMLElement
  */
Position.getBorderPadding = function(elm) {
	var cs = Position.getCurrentSize(elm);
	if (elm.currentStyle) {
		var thin = 2;
		var medium = 4;
		var thick = 6;
	} else {
		var thin = 1;
		var medium = 3;
		var thick = 5;
	}
	// this isn't entirely precise, since the actual pixel-sizes may differ from browser to browser.
	// they are however the defaults for internet explorer 6sp2 and firefox 1.0, windows xp
	var tmpFunc = function(val) {
		val = parseInt(val);
		if (isNaN(val)) {
			switch (val) {
			case "thin" : return thin;
			case "medium" : return medium;
			case "thick" : return thick;
			}
			return 1;
		} else {
			return val;
		}
	};

	return {
		borderWidth  : tmpFunc(cs.borderLeftWidth) + tmpFunc(cs.borderRightWidth),
		borderHeight : tmpFunc(cs.borderTopWidth) + tmpFunc(cs.borderBottomWidth),
		paddingWidth : tmpFunc(cs.paddingLeft) + tmpFunc(cs.paddingRight),
		paddingHeight: tmpFunc(cs.paddingTop) + tmpFunc(cs.paddingBottom)
	}
};

Position.getCurrentSize = function(elm) {
	if (elm == null) throw new Error("Argument is not an HTMLElement");
	if (elm.currentStyle) {
		return elm.currentStyle;
	} else {
		var cs = document.defaultView.getComputedStyle(elm,'');
		return {
			paddingLeft  : cs.getPropertyValue('padding-left'),
			paddingRight : cs.getPropertyValue('padding-right'),
			borderLeftWidth : cs.getPropertyValue('border-left-width'),
			borderRightWidth: cs.getPropertyValue('border-right-width'),
			marginLeft  : cs.getPropertyValue('margin-left'),
			marginRight : cs.getPropertyValue('margin-right'),

			paddingTop  : cs.getPropertyValue('padding-top'),
			paddingBottom : cs.getPropertyValue('padding-bottom'),
			borderTopWidth : cs.getPropertyValue('border-top-width'),
			borderBottomWidth: cs.getPropertyValue('border-bottom-width'),
			marginTop  : cs.getPropertyValue('margin-top'),
			marginBottom : cs.getPropertyValue('margin-bottom')
		}
	}
};
