/**
 * 
 * joink.JAH:		Javascript And xHTML class
 * 
 * @Author				Jochen Vandendriessche
 * @Contact				info@joggink.be
 * @classDescription	This class makes it possible to fetch data from
 * 						a serverside script without reloading the page. Similar
 * 						to AJAX, but instead of XML plain xHTML code is returned
 * @version				1.1b
 * @copyright			MIT licence
 * @build				0.0.1.3
 * Copyright (c) 2007, Jochen Vandendriessche

 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * 
 */

 function joinkJAH(){
 	this.http		=	null;
	this.state		=	false;
	this.debugLog	=	'';
	this.params		=	'';
	this.func		=	null;
	this.response	=	'';
	this.htmlObj	=	'';
	this.openConn();
 }
 
 joinkJAH.prototype	=	{
 	
	/**
	 * 	@function			:	openConn
	 *  @functionDescripton	:	initialize the connection and store it in the http object
	 */
		openConn		:	function(){
			var xmlhttp;
			/*@cc_on
			@if (@_jscript_version >= 5)
				try {
					xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
				}catch(e){
					try {
						xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
					}catch(E){
						xmlhttp = false;
					}
				 }
			@else
				xmlhttp = false;
			@end @*/
			if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
				try {
					xmlhttp = new XMLHttpRequest();
				}catch(e) {
					xmlhttp = false;
				}
			}
			  
			if (xmlhttp){
				this.http = xmlhttp;
				this.debugAdd("JAH::openConn	HTTP object succesfully created", 2);
			}else{
	  			this.debugAdd("JAH::openConn	Could not create HTTP object", 1);
			}			
		}
		
	,
	/**
	 * 	@function			:	doRequest
	 *  @functionDescripton	:	do a Request to the page via the chosen method {get/post}
	 */	
		
		doRequest		:	function(url, method){
		
			if (this.http && ! this.state){
				this.debugAdd("JAH::doRequest	JAH http object is doing the request", 0);
				switch (method.toUpperCase()){
					case "GET":
						var pageURI = url;
						if (this.params){
							pageURI = url + "?" + this.params;
						}
						this.http.open("GET", pageURI, true);
						this.debugAdd("JAH::doRequest	Requesting data from " + url + " using " + method, 2);
						this.http.onreadystatechange = bind(this, this.handleRequest);
						this.state = true;
						this.http.send(null);		
					break;
					
					case "POST":
						if (this.params){
							this.http.open("POST", url, true);		
							this.http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
							this.http.setRequestHeader("Content-length", this.params.length);
							this.http.setRequestHeader("Connection", "close");
							this.debugAdd("JAH::doRequest	Requesting data from " + url + " using " + method, 2);
							this.http.onreadystatechange = bind(this, this.handleRequest);
							this.state = true;
							this.http.send(this.params);
						}else{
							this.debugAdd("JAH::doRequest	No form/input data has been assigned", 2);
						}
						break;
					break;
					
					default:
						this.debugAdd("JAH::doRequest	Unknown method " + escape(method), 1);
				}
			}else{
			if (this.state){
				this.debugAdd("JAH::doRequest	The http request is doing an other request at the time", 1);
			}
		}
		
		}

	,
	
	/**
	 * 	@function			:	handleRequest
	 *  @functionDescripton	:	handle the Request from the doRequest function
	 */	

		handleRequest		:		function(){
			if (this.http.readyState == 4) {		
				this.debugAdd("JAH::handleRequest	Getting responseText", 0);
				switch (this.http.status){
					case 404:
						this.debugAdd("JAH::handleRequest	The requested page was not found", 1);
					break;
					case 403:
						this.debugAdd("JAH::handleRequest	The requested page returned a 403", 1);
					break;
					default:
						this.response = this.http.responseText;
						this.debugAdd("JAH::handleRequest	ResponseText received succesfully", 0);
						this.onFinish();
				}
				this.state = false;
			}
		}

	,

	/**
	 *  @function			:	onFinish
	 *  @functionDescription:	triggers the userfunction / places the responseText in the userObj
	 */

		onFinish			:	function(){
			if (this.htmlObj){
				this.htmlObj.innerHTML = this.response;
			}
			if (this.func){
				this.func.call();
			}			
		}

	,
	
	/**
	 *  @function			:	setFunction
	 *  @functionDescription:	sets the user function, triggered onfinish
	 */

		setFunction			:	function(func){
			this.func	= func;
		}

	,
	
	/**
	 *  @function			:	setHtmlObj
	 *  @functionDescription:	sets the user html obj where the responseText will be placed in, triggered onFinish
	 */

		setHtmlObj			:	function(id){
			if (id){
				if (document.getElementById(id)){
					this.htmlObj = document.getElementById(id);
				}else{
					this.debugAdd('JAH::setHtmlObj	The html Object with id ' + id + ' could not be located on the page', 1);
				}
			}else{
				this.htmlObj = '';
			}
		}

	,
	
	/**
	 *  @function			:	setParams
	 *  @functionDescription:	sets the user parameters, can be form/input/getstring
	 */
	
		setParams			:	function(params){
			/*var paramType = typeof(params);
			if (paramType == 'object'){
				paramType = paramType;
				window.alert(paramType);				
			}*/
			paramType = typeof(params);
			if (paramType == 'object'){
				if(params.method){
					//window.alert('tis een form');
					paramType = 'form';
				}else{
					if (params.type){
						paramType = 'input';
					}else{
						if (params.selectedIndex){
							paramType = 'select-one';
						}	
					}
				}
			}
			
			switch (paramType){
				case "form":
					var formEls = params.elements;
					//window.alert(formEls);
					var paraTxt = "";
					for (var n = 0;n<formEls.length;n++){
					try{
						switch (formEls[n].type.toLowerCase()){
							case "text":
							case "password":
							case "hidden":
								paraTxt += '&' + formEls[n].name + '=' + formEls[n].value;
								break;
							case "select-one":
								paraTxt += '&' + formEls[n].name + '=' + formEls[n].options[formEls[n].selectedIndex].value; 
								break;			
							// select multiple moet nog gebeuren!					
							case "textarea":
								//window.alert(formEls[n].name);
								paraTxt += '&' + formEls[n].name + '=' + escape(formEls[n].value);
							case "checkbox":
							case "radio":
								if (formEls[n].checked){
									paraTxt += '&' + formEls[n].name + '=' + formEls[n].value;
								}						
								break;
						}
					}catch(e){
						this.debugAdd('JAH::setParams	Error (' + e.name + ') ' + e.message, 1);
					}
					}
					this.params = paraTxt;
					//window.alert('form\n' + paraTxt);
				break;
				case "input":
					this.params = input.name + '=' + input.value;
					//window.alert('input\n' + this.params);
				break;
				default:
					this.params = params;
					//window.alert('params:\n' + this.params);
			}
			this.debugAdd('JAH::setParams	The parameters (' + paramType + ') has been added', 2);
		}

	,

	/**
	 * 	@function			:	debugAdd
	 *  @functionDescripton	:	Stores the debug messages and puts them in the debug div if the debug is enabled
	 */

		debugAdd			:	function(debugTxt, errorType){
			var time = new Date();
			var printTime = leading(time.getHours()) + ":" + leading(time.getMinutes()) + ":" + leading(time.getSeconds());
			
			if (this.debugLog == ""){
				this.debugLog = '<pre>' + printTime + ' &raquo; <span style="color:#666;">JAH			Initialising jah class</span></pre>';
			}		
			
			var messagetoadd = '<pre>' + printTime + ' &raquo; ';
			
			switch(errorType){
				case 1:
					messagetoadd += '<span style="color:#f06;">' + debugTxt + '</span>';
					break;
				case 2:
					messagetoadd += '<span style="color:#009;">' + debugTxt + '</span>';
					break;
				default:
					messagetoadd += '<span style="color:#090;">' + debugTxt + '</span>';
			}
			messagetoadd += '</pre>';
			messagetoadd += this.debugLog;
			this.debugLog = messagetoadd;
			var dDiv = document.getElementById('debugDiv');
			if (dDiv){
				dDiv.innerHTML  = '<a href="#" onclick="debugClose()" style="float:right;font-weight:bold;margin-right:10px;color:#0cf;">close debug</a>';
				dDiv.innerHTML += ' | ';
				dDiv.innerHTML += '<a href="#" onclick="debugToggle()" style="float:right;font-weight:bold;margin-right:10px;color:#0cf;">Show / hide debug</a>';
				dDiv.innerHTML += '<strong>joink JAH Debug log:</strong>';
				dDiv.innerHTML += '<hr style="margin-top:3px;" />';
				dDiv.innerHTML += this.debugLog;
			}
		}

	,
	
	/**
	 *  @function			:	showDebug
	 *  @functionDescription:	displays the debug console
	 */
	
		showDebug			:		function(){
			var debugDiv = document.createElement('div');
			debugDiv.setAttribute('id', 'debugDiv');
			debugDiv.style.width 				=  '' + 'px';
			debugDiv.style.height				= '196px';
			debugDiv.style.padding				= '2px';
			debugDiv.style.overflow				= 'auto';
			debugDiv.style.fontFamily			= 'tahoma, arial, verdana, sans-serif';
			debugDiv.style.fontSize				= '10px';
			debugDiv.style.color				= '#333';
			debugDiv.style.backgroundColor		= '#f9f9f9';
			debugDiv.style.position				= 'absolute';
			debugDiv.style.bottom				= '0px';
			debugDiv.style.left					= '0px';
			debugDiv.style.border				= '1px outset #ccc';
			debugDiv.style.textAlign			= 'left';
			debugDiv.style.MozOpacity			= '0.9';
			debugDiv.innerHTML					= '<a href="#" onclick="debugClose()" style="float:right;font-weight:bold;margin-right:10px;color:#0cf;">close debug</a>';
			debugDiv.innerHTML					+= ' | ';
			debugDiv.innerHTML					+= '<a href="#" onclick="debugToggle()" style="float:right;font-weight:bold;margin-right:10px;color:#0cf;">Show / hide debug</a>';			
			debugDiv.innerHTML 					+= '<strong>JAH Debug log:</strong><hr />';
			debugDiv.innerHTML					+= this.debugLog;
			var loc = document.getElementsByTagName('body');			
			loc[0].appendChild(debugDiv);
		}

 }
 
function bind(el, func){
	return function(){
		func.call(el);
	}
}

function debugToggle(){
	var debugDiv = document.getElementById('debugDiv');
	if (debugDiv.offsetHeight < 100){
		debugDiv.style.height = '196px';
		debugDiv.style.overflow = 'auto';
	}else{
		debugDiv.style.height = '14px';
		debugDiv.style.overflow = 'hidden';
	}
}

function debugClose(){
	document.getElementById('debugDiv').style.display = 'none';
}

function leading(inte){
	if (parseInt(inte) < 10){
		return '0' + inte;
	}else{
		return inte;
	}
}