/* --- JavaScript --- */
/* ---- main.js ----- */

/* ============== */
/* === 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.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;
}

/* =========== */
/* === DOM === */
/* =========== */

function domReady( f ) {
	if ( domReady.done ) return f();							// If DOM is already loaded, execute the function right away
	
	if ( domReady.timer ) {										// If wwe've already added a function
		domReady.ready.push( f );								// Add it to the list of functions to execute
	} else {
		addEvent( window, "load", isDOMReady );			// Attach an event for when the page finishes loading, just in case it finishes first.
		domReady.ready = [ f ];									// Initialize the array of functions to execute;
		domReady.timer = setInterval( isDOMReady, 200 );	// Check to see if the DOM is ready as quickly as possible
	}
}

function isDOMReady() {																										// Checks to see if the DOM is ready for navigation
	if ( domReady.done ) return false;																					// If we already figures out that the page is ready, ignore
	
	if ( document && document.getElementsByTagName && document.getElementById && document.body ) {	// Check to see if a number of functions and elements are able to be accessed
		clearInterval( domReady.timer );																					// If they're ready, we can stop checking
		domReady.timer = null;
		
		for ( var i = 0; i < domReady.ready.length; i++ ) domReady.ready[ i ]();							// Execute all functions that were waiting	
		domReady.ready = null;
		domReady.done = true;
	}
}

/* --- nodes --- */

function create( elem ) {
	return document.createElementNS ? document.createElementNS( 'http://www.w3.org/1999/xhtml', elem ) : document.createElement( elem );
}

function before( parent, before, elem ) {
	if ( elem == null ) {										// Check to see if no parent was provided
		elem = before;
		before = parent;
		parent = before.parentNode;
	}
	parent.insertBefore( checkElem( elem ), before );
}

function append( parent, elem ) {
	parent.appendChild( checkElem( elem ));
}

function checkElem( elem ) {
	return elem && elem.constructor == String ? document.createTextNode( elem ) : elem;	// if a string was provided, convert it into a text node
}

function remove( elem ) {
	if ( elem ) elem.parentNode.removeChild( elem );
}

function empty( elem ) {
	while ( elem.firstChild ) remove( elem.firstChild );
}

/* --- finding elements --- */
function id( name ) {
	return document.getElementById( name );	// -> HTML element
};

	/* === fix document.getElementById for IE - based on code by J. Max Wilson: http://www.sixteensmallstones.org/ie-javascript-bugs-overriding-internet-explorers-documentgetelementbyid-to-be-w3c-compliant-exposes-an-additional-bug-in-getattributes === */ 
	document.nativeGetElementById = document.getElementById;
	document.getElementById = function( id ) {
	    if ( document.all ) {   // only override when document.all is supported (IE + Opera)
	
	        document.getElementById = function( id ) {
	            var elem = document.nativeGetElementById( id );
	            if ( !elem ) return null;
	            if ( elem.attributes['id'] && elem.attributes['id'].value == id ) return elem;							// make sure that it is a valid match on id
	
	            for ( var i = 1; i < document.all[ id ].length; i++ ) {															// otherwise find the correct element
	                if ( document.all[ id ][ i ].attributes[ 'id' ].value == id ) return document.all[ id ][ i ];
	            }
	        };
	    } else {    // otherwise change back to original
	        document.getElementById = document.nativeGetElementById;
	        document.nativeGetElementById = null;  																						// we don't need it anymore
	    }
	};
	document.getElementById();																													// run document.getElementById() once to let it rewrite itself
	/* --- /fix document.getElementById for IE --- */

function tag( name, elem ) {
	return ( elem || document ).getElementsByTagName( name );	// -> Array
};

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 prev( elem ) {
	do {
		elem = elem.previousSibling;
	} while ( elem && elem.nodeType != 1 );
	return elem;
}

function next( elem ) {
	do {
		elem = elem.nextSibling;
	} while ( elem && elem.nodeType != 1 );
	return elem;
}

function first( elem ) {
	elem = elem.firstChild;
	return elem && elem.nodeType != 1 ? next( elem ) : elem;
}

function last( elem ) {
	elem = elem.lastChild;
	return elem && elem.nodeType != 1 ? next( elem ) : elem;
}


/* --- get/set attributes --- */
function attr( elem, attrib ) {															// attrib can be a String (get) or an Object (set)
	if ( attrib.constructor == String ) {
		name = validName( attrib );
		return elem[ name ] || elem.getAttribute( name ) || '';					// -> String (attribute value)
	}
	else if ( attrib.constructor == Object ) {
		for ( n in attrib ) {
			var value = attrib[ n ];
			name = validName( n );
			if ( name == "className" || name == "rel" || name == "rev" ) {
				addToAttr( elem, name, value );
			} else {
				elem[ name ] = value;														// do it quick if possible
				if ( elem.setAttribute ) elem.setAttribute( name, value );		// XML fallback
			}
		}
		return true;																			// -> Boolean (values are set)
	}
	function validName( name ) {
		return { 'for': 'htmlFor', 'class': 'className' }[ name ] || name;	// rename in case of 'for' or 'class' attribute
	};
	return '';																					// -> String (empty: attrib was neither a String or Object)
};

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( " " );
}

/* ============= */
/* === STYLE === */
/* ============= */

/* --- check for CSS support --- */
function cssSupport() {
	if ( !document.styleSheets ) return false;									// styleSheets object is not supported
	var css = document.styleSheets;
	for ( var s = 0; s < css.length; s++) {
		if ( s == 0 ) {
			if ( !( css[ 0 ].cssRules || css[ 0 ].rules )) return false;	// both methods (cssRules/rules) are not supported
		}
		if ( !css[ s ].disabled ) return true;										// at least one of the stylesheets is not disabled
	}
	return false;																			// stylesheets are all disabled or not supported at all
}


/* ================================== */
/* ============= CUSTOM ============= */
/* ================================== */

////////// INIT OVERLABEL //////////

/* --- overLabel --- place labels over corresponding form control --- */
/* --- based on http://www.alistapart.com/articles/makingcompactformsmoreaccessible/ ---*/
function initOverLabel() {
	var IEindex = navigator.userAgent.indexOf( "MSIE" );
	if ( IEindex != -1 && parseFloat( navigator.userAgent.substring( IEindex + 5 ) ) < 7 ) return;	// skip if IE6 or older
	
	var labels = withClass( "overLabel", "label" );
	if ( !labels ) return;
	
	for ( var l = 0; l < labels.length; l++ ) {
		var label = labels[ l ];
		if ( !label.htmlFor ) continue;
		
		var overControl = id( label.htmlFor );
		if ( !overControl ) continue;
		
		label.forControl = overControl;																												// make reference from label to corresponding control
		
		if ( overControl.value === "" ) addClass( overControl.parentNode, "inactive" );	// make sure label is only placed on top of control in case it has no value which is not always the case after a reload
		else removeClass( overControl.parentNode, "inactive" );
		
		addEvent( overControl, "focus", function() { removeClass( this.parentNode, "inactive" ) } );
		addEvent( overControl, "blur", function() { if ( this.value === "" ) addClass( this.parentNode, "inactive" ) } );
		addEvent( label, "click", function() { this.forControl.focus() } );																// give focus to corresponding control (needed for Safari)
	}
	
	addClass( document.body, "jsLabelsOn" );																										// CSS hook to turn it on
}


////////// INIT MAIN MENU //////////

function initMainNav() {
	var mainNav = id( "mainNav" );
	if ( !mainNav ) return;
	
	addEvent( mainNav, "mouseover", function( e ) { mainNav.mOver( e ) } );
	addEvent( mainNav, "mouseout", function( e ) { mainNav.mOut( e ) } );
	
	mainNav.mOver = function( e ) {
		var mainItem = mainNav.getItem( e );
		if ( mainItem ) addClass( mainItem, "jsHover" );
	};
	
	mainNav.mOut = function( e ) {
		var mainItem = mainNav.getItem( e );
		if ( mainItem ) removeClass( mainItem, "jsHover" );
	};
	
	mainNav.getItem = function( e ) {
		e = normEvent( e );
		var targetName = e.target.nodeName;
		
		if ( targetName != "IMG" && targetName != "SPAN" && targetName != "A" && targetName != "LI" ) return false;
		
		var target = ( targetName == "IMG" || targetName == "SPAN" ) ? e.target.parentNode : e.target;
		target = ( target.nodeName == "A" ) ? target.parentNode : target;
		
		return ( hasClass( target.parentNode, "nav" ) ) ? target : target.parentNode.parentNode;
	};
	
	var mainLinks = tag( "a", mainNav );
	for ( var a = 0; a < mainLinks.length; a++ ) {
		var mainLink = mainLinks[ a ];
		addEvent( mainLink, "focus", function( e ) { mainNav.mOver( e ) } );
		addEvent( mainLink, "blur", function( e ) { mainNav.mOut( e ) } );
	}
}


////////// INIT NOTIFY //////////

function initNotify() {
	var notify = id( "notify" );
	if ( !notify ) return;

	// add closeLink
	var popupHeader = tag( "h2", notify )[ 0 ];
	if ( popupHeader ) {
		var closePopup = create( "div" );
		addClass( closePopup, "closePopup" );
		var closeLink = create( "a" );
		attr( closeLink, { "href": "#", "title": "Sluiten" } );
		var closeIcon = create( "img" );
		attr( closeIcon, { "src": "/Images/Campaign/button_" + sector + "_close.gif", "width": "8", "height": "7", "alt": "Sluiten" } );	// sector is defined in header of HTML file
		append( closeLink, closeIcon );
		append( closePopup, closeLink );
		
		var popupForm = next( popupHeader );
		if ( popupForm ) before( popupForm, closePopup );
		else append( popupHeader.parentNode, closePopup );
	}
	
	// add onclick event handler
	addEvent( notify, "click", function( e ) {
		e = normEvent( e );
		var targetName = e.target.nodeName.toUpperCase();												// Fx seems to be inconsequent about the case of the nodeName property
		
		if ( targetName != "IMG" && targetName != "A" ) return;
		var target = ( targetName == "IMG" ) ? e.target.parentNode : e.target;
		
		if ( hasClass( target.parentNode, "openPopup" ) ) addClass( this, "open" );
		else if ( hasClass( target.parentNode, "closePopup" ) ) removeClass( this, "open" );
		
		return stopDefault( e );
	} );
}


////////// ADD JS BUTTONS //////////

/*function addJSbuttons() {
	addJSprint();
}*/

function addJSprint() {
	var content = id( "content" );
	if ( !content ) return;
	
	var p = create( "p" );
	addClass( p, "printPage" );
	var printLink = create( "a" );
	attr( printLink, { "href": "#", "class": "more" } );
	append( printLink, "Print deze pagina" );
	append( p, printLink );
	
	var cntVacSummary = withClass( "cntVacSummary", "div", content )[ 0 ];
	if ( cntVacSummary ) {
		var printVacSummary = p.cloneNode( true );
		append( cntVacSummary, printVacSummary );
	}
	
	var cntPrintHeader = withClass( "cntPrintHeader", "div", content )[ 0 ];
	if ( cntPrintHeader ) {
		var header = cntPrintHeader.getElementsByTagName( "h1" )[ 0 ];
		if ( header ) {
			var printPrintHeader = p.cloneNode( true );
			before( cntPrintHeader, header, p );
		}
	}
}


///////////// INIT CLICKABLE ITEMS /////////////

/* --- clickableItems --- make entire itemes clickable --- */
function initClickableItems() {
	// content section -|- add section for every clickable item type
	var content = id( "content" );
	if ( content ) {
	
		var items = withClass( "clickableItem", "li", content );
		if ( items && items.length > 0 ) clickAllOver( items );
		
		var items = withClass( "clickableItem", "div", content );
		if ( items && items.length > 0 ) clickAllOver( items );
		
		
		var results = id( "results" );
		if ( results ) {
			var items = withClass( "clickableItem", "div", results );
			if ( items && items.length > 0 ) clickAllOver( items );
		}
	}
	// end content section
}

/* --- clickAllOver --- */
function clickAllOver( elems ) {													// 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; 
		}
		
		item.url = item.getUrl();
		if ( !item.url ) return;
		
		addEvent( item, "click", function() { window.location.href = this.url } );
		addEvent( item, "mouseover", function() { addClass( this, "jsHoverItem" )} );
		addEvent( item, "mouseout", function() { removeClass( this, "jsHoverItem" )} );
		
		addClass( item, "jsClickable" );
	}
}


///////////// INIT SELECT NAVIGATION /////////////

/* --- initSelectNav --- initializes autosubmit on <select>s that have class="selectNav", works with keyboard too (in IE, FX and Op) --- */
initSelectNav = function() {
	var content = id( "content" );
	if ( !content ) return;
	
	var selects = withClass( "selectNav", "select", content );
	for ( var s = 0; s < selects.length; s++ ) {
		var selectNav = selects[ s ];
		
		addEvent( selectNav, "focus", function() { this.origVal = this.value; } );
		addEvent( selectNav, "change", function() { 
			if ( this.newVal ) this.origVal = this.newVal;
			this.newVal = this.value;
		});
		addEvent( selectNav, "blur", function() { if ( this.newVal && this.newVal != this.origVal ) this.form.submit(); } );
		addEvent( selectNav, "click", function() { if ( this.newVal && this.newVal != this.origVal ) this.form.submit(); } );
	}
	if ( selectNav ) addClass( document.body, "jsSelectNavOn" );
}


/* --- call functions only if the used methods are supported --- */
domReady( function() {
	initNotify();
} );

