
var alphabet  ="ABCDEFGHIJKLMNOPQRSTUVWXYZ" // All the pane en menu id's must start with an alphabet letter
var paneStore = new Object(); // A hashmap to store the panes
var spinner = new Image(); spinner.src = "http://www.dothome.co.za/images/icons/spinner.gif"; // Preload spinner
var fileExt = 'php'; // The files' extensions (for the menu items)
var menuTag = 'DIV'; // The default elements that menu items consist of
var useScreenCache = false; // Should panes' screens be cached or not by default

paneStore.size = 0; // Initialize the hash's size

// Function to set the pane's screen to display the file's source
function getAjaxFile(pane, fileName)
{
    if(pane.useCache && pane.cache[fileName])
    {
       pane.screen.innerHTML = pane.cache[fileName];
       return;
    }
    pane.ajax.setPane(pane);
	pane.ajax.requestFile = fileName;
	if(getAjaxFile.arguments[2])	
    	pane.ajax.onCompletion = getAjaxFile.arguments[2];
    else	
    	pane.ajax.onCompletion = showContent;
    if(pane.message)
        pane.ajax.onLoading = showWaitMessage;	
    pane.ajax.runAJAX();			
}
/* 
 * objId must be A_pane, B_pane, C_pane, etc.
 * or A_menu, B_menu, c_menu, etc.
 * If paneObj is a pane then the 2nd parameter is optional - 
 *      A boolean that indicates if the pane's screen contents should be cached
 *      (default is false)
 * If paneObj is a menu then the 2nd parameter is compulsory -
 *      A string that indicates what HTML tags (types) represents the 
 *      menu items (e.g. LI, DIV, etc.)
 */
function paneObj(objId)
{
    // Add this object to the paneStore
    paneStore[objId] = this;
    
	this.objId = objId;
	this.ajax = new sack();
	this.isPane = (objId.substring(2) == 'pane');
	    
    var hasSecArg = paneObj.arguments.length > 1;
    
    if(this.isPane)
    {
    	this.message = "<div align=center><img src='"+spinner.src+"'></div>";
    	this.useCache = useScreenCache;
        if(hasSecArg)
    		this.useCache = paneObj.arguments[1];
        if(this.useCache)
            this.cache = new Object();        
    }
    else
    {
    	this.activeMenuItem = false;
        this.clickedMenuItem = false;
        this.tag = menuTag;
        if(hasSecArg)
        	this.tag = paneObj.arguments[1];
    }
    
	/*
     * Can change default loading message
     * If message is null then nothing will be displayed
     * when pane is loading
     */
	this.setMessage = function(message)
	{
        if(this.isPane)
		    this.message = message;
	}
    
    this.setSpinnerAlign = function(align)
    {
    	this.message = "<div align="+align+"><img src='"+spinner.src+"'></div>";
    }
    
    this.setInitMenuItem = function(itemId)
    {
        if(!this.isPane)
            this.initId = itemId;
    }
}

/*
 * Call this function on page loading to link page elements 
 * with objects.
 */
function initAjax()
{
    // Maximum panes = 26
	for(i = 0; i < 26; i++)
    {
    	var paneId = alphabet.substr(i,1)+'_pane';
    	var menuId = alphabet.substr(i,1)+'_menu';
		var pane = document.getElementById(paneId);
		var menu = document.getElementById(menuId);
        // No more panes, thus break
		if(pane == null)
			break;
		paneStore[paneId].screen = pane;	
		paneStore.size++
        // Do the following only when this pane has a menu
		if(menu != null)
		{
			var menuItems = menu.getElementsByTagName(paneStore[menuId].tag);
			var hasInitItem = paneStore[menuId].initId;
			
			for(var no = 0; no < menuItems.length; no++)
    		{
        		menuItems[no].onmouseover = mouseoverMenuItem;
		 		menuItems[no].onclick = selectMenuItem;
		 		if(hasInitItem && (hasInitItem == menuItems[no].id))
		 			menuItems[no].onclick();
		 	}	
		}
    }
}

function mouseoverMenuItem()	
{
	var menu = paneStore[this.id.substring(0,1)+"_menu"];
	if(this == menu.clickedMenuItem)
		return;
    if(menu.activeMenuItem && menu.activeMenuItem != this)
    {
    	if(menu.activeMenuItem == menu.clickedMenuItem)
        	menu.activeMenuItem.className = 'infoClick';
        else
            menu.activeMenuItem.className = '';
	}
	this.className = 'infoMouseOver';
	menu.activeMenuItem = this;
}

function selectMenuItem()	
{
	var pane = paneStore[this.id.substring(0,1)+"_pane"];
	getAjaxFile(pane, this.id.substring(2) + '.'+fileExt)
    var menu = paneStore[this.id.substring(0,1)+"_menu"];
    if(menu.clickedMenuItem && menu.clickedMenuItem != this)
    	menu.clickedMenuItem.className = '';
    this.className = 'infoClick';
    menu.clickedMenuItem = this;
}

function showContent()	
{
    this.pane.screen.innerHTML = this.pane.ajax.response;
    if(this.pane.useCache && !(this.pane.cache[this.pane.ajax.requestFile]))
        this.pane.cache[this.pane.ajax.requestFile] = this.pane.ajax.response;	
}

function showWaitMessage()
{
	this.pane.screen.innerHTML = this.pane.message;
}

function sack(file) {
	this.xmlhttp = null;

	this.resetData = function() {
		this.method = "POST";
  		this.queryStringSeparator = "?";
		this.argumentSeparator = "&";
		this.URLString = "";
		this.encodeURIString = true;
  		this.execute = false;
  		this.element = null;
		this.elementObj = null;
		this.requestFile = file;
		this.vars = new Object();
		this.responseStatus = new Array(2);
  	};

	this.resetFunctions = function() {
  		this.onLoading = function() { };
  		this.onLoaded = function() { };
  		this.onInteractive = function() { };
  		this.onCompletion = function() { };
  		this.onError = function() { };
		this.onFail = function() { };
	};
	this.setPane = function(pane)  {
		this.pane = pane;
	}
	this.reset = function() {
		this.resetFunctions();
		this.resetData();
	};

	this.createAJAX = function() {
		try {
			this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e1) {
			try {
				this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e2) {
				this.xmlhttp = null;
			}
		}

		if (! this.xmlhttp) {
			if (typeof XMLHttpRequest != "undefined") {
				this.xmlhttp = new XMLHttpRequest();
			} else {
				this.failed = true;
			}
		}
	};

	this.setVar = function(name, value){
		this.vars[name] = Array(value, false);
	};
	
	this.removeVar = function(name) {
		delete this.vars[name];
	}
	
	this.encVar = function(name, value, returnvars) {
		if (true == returnvars) {
			return Array(encodeURIComponent(name), encodeURIComponent(value));
		} else {
			this.vars[encodeURIComponent(name)] = Array(encodeURIComponent(value), true);
		}
	}

	this.processURLString = function(string, encode) {
		encoded = encodeURIComponent(this.argumentSeparator);
		regexp = new RegExp(this.argumentSeparator + "|" + encoded);
		varArray = string.split(regexp);
		for (i = 0; i < varArray.length; i++){
			urlVars = varArray[i].split("=");
			if (true == encode){
				this.encVar(urlVars[0], urlVars[1]);
			} else {
				this.setVar(urlVars[0], urlVars[1]);
			}
		}
	}

	this.createURLString = function(urlstring) {
		if (this.encodeURIString && this.URLString.length) {
			this.processURLString(this.URLString, true);
		}

		if (urlstring) {
			if (this.URLString.length) {
				this.URLString += this.argumentSeparator + urlstring;
			} else {
				this.URLString = urlstring;
			}
		}

		// prevents caching of URLString
		this.setVar("rndval", new Date().getTime());

		urlstringtemp = new Array();
		for (key in this.vars) {
			if (false == this.vars[key][1] && true == this.encodeURIString) {
				encoded = this.encVar(key, this.vars[key][0], true);
				delete this.vars[key];
				this.vars[encoded[0]] = Array(encoded[1], true);
				key = encoded[0];
			}

			urlstringtemp[urlstringtemp.length] = key + "=" + this.vars[key][0];
		}
		if (urlstring){
			this.URLString += this.argumentSeparator + urlstringtemp.join(this.argumentSeparator);
		} else {
			this.URLString += urlstringtemp.join(this.argumentSeparator);
		}
	}

	this.runResponse = function() {
		eval(this.response);
	}

	this.runAJAX = function(urlstring) {
		if (this.failed) {
			this.onFail();
		} else {
			this.createURLString(urlstring);
			if (this.element) {
				this.elementObj = document.getElementById(this.element);
			}
			if (this.xmlhttp) {
				var self = this;
				if (this.method == "GET") {
					totalurlstring = this.requestFile + this.queryStringSeparator + this.URLString;
					this.xmlhttp.open(this.method, totalurlstring, true);
				} else {
					this.xmlhttp.open(this.method, this.requestFile, true);
					try {
						this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
					} catch (e) { }
				}

				this.xmlhttp.onreadystatechange = function() {
			
					switch (self.xmlhttp.readyState) {
						case 1:
							self.onLoading();
							break;
						case 2:
							self.onLoaded();
							break;
						case 3:
							self.onInteractive();
							break;
						case 4:
							self.response = self.xmlhttp.responseText;
							self.responseXML = self.xmlhttp.responseXML;
							self.responseStatus[0] = self.xmlhttp.status;
							self.responseStatus[1] = self.xmlhttp.statusText;

							if (self.execute) {
								self.runResponse();
							}

							if (self.elementObj) {
								elemNodeName = self.elementObj.nodeName;
								elemNodeName.toLowerCase();
								if (elemNodeName == "input"
								|| elemNodeName == "select"
								|| elemNodeName == "option"
								|| elemNodeName == "textarea") {
									self.elementObj.value = self.response;
								} else {
									self.elementObj.innerHTML = self.response;
								}
							}
							if (self.responseStatus[0] == "200") {
								self.onCompletion();
							} else {
								self.onError();
							}

							self.URLString = "";
							break;
					}
				};

				this.xmlhttp.send(this.URLString);
			}
		}
	};

	this.reset();
	this.createAJAX();
}

