/********************************/
/* Eliteology Limited 2006-2007 */
/* www.eliteology.com			*/
/********************************/

/* string prototypes */
String.prototype.startsWith = function(prefix){return (this.substr(0,prefix.length)==prefix);}
String.prototype.trim = function(){return this.trimRight().trimLeft();}
String.format = function(format){for (var i=1;i<arguments.length;i++){format=format.replace("{"+(i -1)+"}",arguments[i]);} return format;}
String.prototype.HTMLEntities = [ ["&", "&amp;"], ["<", "&lt;"], [">", "&gt;"], ["'", "&#039;"], ['"', "&quot;"] ];
String.prototype.HTMLEncode = function() { var i, a, s, re; s = this; a = "".HTMLEntities; for (i=0; i<a.length; i++) { re = new RegExp(a[i][0], "g"); s = s.replace(re, a[i][1]); } return s; }
String.prototype.HTMLDecode = function() { var i, a, s, re;	s = this; a = "".HTMLEntities; for (i=0; i<a.length; i++) { re = new RegExp(a[i][1], "g"); s = s.replace(re, a[i][0]); } return s; }

/* array prototypes */
Array.prototype.clear = function(){if (this.length >0){this.splice(0,this.length);}}
Array.prototype.clone = function(){var clonedArray =[];var length =this.length;for (var index =0;index <length;index++){clonedArray[index]=this[index];} return clonedArray;}
Array.prototype.contains = function(item){var index =this.indexOf(item);return (index >=0);}
Array.prototype.indexOf = function(item){var length =this.length;if (length !=0){for (var index =0;index <length;index++){if (this[index]==item){return index;}} } return -1;}
Array.prototype.insert = function(index,item){this.splice(index,0,item);}
Array.prototype.queue = function(item){this.push(item);}
Array.prototype.remove = function(item){var index =this.indexOf(item);if (index >=0){this.splice(index,1);}}
Array.prototype.removeAt = function(index){this.splice(index,1);}

/* function prototypes */
Function.prototype.sliceArguments = function(from, to) { var args = []; to =(to) ? to : this.arguments.length; for(var i=0; i<this.arguments.length; i++) { if (i>=from && i<=to) args.push(this.arguments[i]); } return args; }

/* cross browser support object */
var support = {

	version	: "1.4.2",
	
	/* obtain parent element/container */
	getReal	:	function(el, type, value)
	{
		var tmp = el;
		while ((tmp != null) && (tmp.tagName.toLowerCase() != "body")) 
		{
			if ((eval("tmp." + type) == value) || (eval("tmp." + type + ".indexOf('"+ value +"')") >-1)) {el = tmp; return el;}
			tmp = tmp.parentNode;
		};
		return el;
	},
	
	/* get a list of elements based on there name attribute */
	getElementsByName :	 function(node, name)
	{
		var a = [];
		node = (node) ? node:document;
		var els = node.getElementsByTagName("*");
		
		for(var i=0,j=els.length; i<j; i++)
		{
			if (els[i].name==name) a.push(els[i]);
		};
		
		return a;
	},
	 
	/* retrive a list of elements by type */
	getElementsByType	:	function(node, types)
	{
		node		= (node) ? node:document;
		var aReturn	= new Array();
		var els		= node.getElementsByTagName("*");
		var aTypes	= types.split(",");
		
		for(var i=0;i<els.length; i++)
		{
			for (var ii=0; ii<aTypes.length; ii++)
			{
				if (els[i].nodeName.toLowerCase()==aTypes[ii].toLowerCase())
				{
					aReturn.push(els[i]);
				}
			}
		};
		
		return aReturn;
	},
	
	/* retrive a list of elements based on assigned class */
	getElementsByClassName	:	function(node, classname)
	{
		var a = new Array();
		node = (node) ? node : document;
				
		var re = (typeof(classname)=="object") ? classname : new RegExp('(^| )'+classname+'( |$)'); 
		var els = node.getElementsByTagName("*");
		for(var i=0,j=els.length; i<j; i++)
		{
			if(re.test(els[i].className))
			{
				a.push(els[i]);
			}
		};

		return a;
	},
	
	/* retrive a list of elements based on assigned class */
	getElementByClassName : function(node, classname)
	{
		node = (node) ? node : document;
				
		var re = (typeof(classname)=="object") ? classname : new RegExp('(^| )'+classname+'( |$)'); 
		var els = node.getElementsByTagName("*");
		for(var i=0,j=els.length; i<j; i++)
		{
			if(re.test(els[i].className))
			{
				return els[i]
			}
		};
	},
	
	/* return position of element */
	getPos : function(el)	
	{
		var x=0, y=0, w=0, h=0; 
	
		if (document.getBoxObjectFor)
		{ 
			var bo = document.getBoxObjectFor(el); 
			return {x:bo.x, y:bo.y, w:bo.width, h:bo.height}
		} 
		else if (el.getBoundingClientRect)
		{
			var rect = el.getBoundingClientRect(); 
			return {x:rect.left, y:rect.top, w:(rect.right - rect.left), h:(rect.bottom - rect.top)}
		}
		else
		{
			w = el.offsetWidth;
			h = el.offsetHeight;
			do { x += el.offsetLeft || 0; y += el.offsetTop || 0; el = el.offsetParent; } while (el);
			return {x:x, y:y, w:w, h:h}
		}
	},
	
	/* check if (b) is contained within (a) */
	contains : function(a,b)	
	{
 		while((a!=b) && (b.tagName.toLowerCase()!="body") && (b!=null)) b = b.parentNode;
		return (a==b);
	},
	
	/* this method is increadibly slow and needs rewriting */
	getElementsByAttribute	:	function(sProperty, sValue)
	{
		var aReturn = [];
		var els = document.getElementsByTagName("*");	
	
		for (var i=0; i<els.length; i++)
		{
			if (els[i].attributes)
			{
				for (var ii=0; ii<els[i].attributes.length; ii++)
				{
					if ( ( els[i].attributes[ii].nodeName == sProperty ) && ( els[i].attributes[ii].nodeValue == sValue ) )
					{
						aReturn.push(els[i]);
					}
				}
			}
		}

		return aReturn;
	},

	/* xSupport.createElement('div', {class: 'myDivCSSClass', id: 'myDivId'}{position: 'absolute', left: '300px', top: '200px'}, 'This is the first text of the rest of this code')); */
	createElement : function(parent, name, attrs, style, text)
	{
		var e = document.createElement(name);
		if (attrs)
		{
			for (key in attrs)
			{
				if (key=="class") e.className = attrs[key];
				else if	(key=="id") e.id = attrs[key];
				else e.setAttribute(key, attrs[key]);
			}
		}
		if (style)
		{
			for (key in style) e.style[key] = style[key];
		}
		if (text) e.appendChild(document.createTextNode(text));
		if (parent) parent.appendChild(e);
		
		return e;
	},
    
    viewport : function()
    {
        return {
            height : (document.body.clientHeight || document.documentElement.clientHeight || window.innerHeight || 0),
            width : (document.body.clientWidth || document.documentElement.clientWidth || window.innerWidth || 0),
            scrollX : (document.body.scrollLeft || document.documentElement.scrollLeft || self.pageXOffset || 0),
            scrollY : (document.body.scrollTop || document.documentElement.scrollTop || self.pageYOffset || 0)
        };
    },
    
	$ : function()
	{
		var els = new Array();
		for (var i = 0; i < arguments.length; i++)
		{
	        var element = arguments[i];
			if (typeof element == 'string') element = document.getElementById(element);
			if (arguments.length == 1) return element;
			els.push(element);
		}
		return els;
	},
	
	previousSibling : function(n)
	{
		var x=(n) ? n.previousSibling : null;
		while ((x) && (x.nodeType!=1))
		{
			x=x.previousSibling;
		}
		return x;
	},

	nextSibling : function(n)
	{
		var x=(n) ? n.nextSibling : null;
		while ((x) && (x.nodeType!=1))
		{
			x=x.nextSibling;
		}
		return x;
	},
	
	getStyle : function(el, style)
	{
		if (el.currentStyle)
		{
			return el.currentStyle[style];
		}
		else if (window.getComputedStyle)
		{
			var elstyle=window.getComputedStyle(el, "");
			return elstyle.getPropertyValue(style);
		}
		return "auto";
	},
	
	addStyleRule : function(selector, styles, index)
	{
		index = !index? 0 : index; ss = document.styleSheets[index];
		if(ss.insertRule)   ss.insertRule(selector+' {'+styles+'}', ss.cssRules.length);
		else if(ss.addRule) ss.addRule(selector,styles);
		else return false; return true;
	}
}