/*---------------------------------------------------------------------------
 * HTTPTabs Constructor
 *-------------------------------------------------------------------------*/
HTTPTabs = function(id, contentLayer, selected, disableAjax, afterReload) {
	this.id = id;
	this.contentLayer = contentLayer;
	this.objectID = "OBJ" + Math.random().toString().substr(2);
	this.HTTPTabList = new Array();
	if(selected != undefined) {
		this.selectedTab = selected-1;
	} else {
		this.selectedTab = -1;
	}
	this.disableAjax=disableAjax;

	if(afterReload != undefined && afterReload != null) {
		this._afterReload=afterReload;
	} else {
		this._afterReload=undefined;
	}

	this.previousTab = -1;
}
/*-----------------------------------------------------------------------------
 * HTTPTabs method addItem
 * adds a tab item to the list of tabs
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype.addItem = function(contentLayerId, tabLayerId, contentURL, backupURL, tabCSS, cacheContent, initiallyCached) {
	this.HTTPTabList.length++;
	this.HTTPTabList[this.HTTPTabList.length-1] = new HTTPTabItem(contentLayerId, tabLayerId, contentURL, backupURL, tabCSS, cacheContent, initiallyCached);
}

/*-----------------------------------------------------------------------------
 * HTTPTabs method onClick
 * handles a user's mouseclick
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype.onClick = function(object, currentTab, extraParams) {
	if(this.disableAjax != undefined && this.disableAjax == "true") {
	
		var backupUrl = this.HTTPTabList[currentTab].getBackupURL();
		if(extraParams != undefined && extraParams != null && extraParams != "") {

			var delim="&";
			if( backupUrl.indexOf("?") == -1 ) {
				delim="?";
			}

			backupUrl += delim+extraParams;
		}
		location.href = backupUrl;

	} else if (this.selectedTab != currentTab) {
		if(object != undefined && object != null && object != "") {
			this._getCurrentTabObject().className = this.HTTPTabList[this.selectedTab].getTabCSS()+"_uit tab";
			object.className = this.HTTPTabList[currentTab].getTabCSS()+"_aan tab";
		}

		this.previousTab = this.selectedTab;
		this.selectedTab = currentTab;

		if(this.HTTPTabList[currentTab].isCached() == false) {
			this._getDocument(this.HTTPTabList[currentTab].getContentURL());
		} else {
			this._switchContentLayers();
		}

		// if no xmlhttprequest could be instantiated, fallback to a refresh
		if( this.ajaxEnabled != undefined && this.ajaxEnabled == false ) {
			location.href = this.HTTPTabList[currentTab].getBackupURL();
		}
    } else {
		if(extraParams != undefined && extraParams != null && extraParams != "") {
			//alert("reload! URL:"+this.HTTPTabList[currentTab].getContentURL()+"&"+extraParams);
			this._getDocument(this.HTTPTabList[currentTab].getContentURL()+"&"+extraParams);    	
		}
	}
}

/*-----------------------------------------------------------------------------
 * HTTPTabs method _getContentObject
 * returns: document content object for selected menu item
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype._getContentObject = function() {
	return document.getElementById(this.HTTPTabList[this.selectedTab].getContentLayerId());
}

/*-----------------------------------------------------------------------------
 * HTTPTabs method _getPreviousContentObject
 * returns: document content object for previously selected layer
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype._getPreviousContentObject = function() {
	if(this.previousTab >= 0) {
		return document.getElementById(this.HTTPTabList[this.previousTab].getContentLayerId());
	}
}

/*-----------------------------------------------------------------------------
 * HTTPTabs method _getVisibleContentObject
 * returns: document content object for selected menu item
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype._getVisibleContentObject = function() {
	return document.getElementById(this.contentLayer);
}

/*-----------------------------------------------------------------------------
 * HTTPTabs method _getContentObject
 * returns: document content object for selected menu item
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype._getCurrentTabObject = function() {
	return document.getElementById(this.HTTPTabList[this.selectedTab].getTabLayerId());
}

/*-----------------------------------------------------------------------------
 * HTTPTabs method _evaluateScript
 * evaluate the <script> tags OR possible nested <script> tags 
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype._evaluateScript = function(parentNode) {
	for(var i=0; i< parentNode.childNodes.length; i++) {

		var child = parentNode.childNodes[i];

		if(child.nodeName.toLowerCase() == "script" && child.src == "") {
			var scriptText = child.text;
			hasComment = scriptText.indexOf("<!--");
			if(hasComment > -1 && hasComment < 10) { /* 10 is a heuristic, 'at the beginning' */
				scriptText = scriptText.substr(hasComment+4);
			}
			//alert(scriptText);
			eval(scriptText);
		} else if(child.nodeName.toLowerCase() == "script" && child.src != "") {
			// what to do with external javascript?
		} else if(child.hasChildNodes()) {
			this._evaluateScript(child);
		}
	}
}


/*-----------------------------------------------------------------------------
 * HTTPTabs method _viewContent
 * sets the content of the configured layer 
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype._viewContent = function(content) {
	// set content of hidden div
	var contentLayer = this._getContentObject();
	contentLayer.innerHTML = content;

	// upon initialisation, evaluate all <script> tags in the layer
	this._evaluateScript(contentLayer);

	// mark layer as cached
	this.HTTPTabList[this.selectedTab].setCached(true);

		// switch to hidden div
	 	this._switchContentLayers();

	// for debugging purposes: remove content of hidden div:
	//this._getContentObject().innerHTML = "-1";
}


/*-----------------------------------------------------------------------------
 * switch content layers
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype._switchContentLayers = function() {
	this._getContentObject().style.display="block";
	this._getPreviousContentObject().style.display="none"; 
}

/*-----------------------------------------------------------------------------
 * var to hold an instance of the XMLHTTPRequest object
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype._request = undefined;

/*-----------------------------------------------------------------------------
 * HTTPTabs method _getXMLHTTPRequest
 * returns: an XMLHTTPRequest instance (based on browser IE/Mozilla)
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype._getXMLHTTPRequest = function() {
	var xmlHttp;
	
	// temporary hack to imitate a JavaScript-enabled, non-AJAX browser:
	//return xmlHttp;
	try {
		xmlHttp = new ActiveXObject("Msxml2.XMLHttp");
	} catch(e) {
		try {
			xmlHttp = new ActiveXObject("Microsoft.XMLHttp");
		} catch(e2) {}
	}
	
	if(xmlHttp == undefined && (typeof XMLHttpRequest != "undefined")) {
		xmlHttp = new XMLHttpRequest();
	}
	
	return xmlHttp;
}

/*-----------------------------------------------------------------------------
 * HTTPTabs method _getDocument
 * AJAX request with XMLHTTPRequest
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype._getDocument = function(URL) {
	// get a new XMLHTTPRequest and store it in an isntance var.
	this._request = this._getXMLHTTPRequest();

	if(this._request == undefined) {
		this.ajaxEnabled = false;
	}

	// set the var so we can scope the callback
	var _this = this;

	// callback will be an anonymous function that calls back into our class
	// this allows the call back in which we handle the response (_onData())
	// to have the correct scope.
	this._request.onreadystatechange = function(){_this._onReadyStateChange();};

	this._request.open("GET", URL, true);
	this._request.send(null);
}

/*-----------------------------------------------------------------------------
 * HTTPTabs method _onReadyStateChange
 * callback for when the data is loaded from the server
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype._onReadyStateChange = function() {
	/**
	 * request.readyState:
	 *   0: uninitialized  -- (open() not called yet) 
	 *   1: loading        -- (send() not called yet)
	 *   2: loaded         -- (send() called, headers+status available)
	 *   3: interactive    -- (downloading.. responseText holds partial data)
	 *   4: completed      -- (all done)
	 *
	 * this piece of code changes the mouse-cursor depending on this state
	 */
	switch(this._request.readyState) {
		case 0:
		case 1:
		case 2:
		case 3:
			document.body.style.cursor="progress";
			this._changeCursorStyle(new Array("a:hover",".tab"), "progress");
			this._changeCursorStyle(".tab", "progress");
			break;
		case 4:
			document.body.style.cursor="default";
			this._changeCursorStyle(new Array("a:hover",".tab"),"pointer");
			this._changeCursorStyle(".tab","pointer");
			break;
	}

	if(this._request.readyState == 4) {
		if(this._request.status == 200) {

			this._viewContent( this._request.responseText );
			
			// additional callback, user injectable
			if(this._afterReload != undefined) {
				this._afterReload();
			}

		} else {

			this._viewContent("<span style=\"font-style:italic;\">There was a problem retrieving the HTTP data</span>:<br/>[<span style=\"color:red\">" + this._request.status + "</span>] : "+ this._request.statusText);

			//check if an error callback handler has been defined
			if(this.onError != undefined) {
				//pass an object to the callback handler with info
				//about the error
				this.onError({status:this_request.status, 
						statusText:this._request.statusText});
			}
		}
		
		//clean up
		delete this._request;
	}
}

/*-----------------------------------------------------------------------------
 * HTTPTabs method _changeCursorStyle
 *   change the cursor of a certain css-style 
 *---------------------------------------------------------------------------*/
HTTPTabs.prototype._changeCursorStyle = function(classNames, cursorStyle) {
	if(document.styleSheets == undefined) return;

	try {
		var className = "";
		var foundClassName = "";
		var theRules = new Array();

		for(var s=0; s<document.styleSheets.length;s++) {
			if (document.styleSheets[s].cssRules)
				theRules = document.styleSheets[s].cssRules;
			else if (document.styleSheets[s].rules)
				theRules = document.styleSheets[s].rules;
		
			for(i=0;i<theRules.length;i++) {
				foundClassName = theRules[i].selectorText;
				for(c=0; c<classNames.length; c++) {
					className=classNames[c];
					if(foundClassName.toLowerCase() == className) {
						theRules[i].style.cursor = cursorStyle;
					}
				}
			}
		}
	} catch(err) {
		//whoops, domain security stuff? (FireFox)
	}
}

/*---------------------------------------------------------------------------
 * HTTPTabItem Constructor
 *-------------------------------------------------------------------------*/
HTTPTabItem = function(contentLayerId, tabLayerId, contentURL, backupURL, tabCSS, cacheContent, initiallyCached) {
	this.contentLayerId = contentLayerId;
	this.tabLayerId = tabLayerId;
	this.contentURL = contentURL;
	this.backupURL = backupURL;
	this.tabCSS = tabCSS;
	this.cache = cacheContent;
	this.cached = initiallyCached;
}
HTTPTabItem.prototype.getContentLayerId = function() {
	return this.contentLayerId;
}
HTTPTabItem.prototype.getTabLayerId = function() {
	return this.tabLayerId;
}
HTTPTabItem.prototype.getContentURL = function() {
	return this.contentURL;
}
HTTPTabItem.prototype.getBackupURL = function() {
	return this.backupURL;
}
HTTPTabItem.prototype.getTabCSS = function() {
	return this.tabCSS;
}
HTTPTabItem.prototype.getCache = function() {
	return this.tabCache;
}
HTTPTabItem.prototype.setCached = function(state) {
	this.cached = state;
}
HTTPTabItem.prototype.isCached = function() {
	return this.cached;
}
