/* ============== */
/* === EVENTS === */
/* ============== */

/* === addEvent/removeEvent written by Dean Edwards (2005) with input from Tino Zijdel, Matthias Miller, Diego Perini: http://dean.edwards.name/weblog/2005/10/add-event/ === */
function addEvent( element, type, handler ) {
	if ( !element ) element = window;	// fix: sometimes element does not seem to exist, even though one is passed
	if ( element.addEventListener ) {
		element.addEventListener( type, handler, false );
	} else {
		// 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) {
	if ( element.removeEventListener ) {
		element.removeEventListener( type, handler, false );
	} else {
		// 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( (( this.ownerDocument || this.document || this ).parentWindow || 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;
};
/* --- /addEvent/removeEvent --- */

function stopDefault( e ) {
	if ( e && e.preventDefault ) e.preventDefault();	// Prevent default browser action (W3C)
	else window.event.returnValue = false;					// IE version
	return false;
}

function normEvent( e ) {
	e = e || window.event;
	if ( !e.target ) e.target = e.srcElement;
	return e;
}

/////////////////////// elements and classes /////////////////////

function id( name ) {
	return document.getElementById( name );	// -> HTML element
};

function withClass( name, sel, sel2 ) {														// sel and sel2 are both optional and can be either an element or a tag (one of each)
	var haveClass = [];
	var regExp = new RegExp( "(^|\\s)" + name + "(\\s|$)" );								// allows for multiple class names
	var tagName = sel.constructor == String ? sel : sel2;
	var elem = sel.constructor == String ? sel2 : sel;
	var elements = ( elem || document).getElementsByTagName( tagName || "*" );		// use document if no element has been specified and get all elements if no tag name has been specified
	for ( var e = 0; e < elements.length; e++) {
		var element = elements[ e ];
		if ( hasClass( element, name )) haveClass[ haveClass.length ] = element;
	}
	return haveClass;																					// -> Array
};

function hasClass( elem, name ) {
	if ( !name && elem.className != "") return true; // if no className has been specified any className will do | -> Boolean
	var regExp = new RegExp( "(^|\\s)" + name + "(\\s|$)" ); // allows for multiple class names
	if ( regExp.test( elem.className )) return true; // -> Boolean
	return false; // -> Boolean
}; 
	
function addClass( elem, name ) {
	addToAttr( elem, "className", name );
}

function removeClass( elem, name ) {
	removeFromAttr( elem, "className", name );
}
function addToAttr( elem, attr, value ) {	// can be used for class, rel and rev attributes
	removeFromAttr( elem, attr, value );	// make sure there won't be any doubles
	elem[ attr ] += " " + value;
}

function removeFromAttr( elem, attr, value ) {									// can be used for class, rel and rev attributes
	var remain = [];
	var values = elem[ attr ].split(/\s+/);										// seperate class names (devided by one or more whitespaces)
	for ( var v = 0; v < values.length; v++ ) {
		if ( values[ v ] != value ) remain[ remain.length ] = values[ v ];
	}
	elem[ attr ] = remain.join( " " );
}


function tag( name, elem ) {
	return ( elem || document ).getElementsByTagName( name );	// -> Array
};

///////////// INIT CLICKABLE ITEMS /////////////

/* --- clickableItems --- make entire itemes clickable --- */
function initClickableItems(divClass,parentId, clickableTags) {
	var content = id( parentId );
	if ( content ) {
		var items;
		items = withClass( divClass, "div", content );
		if ( items && items.length > 0 ) clickAllOver( items , clickableTags );
	}
}

function initClickableItemsLi(liClass,parentId, clickableTags) {
	var content = id( parentId );
	if ( content ) {
		var items;
		items = withClass( liClass, "li", content );
		if ( items && items.length > 0 ) clickAllOver( items , clickableTags );
	}
}

/* --- clickAllOver --- */
function clickAllOver( elems , clickableTags ) {													// elem can be a single element or an array of elements
	var items = ( elems.constructor == Array ) ? elems : [ elems ];	// if elem is a single element, put it in an array
	for ( var i = 0; i < items.length; i++ ) {
		var item = items[ i ];
		
		item.getUrl = function() {
			var url = tag( "a", this )[0];
			return ( url ) ? url.href : false; 
		}
		itemUrl=item.getUrl();
		
		/* if ( !itemUrl ) return; */
		if ( itemUrl ) {
		
			item.getTarget = function() {
				var url = tag( "a", this )[0];
				return ( url ) ? url.target : false; 
			}
			itemTarget=item.getTarget();
			if(clickableTags){
				clickableItems=clickableTags;
			}else{
				clickableItems=['img','p', 'h3'];
				/* clickableItems=['img','p']; */
			}
			for(ci=0;ci<clickableItems.length;ci++){
				elements=tag( clickableItems[ci], item );
				for(ti=0;ti<elements.length;ti++){
					clickableItem=elements[ti];
					if(clickableItem.className=='noneClickable'){
						continue;
					}
					clickableItem.url=itemUrl;
					clickableItem.target=itemTarget;
					addEvent( clickableItem, "click", function() { 
					    if(this.target && this.target=='_blank'){
					        window.open(this.url,'');
					    }else{
					        window.location.href = this.url;
					    } 
					});
				}
			}
			addEvent( item, "mouseover", function() { addClass( this, "jsHoverItem" )} );
			addEvent( item, "mouseout", function() { removeClass( this, "jsHoverItem" )} );
		}
	}
}
