/* 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|$)");
	var i = 0;
	var j = 0;
	do{
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}while(++i<elsLen)	
	return classElements;
}

/* toggle an element's display */
function toggle(obj) {
	var el = document.getElementById(obj);
	//alert(el);
	if(el){
		el=el.style;
		//alert(']'+el+'[')
//you would use switch for more optimization, but i think is ininfluent due to the shorten dom trick already used. <kenta>		
		if ( el.display != 'none' ) {
			//alert('ok');
			el.display = 'none';
		}
		else {
			el.display = '';
		}
	}
}

/* insert an element after a particular node */
/*function insertAfter(parent, node, referenceNode) {
	parent.insertBefore(node, referenceNode.nextSibling);
}*/
function insertAfter(parent, node, referenceNode){ 

if(referenceNode.nextSibling)
	{ 
		parent.insertBefore(node, referenceNode.nextSibling); 
	} 
else 
	{ 
		parent.appendChild(node); 
	} 
}
/*
I prefer the following form ;) however this function throw an error when node.parentNode don't exist (eg.when you don't pass a DOM-Node ;)

function insertAfter2(node, referenceNode){ 

if(referenceNode.nextSibling)
	{ 
		referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling); 
	} 
else 
	{ 
		referenceNode.parentNode.appendChild(node); 
	} 
}
*/
/* Array prototype, matches value in array: returns bool */
Array.prototype.inArray = function (value) {	

	var i=this.length-1;
	if(i>-1)
		do
		{
			//alert('i'+i+')'+this[i])
			if (this[i] === value) {
				return true;
			}
		}
		while(--i>-1);		
		
	return false;
};

/* get, set, and delete cookies */
function getCookie( name ) {
	var cook=document.cookie
	var start = cook.indexOf( name + "=" );
	var len = start + name.length + 1;
	if ( ( !start ) && ( name != cook.substring( 0, name.length ) ) ) {
		return null;
	}
	if ( start == -1 ) return null;
	var end = cook.indexOf( ";", len );
	if ( end == -1 ) end = cook.length;
	return unescape( cook.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;
		expires*=86400000;
	}
	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";
}

/* quick getElement reference */
function $() {
	var elements = new Array();
	
	var endloop=arguments.length;
	var i=0;
	switch (endloop){
	
		case 0: return null;break;// this is just done in default branch but you wouldn't expected a empty array,so i leave it<kenta>
		case 1: 
		var element = arguments[0];
			if (typeof element == 'string')
				return document.getElementById(element)
			else return element;
		break;
		default:
		var element;
			while(i<endloop)
			{
				element = arguments[i];
				if (typeof element == 'string')
					element = document.getElementById(element);
				elements.push(element);
				++i;
			}			
		break;
	}	
	return elements;
}


// written by Federico Bianco Prevot
function clamp(current_value, bottom_value, top_value) {
	return Math.min(Math.max(bottom_value,current_value),top_value);
}

// written by Dean Edwards, 2005
// with input from Tino Zijdel
// http://dean.edwards.name/weblog/2005/10/add-event/

function addEvent(element, type, handler) {
	// assign each event handler a unique ID
	if (!handler.$$guid) handler.$$guid = addEvent.guid++;
	// create a hash table of event types for the element
	if (!element.events) element.events = {};
	// create a hash table of event handlers for each element/event pair
	var handlers = element.events[type];
	if (!handlers) {
		handlers = element.events[type] = {};
		// store the existing event handler (if there is one)
		if (element["on" + type]) {
			handlers[0] = element["on" + type];
		}
	}
	// store the event handler in the hash table
	handlers[handler.$$guid] = handler;
	// assign a global event handler to do all the work
	element["on" + type] = handleEvent;
};
// a counter used to create unique IDs
addEvent.guid = 1;

function removeEvent(element, type, handler) {
	// delete the event handler from the hash table
	if (element.events && element.events[type]) {
		delete element.events[type][handler.$$guid];
	}
};

function handleEvent(event) {
	var returnValue = true;
	// grab the event object (IE uses a global event object)
	event = event || fixEvent(window.event);
	// get a reference to the hash table of event handlers
	var handlers = this.events[event.type];
	// execute each event handler
	for (var i in handlers) {
		this.$$handleEvent = handlers[i];
		if (this.$$handleEvent(event) === false) {
			returnValue = false;
		}
	}
	return returnValue;
};

function fixEvent(event) {
	// add W3C standard event methods
	event.preventDefault = fixEvent.preventDefault;
	event.stopPropagation = fixEvent.stopPropagation;
	return event;
};
fixEvent.preventDefault = function() {
	this.returnValue = false;
};
fixEvent.stopPropagation = function() {
	this.cancelBubble = true;
};

