/***************************************************************
* JavaScript Observer Pattern                                  *
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
* (C) Copyright 2007, Daniel Boorn, all rights are reserverd   *
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
* THIS CODE IS NOT OPEN SOURCE CODE AND IS SUBJECT TO A        *
* SOFTWARE LICENSE AGREEMENT. YOU MAY NOT COPY, GIVE AWAY,     *
* REPRODUCE THIS CODE. SEE LICENSE AGREEMENT FOR FULL DETAILS  *
***************************************************************/

/**************************************************************************/

/* XML Node Module (void) */
function xmlnode(){
	this.tagname = "";
	this.attributes = new Array();
	this.value = "";
	this.addAttribute = function(name, value){
		this.attributes[this.attributes.length] = new Array(name, value);
	}
	var tmp = new Date();
	this.time = tmp.getTime();
		
}

/* HTML XML Request Module (string, string, string, object) */
function ajax(page, getPost, sendVars, readyStateHandler){
	//Builld xml http request object
    var xmlHttpReq = false;
    if (window.XMLHttpRequest) 
       xmlHttpReq = new XMLHttpRequest();// Mozilla/Safari
    else if (window.ActiveXObject)// IE
       xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
	//post request to fetchpage php file
    xmlHttpReq.open(getPost, page, true);
    xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlHttpReq.onreadystatechange = function (){ 
		if(xmlHttpReq.readyState == 4){//On load state
			try{
				readyStateHandler(xmlHttpReq.responseText);
			}catch(e){
			}
		}
	}
    xmlHttpReq.send(sendVars);
}


function RTUS(self){

	this.xmllog = new Array();
	this.loginterval = 100; //one second 
	this.minloglength = 1; 
	this.datetime = new Date();	
	this.self = self;
	this.sendBodyHTML = true;
	
	//dump xml log to screen
	this.dumpXmlLogToScreen = function(){
		alert("Log length:"+this.xmllog.length);
		alert("Min Log length:"+this.minloglength);
		alert(this.generateXmlDoc());
	}
	
	
	this.generateXmlDoc = function(){
		
		var width, height = 0;
		if( typeof( window.innerWidth ) == 'number' ) {
			//Non-IE
			width = window.innerWidth;
			height = window.innerHeight;
		} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
			//IE 6+ in 'standards compliant mode'
			width = document.documentElement.clientWidth;
			height = document.documentElement.clientHeight;
			} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
		//IE 4 compatible
			width = document.body.clientWidth;
			height = document.body.clientHeight;
		}
		
//		var xmldoc = "<entry>";
		xmldoc = "<window";
		xmldoc += " width='"+width+"'";
		xmldoc += " height='"+height+"'";
		xmldoc += " location='"+window.location+"'";
		xmldoc += " time='"+this.datetime.getTime()+"'";
		xmldoc += " />";
		for(var i=0; i<this.xmllog.length; i++){
			var tmp = "<event";
			tmp += " type='"+this.xmllog[i].tagname+"'";
			tmp += " time='"+this.xmllog[i].time+"'";
			for(var k=0; k<this.xmllog[i].attributes.length; k++){
				tmp += " "+this.xmllog[i].attributes[k][0];
				tmp += "='"+this.xmllog[i].attributes[k][1]+"'";
			}
			tmp += ">";
			tmp += this.xmllog[i].value;
			tmp += "</event>";
			xmldoc += tmp;
		}
//		xmldoc += "</entry>";
		return xmldoc;
	}		
				
	
	//add xml node to xml log
	this.addXmlNode = function(xmlnode){
		this.xmllog[this.xmllog.length] = xmlnode;
	}
	
	
	this.mmCount = 0;
	//record mouse position
	this.onmousemove = function(evt){
		if(this.mmCount%3==0){
			var node = new xmlnode();
			node.tagname = "mousemove";
			if(isIE()){
				var x, y = 0;			
				if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
					//DOM compliant
					y = document.body.scrollTop;
					x = document.body.scrollLeft;
				}else{
					//IE6 standards compliant mode
					y = document.documentElement.scrollTop;
					x = document.documentElement.scrollLeft;			
				}				
				//add in scrolling
				node.addAttribute("pagex", evt.clientX+x);
				node.addAttribute("pagey", evt.clientY+y);						
			}else{
				node.addAttribute("pagex", evt.pageX);
				node.addAttribute("pagey", evt.pageY);	
			}
			this.addXmlNode(node);
		}
		this.mmCount++;
	}
	
	//record page scroll
	this.onscroll = function(evt){
//		var_dump(evt);
		var node = new xmlnode();
		node.tagname = "scroll";
		if(isIE()){
			var x, y = 0;			
			if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
				//DOM compliant
				y = document.body.scrollTop;
				x = document.body.scrollLeft;
			}else{
				//IE6 standards compliant mode
				y = document.documentElement.scrollTop;
				x = document.documentElement.scrollLeft;			
			}
			node.addAttribute("pagexoffset", x);
			node.addAttribute("pageyoffset", y);				
		}else{
			node.addAttribute("pagexoffset", window.pageXOffset);
			node.addAttribute("pageyoffset", window.pageYOffset);	
		}
		this.addXmlNode(node);
	}	
	
	//record mouse down
	this.onmousedown = function(evt){
		var node = new xmlnode();
		node.tagname = "mousedown";
		if(isIE()){
			node.addAttribute("pagex", evt.x);
			node.addAttribute("pagey", evt.y);						
		}else{
			node.addAttribute("pagex", evt.pageX);
			node.addAttribute("pagey", evt.pageY);	
		}
		node.addAttribute("targetid",evt.target.id);
		node.addAttribute("targetparentnodeid", evt.target.parentNode.id);
		this.addXmlNode(node);
	}
	
	//record mouse up
	this.onmouseup = function(evt){
		var node = new xmlnode();
		node.tagname = "mouseup";
		if(isIE()){
			node.addAttribute("pagex", evt.x);
			node.addAttribute("pagey", evt.y);						
		}else{
			node.addAttribute("pagex", evt.pageX);
			node.addAttribute("pagey", evt.pageY);	
		}
		node.addAttribute("targetid",evt.target.id);
		node.addAttribute("targetparentnodeid", evt.target.parentNode.id);
		this.addXmlNode(node);
	}
	
	//record on focus
	this.onfocus = function(evt){
		var node = new xmlnode();		
		node.tagname = "focus";
		if(isIE() && evt.srcElement.id){
			node.addAttribute("pagex", evt.x);
			node.addAttribute("pagey", evt.y);						
			node.addAttribute("targetid",evt.srcElement.id);
			node.addAttribute("targetparentnodeid", evt.srcElement.parentNode.id);				
			this.addXmlNode(node);				
		}else if(evt.target.id){
			node.addAttribute("pagex", evt.pageX);
			node.addAttribute("pagey", evt.pageY);	
			node.addAttribute("targetid",evt.target.id);
			node.addAttribute("targetparentnodeid", evt.target.parentNode.id);				
			this.addXmlNode(node);				
		}
	}
	
	//record on key down
	this.onkeydown = function(evt){
		var node = new xmlnode();		
		node.tagname = "keydown";
		if(isIE()){
			node.addAttribute("pagex", evt.x);
			node.addAttribute("pagey", evt.y);						
			node.addAttribute("which", evt.keyCode);			
		}else{
			node.addAttribute("pagex", evt.pageX);
			node.addAttribute("pagey", evt.pageY);	
			node.addAttribute("which", evt.which);			
			node.addAttribute("targetid",evt.target.id);
			node.addAttribute("targetparentnodeid", evt.target.parentNode.id);			
		}
		node.addAttribute("modifiers", evt.modifiers);
		this.addXmlNode(node);
	}	
	
	//tmp
	this.onclick = function(evt){
//		this.dumpXmlLogToScreen();
	}
	

	//send log to server every second
	this.sendLog = function(){	
		//check to see if log needs to be sent
		if(this.xmllog.length>=this.minloglength){
			var tmp = this.generateXmlDoc();
			tmp = "log="+tmp;
			if(this.sendBodyHTML){
				tmp += "&head="+escape(document.getElementsByTagName("HEAD")[0].innerHTML);				
				tmp += "&html="+escape(document.body.innerHTML);
				this.sendBodyHTML=false;
			}
			ajax("/rtus/rtus.php", "POST", tmp, function(txt){  /*alert(txt);*/ });			
//			ajax("/rtus/rtus.php", "POST", tmp, function(txt){ });
			this.xmllog = new Array();
		}
		window.setTimeout(this.self+".sendLog()", this.loginterval);		
	}	
	
	this.sendLog();

}
RTUS.prototype = new Observer;
//-----------------------------------------------------------------------
function cursorFun(){
	this.onmousemove = function(evt){
		this.cursor = document.getElementById('cursorimage');
		this.cursor.style.left = evt.pageX+"px";
		this.cursor.style.top = evt.pageY+"px";
	}
}	
cursorFun.prototype = new Observer;
//-----------------------------------------------------------------------
function var_dump(foobar){
	var message = foobar + "\n";
	count = 0;
	for(var i in foobar){
		message += i+", ";
		if(count%3==0) message += "\n";
		count++;
	}
	alert(message);
}


	var webpageSubject = new Subject(document.body, 'webpageSubject');
	//create instance of rtus
	var observer1 = new RTUS('observer1');
	webpageSubject.registerObserver(observer1);
	//var observer2 = new cursorFun();
	//webpageSubject.registerObserver(observer2);

