/* addEvent: simplified event attachment */
function addEvent( obj, type, fn ) 
{
	if (obj.addEventListener) 
	{
		obj.addEventListener( type, fn, false );
		EventCache.add(obj, type, fn);
	}
	else if (obj.attachEvent) 
	{
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
		obj.attachEvent( "on"+type, obj[type+fn] );
		EventCache.add(obj, type, fn);
	}
	else 
	{
		obj["on"+type] = obj["e"+type+fn];
	}
}
	
/* window 'load' attachment */
function addLoadEvent(func) 
{
	var oldonload = window.onload;
	if (typeof window.onload != 'function') 
	{
		window.onload = func;
	}
	else 
	{
		window.onload = function() 
		{
			oldonload();
			func();
		}
	}
}

/* grab Elements from the DOM by className */
function getElementsByClass(searchClass,node,tag) 
{
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
	for (i = 0, j = 0; i < elsLen; i++) 
	{
		if ( pattern.test(els[i].className) ) 
		{
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

/* toggle an element's display */
function toggle(obj) 
{
	var el = document.getElementById(obj);
	if ( el.style.display != 'none' ) {
		el.style.display = 'none';
	}
	else 
	{
		el.style.display = '';
	}
}

/* insert an element after a particular node */
function insertAfter(parent, node, referenceNode) 
{
	parent.insertBefore(node, referenceNode.nextSibling);
}

/* Array prototype, matches value in array: returns bool */
Array.prototype.inArray = function (value) 
{
	var i;
	for (i=0; i < this.length; i++) {
		if (this[i] === value) {
			return true;
		}
	}
	return false;
};

/* get, set, and delete cookies */
function getCookie( name ) 
{
	var start = document.cookie.indexOf( name + "=" );
	var len = start + name.length + 1;
	if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
		return null;
	}
	if ( start == -1 ) return null;
	var end = document.cookie.indexOf( ";", len );
	if ( end == -1 ) end = document.cookie.length;
	return unescape( document.cookie.substring( len, end ) );
}
	
function setCookie( name, value, expires, path, domain, secure ) 
{
	var today = new Date();
	today.setTime( today.getTime() );
	if ( expires ) {
		expires = expires * 1000 * 60 * 60 * 24;
	}
	var expires_date = new Date( today.getTime() + (expires) );
	document.cookie = name+"="+escape( value ) +
		( ( expires ) ? ";expires="+expires_date.toGMTString() : "" ) + //expires.toGMTString()
		( ( path ) ? ";path=" + path : "" ) +
		( ( domain ) ? ";domain=" + domain : "" ) +
		( ( secure ) ? ";secure" : "" );
}
	
function deleteCookie( name, path, domain ) 
{
	if ( getCookie( name ) ) document.cookie = name + "=" +
			( ( path ) ? ";path=" + path : "") +
			( ( domain ) ? ";domain=" + domain : "" ) +
			";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}

/**
 * Remove leading and trailing whitespace from a String
 */
String.prototype.trim = function() {
	return this.replace(/^\s+/,'').replace(/\s+$/,'');
}

/**
 * A very basic function to remove HTML tags from a string.
 * Inline <script> and <style> areas are also removed, and excess whitespace
 * is trimmed
 */
String.prototype.stripTags = function() {
	return this.replace(/<(script|style).*?>[^\t]*?<\/\s*\1>/gi,'').replace(/<\/?.*?>/gi,'').replace(/\s{2,}/g,' ');
}

/**
 * Converts all <br> or <br/> tags into newline characters
 */
String.prototype.br2nl = function() {
	return this.replace(/<br\s*\/?>/gi,"\n");
}

/**
 * Converts all newline characters into <br> tags
 *
 * @TODO: detect if page is rendered as XHTML, and use the proper tag
 */
String.prototype.nl2br = function() {
	return this.replace(/\r?\n/gi,"<br>");
}

/**
 * Checks if the array contains the passed value. This method performs
 * an exact match, types must also match
 *
 * @param value The value to check for
 */
Array.prototype.contains = function(value) {
	var result = false;
	for(var property in this) {
		if (this[property] === value) {
			result = true;
			break;
		}
	}
	return result;
}

function cloneCSS ( srcObj, destObj )
{
	if ( ( typeof(srcObj.style) != "undefined" ) && ( typeof(destObj.style) != "undefined" ) )
	{
		destObj.className = srcObj.className;
		if (window.getComputedStyle)
		{
		    var srcStyle = window.getComputedStyle(srcObj,null);
		    var val;
		    for(var s in srcObj.style) {
		        if ( parseInt(s).toString() == s ) continue;
		        if (s == 'length') continue;
				if ( ( typeof(srcObj.style[s]) != "function" ) && ( typeof(srcObj.style[s]) != "object" ) )
				{
				    try
				    {
						val = srcStyle.getPropertyValue(s);
						if (val) destObj.style[s] = val;
						else destObj.style[s] = srcObj.style[s];
					}
					catch(e)
					{
						// NOOP, just to prevent runtime errors
					}
				}
			}
		}
		else if (srcObj.currentStyle)
		{
		    var val;
		    for(var s in srcObj.style) {
		        if ( parseInt(s).toString() == s ) continue;
		        if (s == 'length') continue;
				if ( typeof(srcObj.style[s]) != "function" )
				{
				    try
				    {
						val = srcObj.currentStyle[s];
						if (val) destObj.style[s] = val;
						else destObj.style[s] = srcObj.style[s];
					}
					catch(e)
					{
					    // NOOP, just to prevent runtime errors
					}
				}
			}
		}
		else
		{
		    for(var s in srcObj.style) {
		        if ( parseInt(s).toString() == s ) continue;
		        if (s == 'length') continue;
				if ( typeof(srcObj.style[s]) != "function" )
				{
				    try
				    {
						destObj.style[s] = srcObj.style[s];
					}
					catch(e)
					{
						// NOOP, just to prevent runtime errors
					}

				}
			}
		}
	}
}

function checkbox_max(checkbox, max)
{
	var count = 0;
	var unchecked = new Array();
	for ( var i = 0; i < checkbox.form.elements.length; i++ )
	{
		if ( checkbox.form.elements[i].name == checkbox.name )
		{
			if ( checkbox.form.elements[i].checked )
			{
				count ++;
			}
			else
			{
			    unchecked.push(checkbox.form.elements[i]);
			}
		}
	}
	if ( count >= max )
	{
	    for ( i = 0; i < unchecked.length; i++ )
		{
		    unchecked[i].disabled = true;
		}
	}
	else
	{
	    // enable all
		for ( i = 0; i < checkbox.form.elements.length; i++ )
		{
			if ( checkbox.form.elements[i].name == checkbox.name )
			{
			    checkbox.form.elements[i].disabled = false;
			}
		}
	}
}
