/*	---------------------------------------------------------------------------
		Aqtion pageflow library of javascript functions and prototypes.
		
		Meta:
			CreateDate	: 2006-02-01
			Author		: JS
			Source		: 
							xGetElements* functions are from Cross-Browser.com.
							Rest of functions are made by Aqtion FG & JS
			Copyright	: Except for the xGetElements* functions, visit: Cross-Browser.com
							Aqtion ID bv.
			Support		: Support@aqtion.nl

		functions included in this file:
			includeJavaScript( strFile )
			xGetElementsByClassName(class, parent, tagname, function)
			xGetElementsByTagName(tagname, parent)
			xGetElementsByAttribute(tagname, attribute, regexp, function)
			xmlHttpPostForm( strUrl, objForm, callBack, runCallEachStateChange )
			xmlHttpPost( strUrl, postData, callBack, runCallEachStateChange )
			xmlHttpGet( strUrl, callBack, runCallEachStateChange )
			*1 xmlHttpConnection( strUrl, strType, postData, callBack, runCallEachStateChange )
			aqtion_getXMLHTTP()
			getInputFromFormAsString( objForm )
			getSessionCookie(cookieName)
			setSessionCookie(cookieName, cookieValue)
			aqtion_displayXMLHTTPError(objXMLHTTP, boolShowError)
			aqtion_debugPopup(strElement)
			document.apgf_attachEvent('onload', functionname) ;
			document.apgf_attachEvent('onresize', functionname) ;
			
		prototypes included:
			*2 Array.prototype.inArray(value)	'returns true/false
			*2 Array.prototype.inArrayX(value)	' returns position in array, -1 if it's not found
			String.prototype.urlEncode()
			String.prototype.urlDecode()
			String.prototype.left(n)
			String.prototype.right(n)
			String.prototype.htmlEscape()
			String.prototype.htmlStrip()
		
		Comments:
		*1	Don't use this function directly, use one of the following instead:
				xmlHttpPostForm( strUrl, objForm, callBack, runCallEachStateChange )
				xmlHttpPost( strUrl, postData, callBack, runCallEachStateChange )
				xmlHttpGet( strUrl, callBack, runCallEachStateChange )
			callBack is name of function called when readyState = 4
			runCallEachStateChange is bool, when true callBack function is called on each readyState change
		*2	Current wysiwyg has problems with inArray, seems there is a bug when looping in an array the added prototype return as well.
			Could be solved with checking in wysiwyga.js for functions.
			These prototypes are changed to functions
			inArray( array, value )
			inArrayX( array, value )

	---------------------------------------------------------------------------
*/


/*	---------------------------------------------------------------------------
		Prototypes
*/
//Array.prototype.inArray = function (value) { var i; for (i=0; i < this.length; i++) { if (this[i] === value) { return true; } } return false; };
//Array.prototype.inArrayX = function (value) { var i; for (i=0; i < this.length; i++) { if (this[i] === value) { return i; } } return -1; };
	function inArray( arr, val ) {
		var i; for (i=0; i < arr.length; i++) { if (arr[i] === val) { return true; } } return false;
	}
	function inArrayX( arr, val ) {
		var i; for (i=0; i < arr.length; i++) { if (arr[i] === val) { return i; } } return -1;
	}


String.prototype.urlEncode = function() { return encodeURIComponent(this); }
String.prototype.urlDecode = function() { return decodeURIComponent(this); }
String.prototype.left = function( n ) { if (n <= 0) return ''; else if (n > String(this).length) return this; else return String(this).substring(0,n); }
String.prototype.right = function( n ) { if (n <= 0) return ''; else if (n > String(this).length) return this; else { var iLen = String(this).length; return String(this).substring(iLen, iLen - n); } }
String.prototype.htmlEscape = function() { var strTMP = this; strTMP = strTMP.replace(/> </g,'>\n\r<'); strTMP = strTMP.replace(/&/g,'&amp;'); strTMP = strTMP.replace(/>/g,'&gt;'); strTMP = strTMP.replace(/</g,'&lt;'); return strTMP; }
String.prototype.htmlStrip = function() { var strTMP = this; strTMP = strTMP.replace(/<(.|\n)+?>/g, ''); return strTMP; }


/*	---------------------------------------------------------------------------
	includeOnce : include a javascript file once;
*/
	var strLoadedJSFiles = '' ;
	function includeJavaScript( strFile ) {
		if (strLoadedJSFiles.indexOf(strFile)==-1){
			var objScript = document.createElement('script'); 
			var time = new Date().getTime();
			objScript.setAttribute('language', 'JavaScript1.2'); 
			objScript.setAttribute('type', 'text/javascript'); 
			objScript.setAttribute('src', strFile + '?' + time);
			document.getElementsByTagName('head')[0].appendChild(objScript);
			// we need to sleep for a while, let the browser handle the new inserted javascript file.
			strLoadedJSFiles += strFile + ' ' ;
		}
	}
	
	function sleepMode(millis)
	{
		var date = new Date();
		var curDate = new Date();
	
		do { var curDate = new Date(); }
		while(curDate-date < millis);
	}
/*	---------------------------------------------------------------------------
	xGetElementsByClassName + xGetElementsByTagName
*/
// xGetElementsByClassName, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL
	
	function xGetElementsByClassName(c,p,t,f)
	{
	  var found = new Array();
	  var re = new RegExp('\\b'+c+'\\b', 'i');
	  var list = xGetElementsByTagName(t, p);
	  for (var i = 0; i < list.length; ++i) {
	    if (list[i].className && list[i].className.search(re) != -1) {
	      found[found.length] = list[i];
	      if (f) f(list[i]);
	    }
	  }
	  return found;
	}
// xGetElementsByTagName, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL
	function xGetElementsByTagName(t,p)
	{
	  var list = null;
	  t = t || '*';
	  p = p || document;
	////
	  if (p.getElementsByTagName) { // DOM1
	    list = p.getElementsByTagName(t);
	    if (t=='*' && (!list || !list.length)) list = p.all; // IE5 '*' bug
	  }
	  else { // IE4 object model
	    if (t=='*') list = p.all;
	    else if (p.all && p.all.tags) list = p.all.tags(t);
	  }
	////
	  return list || new Array();
	}
// xGetElementsByAttribute, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL
	function xGetElementsByAttribute(sTag, sAtt, sRE, fn)
	{
	  var a, list, found = new Array(), re = new RegExp(sRE, 'i');
	  list = xGetElementsByTagName(sTag);
	  for (var i = 0; i < list.length; ++i) {
	    a = list[i].getAttribute(sAtt);
	    if (!a) {a = list[i][sAtt];}
	    if (typeof(a)=='string' && a.search(re) != -1) {
	      found[found.length] = list[i];
	      if (fn) fn(list[i]);
	    }
	  }
	  return found;
	}
/*	---------------------------------------------------------------------------
	xmlHTTP stuff
*/
	// get data remote through a post
	function xmlHttpPostForm( strUrl, objForm, callBack, runCallEachStateChange, bSynch ) { var postData = getInputFromFormAsString(objForm); xmlHttpConnection( strUrl, 'POST', postData, callBack, runCallEachStateChange ) ; }
	function xmlHttpPost( strUrl, postData, callBack, runCallEachStateChange, bSynch ) { xmlHttpConnection( strUrl, 'POST', postData, callBack, runCallEachStateChange ) ; }
	// get data remote through a get
	function xmlHttpGet( strUrl, callBack, runCallEachStateChange, bSynch ) { xmlHttpConnection( strUrl, 'GET', null, callBack, runCallEachStateChange ) ; }
	// get data remote through a post/get
	function xmlHttpConnection( strUrl, strType, postData, callBack, runCallEachStateChange, bSynch ) {
			if ( bSynch==null ) bSynch = true;
	        var xmlhttp = new aqtion_getXMLHTTP();
	        xmlhttp.open(strType, strUrl, bSynch) ;
	        xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	        if (callBack!=null) {
				xmlhttp.onreadystatechange = function() {
					if (runCallEachStateChange==null || !runCallEachStateChange) 
						runCallEachStateChange=false; 
					else 
						runCallEachStateChange=true;
					if (callBack) {
						if (runCallEachStateChange) {
							callBack( xmlhttp );
						} else if (xmlhttp.readyState == 4) {
							switch (xmlhttp.status) {
								case 200: // 200 - OK
									callBack(xmlhttp) ;
									return true;
								case 401: // 401 - not authorized
									/* 
										if this happens somethings is wrong on server side.
										this sessioncookie should also be readable on server side for fixing session.
										
										question is: Do we really want to redirect? Or prompt user first?
									*/
									window.location.href = '/2.3/login/login.asp?session_hash=' + getSessionCookie('sessionhash');
									return false;
								case 404: // 404 - file not found
									aqtion_displayXMLHTTPError(xmlhttp, false);
									return false;
								default:
									aqtion_displayXMLHTTPError(xmlhttp, true);
									return false;
							}
		            	}
					}
				};
	        }
	        xmlhttp.send(postData);
	}
	// return xmlhttpObject
	function aqtion_getXMLHTTP() {
	    var obj = null ;
		if (window.XMLHttpRequest) {
	        obj = new XMLHttpRequest();
	    } else if (window.ActiveXObject) {
	        obj = new ActiveXObject("Microsoft.XMLHTTP");
	    }
		return obj; 
	}

/*	---------------------------------------------------------------------------
	retrieve data from form as string
*/
	function getInputFromFormAsString( objForm ) {
		var time = new Date().getTime();
		var strData = 'xmlHTTPPostTime='+time ;
		var strTMP = '' ;
		var objCollItems = new Array();
		if (objForm.tagName.toLowerCase() == 'form' ) {
			objCollItems = aMerge(objCollItems, objForm.elements);
		} else {
			objCollItems = aMerge(objCollItems, objForm.getElementsByTagName('input'));
			objCollItems = aMerge(objCollItems, objForm.getElementsByTagName('select'));
			objCollItems = aMerge(objCollItems, objForm.getElementsByTagName('textarea'));
		}
		for (var i=0; i<objCollItems.length; i++) {
			if (!objCollItems[i].disabled) {
				switch(objCollItems[i].tagName.toLowerCase()) {
					case 'input':
						switch(objCollItems[i].type.toLowerCase()) {
							case 'text' :
							case 'hidden' :
							case 'password' :
								strData += '&' + objCollItems[i].name + '=' + objCollItems[i].value.urlEncode() ;
								break;
							case 'radio' :
								if (objCollItems[i].checked)
									strData += '&' + objCollItems[i].name + '=' + objCollItems[i].value.urlEncode() ;
								break ;
							case 'checkbox' :
								if (objCollItems[i].checked) {
									if (objCollItems[i].value)
										strData += '&' + objCollItems[i].name + '=' + objCollItems[i].value.urlEncode() ;
									else
										strData += '&' + objCollItems[i].name + '=on' ;
								}
								break ;
							default :
								strData += '&' + objCollItems[i].name + '=' + objCollItems[i].value.urlEncode() ;
								break;
						}
						break;
					case 'select':
						var strSelectData = '' ;
						for( j=0; j<objCollItems[i].options.length; j++) {
							if (objCollItems[i].options[j].selected) {
								if (strSelectData!='') strSelectData += ',' ;
								strSelectData += objCollItems[i].options[j].value.urlEncode() ;
							}
						}
						strData += '&' + objCollItems[i].name + '=' + strSelectData ;
						break;
					case 'textarea':
						strData += '&' + objCollItems[i].name + '=' + objCollItems[i].value.urlEncode() ;
						break;
				}
			}
		}
		return strData;
	}
	function aMerge( arr1, arr2 ) {
		for (var i=0; i<arr2.length; i++) {
			arr1[arr1.length] = arr2[i];
		}
		return arr1;
	}
/*	---------------------------------------------------------------------------
	session cookie functions
*/
	function getSessionCookie(cookieName) {
		var exp = new RegExp(escape(cookieName) + "=([^;]+)");
		if (exp.test(document.cookie + ";")) {
			exp.exec(document.cookie + ";");
			return unescape(RegExp.$1);
		}
		else 
			return false;
		}		
	function setSessionCookie(cookieName, cookieValue) {
		document.cookie = escape(cookieName) + "=" + escape(cookieValue) + "; path=/";
	}	
/*	---------------------------------------------------------------------------
	debug functions
*/
	function aqtion_displayXMLHTTPError(objXMLHTTP, boolShowError) {
		alert('Er is een fout opgetreden bij het ophalen van de gegevens.\n' +
			'Probeer het nogmaals of neem contact op met Aqtion.\n\n' +
			'De foutcode is: ' + objXMLHTTP.status + ' ' + objXMLHTTP.statusText);
			
		if (boolShowError) {
			var x = window.open();
			x.document.write('<html><head><title>' + objXMLHTTP.statusText + '</title></head><body>\n');
			x.document.write('<div id="showhtml"><pre>' + objXMLHTTP.responseText.htmlEscape() + '</pre></div>\n');
			x.document.write('</body></html>');
			x.document.close();
		}
	}
	
	function aqtion_debugPopup(strElement) {
		//
		// laat de content van het aangegeven id zien in een nieuw window
		//
		var x=window.open(); 
		x.document.write('<pre>' + aqtion_getObject(strElement).innerHTML.htmlEscape() + '</pre>'); 
		x.document.close();
		
		return false;
	}
/*	---------------------------------------------------------------------------
	with this function you can attach several functions to the same event.
	simply by doing:
		document.apgf_attachEvent('onload', functionname) ;
		document.apgf_attachEvent('onresize', functionname) ;
	
	currently only onload & onresize are supported.
*/
	document.apgf_events = [];
	document.apgf_attachEvent = function(type, reference) {
	    var evt = this.apgf_events;
	    if(!evt[type]) evt[type] = [];
	    evt[type][evt[type].length] = reference;
	
	    document[type] = function(e) { 
	        document.apgf_executeEvents(type, e);        
	    }
	}    
	
	document.apgf_executeEvents = function(type, e) {
	    for(var i in this.apgf_events[type]) {
	        this.apgf_events[type][i](e);
	    }    
	}
	
	window.onload = function() { document.apgf_executeEvents('onload'); }
	window.onresize = function() { document.apgf_executeEvents('onresize'); }
	
/*	--------------------------------------------------------------------------	
	This is a function for toggling the display status of an element
*/
function apgf_ToggleElementById( id, defState ) {
	if (!defState) defState = 'none';
	var obj = document.getElementById(id) ;
	if (obj.style.display == '') 
		obj.style.display = defState ;
	obj.style.display = (obj.style.display=='none')?'block':'none' ;
}


/*	--------------------------------------------------------------------------	
	dependencies: x_library.js
	
	loops collection of elements and resizes all to highest member
*/
function apgf_SynchHeightElements( oCol ) {
	var intMax = 0;
	
	for (var i=0; i<oCol.length; i++) {
		var tH = xHeight(oCol[i]) ;
		if (tH>intMax) intMax = tH;
	}
	for (var i=0; i<oCol.length; i++) {
		xHeight(oCol[i],intMax);
	}
}