/*
	Common functions Copyright (C) 2006  Sunil G Vanmullem
	http://www.das-kuechen-studio.co.uk/solutions
	
    This code is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

var AJAX__CONTEXT = null;
var AJAX__CALLBACKNAME = "";
var AJAX__OBJ = null;
var XML__IS_IE = false;
var AJAX__FILENAME = "";
var DEBUG__WINDOW = null;
var DEBUG__DEPTH = 0;
var DEBUG__PADDING= "    ";
var DEBUG_LEVEL = 0;
var SOME_DEBUG = 1;
var MORE_DEBUG = 2;
var FULL_DEBUG = 3;

//**********************************************************
function findObj(theObj, theDoc)
{
  var p, i, foundObj;
  
  if(!theDoc) theDoc = document;
  if( (p = theObj.indexOf("?")) > 0 && parent.frames.length)
  {
    theDoc = parent.frames[theObj.substring(p+1)].document;
    theObj = theObj.substring(0,p);
  }
  if(!(foundObj = theDoc[theObj]) && theDoc.all) foundObj = theDoc.all[theObj];
  for (i=0; !foundObj && i < theDoc.forms.length; i++) 
    foundObj = theDoc.forms[i][theObj];
  for(i=0; !foundObj && theDoc.layers && i < theDoc.layers.length; i++) 
    foundObj = findObj(theObj,theDoc.layers[i].document);
  if(!foundObj && document.getElementById) foundObj = document.getElementById(theObj);
  
  return foundObj;
}

function repeat_string(psString, piOccurances)
{
	var s,i;
	s= "";
	for (i=0; i<piOccurances; i++)
		s = s + psString;
	return s;
}

//**********************************************************
function trim(str){
	return str.replace(/^\s*|\s*$/g,"");
}

//**********************************************************
function strExtract( pStr, psStart, psEnd)
{
	var sOut, iLast, iPos, iEnd;
	var sUpper, sFragment;
	
	sUpper = pStr.toUpperCase();
	sOut = "";
	iLast = 0;
	
	while (true){
		iPos = sUpper.indexOf(psStart, iLast);
		if (iPos == -1)
			break;
		else{
			iEnd = sUpper.indexOf(psEnd,iPos);
			iEnd += psEnd.length;
			sFragment = pStr.substring(iPos, iEnd);
			sOut += sFragment;
			iLast = iEnd;
		}
	}
	
	return sOut;
}

//**********************************************************
function strRemove( pStr, psStart, psEnd)
{
	var sOut, iLast, iPos, iEnd;
	var sUpper, sFragment;
	
	sUpper = pStr.toUpperCase();
	sOut = "";
	iLast = 0;
	
	while (true){
		iPos = sUpper.indexOf(psStart, iLast);
		if (iPos == -1){
			//append rhs to string
			if (iPos < sUpper.length){
				sFragment = pStr.substring(iPos, sUpper.length);
				sOut += sFragment;
			}
			break;
		}else{
			//everything before this is kept
			sFragment = pStr.substring(iLast, iPos-1);
			sOut += sFragment;
			iEnd = sUpper.indexOf(psEnd,iPos);
			iEnd += psEnd.length;
			iLast = iEnd;
		}
	}
	
	return sOut;
}

//**********************************************************
function getXMLHttpRequestobj()
{
	var req;
	var ieVersions = ["Microsoft.XMLHTTP", "Msxml2.XMLHTTP.7.0", "Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP"];
	
    // branch for native XMLHttpRequest object
    if(window.XMLHttpRequest) {
    	try {
			req = new XMLHttpRequest();
        } catch(e) {
			req = null;
      	}
	} else if (window.ActiveXObject) {		//internet explorer
		XML__IS_IE = true;
	    // loops through the various versions of XMLHTTP to ensure we're using the latest
        for (var i = 0; i < ieVersions.length ; i++) {
		  // try to create the object, if it works hey use it
            try {
                req = new ActiveXObject(ieVersions[i]);
                if (req != null) {break;}
            }
            catch (objException) {}
        } 
	}    
    return req;
}

//**********************************************************
//web browser needs to be told mime type when XML- otherwise it dont work
// uses ajax - but a slight improvement to retain the object context 
//in the callback! 
function read_remote_data(psUrl, pbIsXML, poObjContext, psCallback){
	var oReq;
	
	oReq = getXMLHttpRequestobj();
	if (oReq ){
		AJAX__CONTEXT = poObjContext;
		AJAX__CALLBACKNAME = psCallback;
		AJAX__OBJ = oReq;
		AJAX__FILENAME = psUrl;
		
		if (oReq.url){oReq.url = psUrl;}
		oReq.onreadystatechange = pxml_callback;
		oReq.open("GET", psUrl, true);
		if (pbIsXML && oReq.overrideMimeType)
			oReq.overrideMimeType('text/xml');	

		if (XML__IS_IE)
			oReq.send();
		else
			oReq.send(null);
		return oReq;
	}else{
		return null;
	}
}


//**********************************************************
//checks that remote call has worked and retains object context without using eval function
//Opera gives a status of 304 but it still works.. how weird
function pxml_callback()
{
	var oFn;
	
	if (AJAX__OBJ.readyState == 4){
		if (( AJAX__OBJ.status == 200) || ( AJAX__OBJ.status == 304) || ( (document.location.protocol == "file:") && (AJAX__OBJ.status == 0))){
			AJAX__CONTEXT[AJAX__CALLBACKNAME](AJAX__OBJ);
			return;
		}else{
			alert ("unable to read remote data XML: "+ AJAX__FILENAME + "\n reason was - " + AJAX__OBJ.status);
			return;
		}
	}else{	
		return;
	}
}

//**********************************************************
function get_base_url(){
	var sURL, sProtocol, sPort, sLeft, sPath, sHost;
	var iLastslash, iLastBackslash;
	

	sProtocol = document.location.protocol;
	sPath = document.location.pathname;
	sHost = document.location.hostname;
	
	
	iLastslash = sPath.lastIndexOf("/");
	iLastBackslash = sPath.lastIndexOf("\\");
	if (iLastBackslash >iLastslash) 
		iLastslash = iLastBackslash;

	sLeft = sPath.substring(0, iLastslash+1);
	
	if (sProtocol == "file:")
		sURL = sProtocol + "//" + sLeft;
	else
		sURL = sProtocol + "//" + sHost + sLeft;
	return sURL;
}


//############################################################
//############################################################
//**********************************************************
/**
 * Function : dump()
 * Docs: http://www.openjs.com/scripts/others/dump_function_php_print_r.php
 */
function dump(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;
	
	//The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += "    ";
	
	if(typeof(arr) == 'object') { //Array/Hashes/Objects 
		for(var item in arr) {
			var value = arr[item];
			
			if(typeof(value) == 'object') { //If it is an array,
				dumped_text += level_padding + "'" + item + "' ...\n";
				dumped_text += dump(value,level+1);
			} else {
				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
			}
		}
	} else { //Stings/Chars/Numbers etc.
		dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
}

//############################################################
//############################################################
function getNodeText(poNode){
		var iNodeType, sValue, sName,i, aChildren;
		
		sName = poNode.nodeName;
		iNodeType= poNode.nodeType;
		
		switch (iNodeType){
			case 1:		//ELEMENT_NODE
				sValue = "";
				if (poNode.hasChildNodes){
				   		aChildren = poNode.childNodes;
					   for (var i = 0; i < aChildren.length; i++) 
							sValue += getNodeText(aChildren[i]);	
				}
   				break;
			case 3:		//TEXT_NODE
			case 4:		//CDATA_NODE				break;
				sValue = poNode.nodeValue;
				break;
			default:
				sValue = "unknown node type: " + iNodeType;
		}
		
		return sValue;

}

//############################################################
//############################################################
function DEBUG_PRINT(psText, piMaxLen, pbshowFuncs)
{
	var sPad;
	
	if (DEBUG__WINDOW  == null){
		DEBUG__WINDOW  = window.open('',"DEBUG");
		DEBUG__WINDOW.document.write("<PRE>");
	}
	sPad = 	repeat_string(DEBUG__PADDING, DEBUG__DEPTH)
	DEBUG__WINDOW.document.write(sPad + psText + "\n");
}


//**********************************************************
function DEBUG_ALERT(psText, pbVisualAlert)
{
	if (pbVisualAlert)
		alert (psText);
		
	DEBUG_PRINT(psText);
}

//**********************************************************
function DEBUG_EXPLODE( poThing, piCurrentLevel, piMaxLevel)
{
	var sHTML, sName, oValue, sFragment;
	var sType;
	
	sType = typeof(poThing);
	switch(sType){
		case "object":
			if (piCurrentLevel > piMaxLevel)
				sHTML = "<i>Object</i>";
			else{
				
				try{
					sHTML = "<UL>";
					for (sName in poThing){
						try{
							oValue = poThing[sName];
							sFragment = DEBUG_EXPLODE(oValue, piCurrentLevel+1, piMaxLevel);
						}
						catch (e){
							sFragment = "<font color='red'>"+ oValue+ "</font>";
						}
			
						//sFragment = oValue;
						sHTML += "<li>" + sName + " = " + sFragment;
					}
					sHTML += "</UL>";
				}catch(e){
					sHTML = "Unable to inspect " + e;
				}
			}	
			break;
		case "array":
			sHTML = "<b>array</b>";
			break;
		default:
			sHTML = "<b>" + poThing + "(" + sType +")</b>";
			break;
	}
	
	return sHTML;
}

function DEBUG_ENTER(psText){
	DEBUG_ALERT_LEVEL("&gt;&gt; enter " + psText ,FULL_DEBUG);
	DEBUG__DEPTH = DEBUG__DEPTH + 1;
}

function DEBUG_EXIT(psText){
	if (DEBUG__DEPTH  >0){
		DEBUG__DEPTH = DEBUG__DEPTH  -1;
		DEBUG_ALERT_LEVEL("&lt;&lt; exit " + psText ,FULL_DEBUG);
	}
}

function DEBUG_ALERT_LEVEL( psText, piLevel){
	if (DEBUG_LEVEL >= piLevel)
	{
		DEBUG_ALERT("DEBUG::" + psText, false);
	}
}
