/*
	executeEmbeddedScripts
	
	Based on the script from the article: Javascript script execution in innerHTML: the revenge by kratorius
	
	Extended by Jeremy Bell to support document.write
	jeremy@blackoutwebdesign.com
	Blackout Entertainment Limited, New Zealand
*/

function executeEmbeddedScripts(node){
  var bSaf = (navigator.userAgent.indexOf('Safari') != -1);
  var bOpera = (navigator.userAgent.indexOf('Opera') != -1);
  var bMoz = (navigator.appName == 'Netscape');

  if (!node) return;
	
  /* IE wants it uppercase */
  var st = node.getElementsByTagName('SCRIPT');
  var strExec;
	var scripts = st.length;
	
	i=0;
	for(j=0;j<scripts;j++){
		
		var scriptsAtStart = st.length;
		
		if (bSaf) {
      strExec = st[i].innerHTML;
      st[i].innerHTML = "";
    } else if (bOpera) {
      strExec = st[i].text;
      st[i].text = "";
    } else if (bMoz) {
      strExec = st[i].textContent;
      st[i].textContent = "";
    } else {
      strExec = st[i].text;
      st[i].text = "";
    }
		
		// Remove html comment syntax
		strExec = strExec.replace("<!--","");
		strExec = strExec.replace("//-->","");
		strExec = strExec.replace("// -->","");
		
		if(st[i].getAttribute("src")){
			// Check for src
			getDataReturnText(st[i].getAttribute("src"), function(text){ alert(text); }, function(text,url){ alert("Error "+url); }, false, null, null, true);
		} else {
			strSrc=false;
		}
		
		// Create attribute to hold document write output
		document.getElementsByTagName('body')[0].setAttribute("docWriteOutput","");
		
		// Fix document.write statements
		if(strExec) strExec = fixDocWrite(strExec);
		
    try {
      var x = document.createElement("script");
      x.type = "text/javascript";
			
			if(strExec){
				/* In IE we must use .text! */
				if ((bSaf) || (bOpera) || (bMoz))
					x.innerHTML = strExec;
				else x.text = strExec;
			} else {
				x.src = strSrc;
			}
			
      document.getElementsByTagName("head")[0].appendChild(x);
			
			// Get position just after script
			var html = node.innerHTML;
			var pos = html.indexOf('</script>',html.indexOf(strExec))>=0
				? html.indexOf('</script>',html.indexOf(strExec))
				: html.indexOf('</SCRIPT>',html.indexOf(strExec));
			pos += String('</script>').length;
			
			// Insert document.write output
			if(document.getElementsByTagName('body')[0].getAttribute("docWriteOutput")!=null){
				html = html.substr(0,pos) + document.getElementsByTagName('body')[0].getAttribute("docWriteOutput") + html.substr(pos);
				node.innerHTML = html;
			}
			
			// Is the script still there or has it been replaced with other HTML
			if(scriptsAtStart==st.length){
				// Script has not been replaced
				i++;
			}
    } catch(e) {
      alert("Script execution error: "+e);
    }
  }
}

function fixDocWrite(str){
	var replacee = 'document.write(';
	var replacer = 'document.getElementsByTagName("body")[0].setAttribute("docWriteOutput",document.getElementsByTagName("body")[0].getAttribute("docWriteOutput")+';
	while(str.indexOf(replacee)>=0){
		// Get left side
		var left = str.substr(0,str.indexOf(replacee));
		// Get position of closing bracket
		var pos = getNextScriptChar(str,(str.indexOf(replacee)+replacee.length),')');
		// Get length of middle
		var middleLength = pos - (str.indexOf(replacee)+replacee.length);
		// Get middle
		var middle = str.substr(str.indexOf(replacee)+replacee.length,middleLength);
		// Get right
		var right = str.substr(pos);
		// Rebuild string
		str = left+replacer+middle+right;
	}
	return str;
}

function getNextScriptChar(str,startingpos,char){
	var insideDoubleQuote = false;
	var insideSingleQuote = false;
	var escaped = false;
	for(j=startingpos;j<str.length;j++){
		
		if(str.charAt(j)==char&&!insideDoubleQuote&&!insideSingleQuote){ // Look for the char
			return j;
		}
		
		if(str.charAt(j)=="'"&&!escaped&&insideSingleQuote){ // Look for closing single quote
			insideSingleQuote = false;
		} else if(str.charAt(j)=="'"&&!escaped&&!insideDoubleQuote){ // Look for opening single quotes
			insideSingleQuote = true;
		}
		
		if(str.charAt(j)=='"'&&!escaped&&insideDoubleQuote){ // Look for closing double quote
			insideDoubleQuote = false;
		} else if(str.charAt(j)=='"'&&!escaped&&!insideSingleQuote){ // Look for opening double quotes
			insideDoubleQuote = true;
		}
		
		if(str.charAt(j)=='\\'&&!escaped){ // Look for escape
			escaped = true;
		} else {
			escaped = false;
		}
		
	}
	return -1;
}

/*
	getDataReturnText
	
	Snippet from the Ajax Gold framework from "Ajax for Dummies".
	
	Extended by Jeremy Bell to support caching control and basic error handling.
	jeremy@blackoutwebdesign.com
	Blackout Entertainment Limited, New Zealand
*/
function getDataReturnText(url, callback, servererrorcallback, cache)
{ 
  // Make sure we're online, otherwise call the error callback function
  if(!navigator.onLine){
	  servererrorcallback(0,url);
  }
  
  ajaxObj = false; 
  
  if (window.XMLHttpRequest) {
    ajaxObj = new XMLHttpRequest();
  } else if (window.ActiveXObject) {
    ajaxObj = new 
    ActiveXObject("Microsoft.XMLHTTP");
  }

  if(ajaxObj) {
	
		if (!cache) {
			if(url.indexOf('x=')>=0){ url = url.substr(0,url.indexOf('x=')-1); }
			if(url.indexOf('?')>=0){ url += '&'; } else { url += '?'; }
			url += 'x=' + Math.floor(Math.random()*99999999);
		}
	
    ajaxObj.open("GET", url); 

    ajaxObj.onreadystatechange = function() 
    {
			if (ajaxObj.readyState == 4 && 
				ajaxObj.status == 200) {
				callback(ajaxObj.responseText,url);
				delete ajaxObj;
				ajaxObj = null;
			} else if (ajaxObj.readyState == 4 && ajaxObj.status){
				servererrorcallback(ajaxObj.status,url);  
			}
    };

    ajaxObj.send(null);
  }
}

/*
	Ajax History Manager
	
	A cut down version of the Really Simple History framework from Brad Neuberg
	
	Cut down by Jeremy Bell.
	jeremy@blackoutwebdesign.com
	Blackout Entertainment Limited, New Zealand
*/

// Variables
var ajaxHistoryDefaultHash;
var ajaxHistoryExpectedHash;
var ajaxHistoryMasterHash;
var ajaxHistoryIEHash;
var ajaxHistoryCallback;

// Functions
function ajaxHistoryInitiate(callback,def){
	if(isMSIE()) document.write('<iframe style="border: 0px; width: 1px; height: 1px; position: absolute; bottom: 0px; right: 0px; visibility: visible; display:none;" name="historyframe" id="historyframe" src="blank.html"></iframe>');
	ajaxHistoryCallback = callback;
	ajaxHistoryDefaultHash = def;
	ajaxHistoryCheckHash();
}

function ajaxHistoryCheckHash(){
	if(!ajaxHistoryExpectedHash && window.location.hash!=''){
		ajaxHistoryMasterHash=window.location.hash.substr(1);
	} else if(!ajaxHistoryExpectedHash){
		ajaxHistoryMasterHash=ajaxHistoryDefaultHash;
		ajaxHistoryExpectedHash = ajaxHistoryDefaultHash+'x';
	} else {
		if(isMSIE()) {
			if(ajaxHistoryIEHash != ajaxHistoryMasterHash && window.location.hash.substr(1)==ajaxHistoryMasterHash){
				ajaxHistoryMasterHash = ajaxHistoryIEHash;
			} else if(window.location.hash.substr(1)!=ajaxHistoryMasterHash){
				ajaxHistoryMasterHash = window.location.hash.substr(1);
			}
		} else {
			ajaxHistoryMasterHash = window.location.hash.substr(1);
		}
	}
	if(ajaxHistoryMasterHash){
		if(ajaxHistoryMasterHash!=ajaxHistoryExpectedHash){
			ajaxHistoryCallback(ajaxHistoryMasterHash);
		}
		setTimeout("ajaxHistoryCheckHash();",200);
	} else {
		window.history.go(-2);
	}
}

function ajaxHistoryAdd(hash){
	window.location.hash = hash;
	ajaxHistoryMasterHash = hash;
	ajaxHistoryExpectedHash = hash;
	ajaxHistoryIEHash = hash;
	if(isMSIE()) document.getElementById('historyframe').contentWindow.location = 'blank.html?hash='+hash;
}

/*
	Misc stuff
*/

function isMSIE(){
	var userAgent = navigator.userAgent.toLowerCase();
	return document.all && userAgent.indexOf('msie')!=-1 ? true : false;
}