/**
 * Event Pump.
 *
 * Move events from one browser to another.
 */

function fireEvent(element,event){
    if (document.createEventObject){
        // dispatch for IE
        var evt = document.createEventObject();
        return element.fireEvent('on'+event,evt)
    }else{
        // dispatch for firefox + others
				var evt;
				if(event == "click"){
					evt = document.createEvent("MouseEvents");
					evt.initMouseEvent(event,true,true,window,0, 0, 0, 0, 0, false, false, false, false, 0, null);
				}else{
        	evt = document.createEvent("HTMLEvents");
        	evt.initEvent(event, true, true ); // event type,bubbling,cancelable
				}
        var rv = element.dispatchEvent(evt);
				return rv;
    }
}

function getElementXPath(elt)
{
     var path = "";
		 var id = "";
		 var first = true;
     for (; elt && elt.nodeType == 1; elt = elt.parentNode)
     {
        idx = getElementIdx(elt);
        xname = elt.tagName;
				id = Element.readAttribute(elt,"id");
				if(id != null && id != "" && !id.match(/\d/)){
					xname += '[@id = "' + id + '"]';
					return "//" + xname + path;
				}else {
					xname += "[" + idx + "]";
				}

        path = "/" + xname + path;

				first = false;
     }
     return path;       
}

function getElementIdx(elt)
{
    var count = 1;
    for (var sib = elt.previousSibling; sib ; sib = sib.previousSibling)
    {
        if(sib.nodeType == 1 && sib.tagName == elt.tagName)     count++
    }
    
    return count;
}

function masterClickEvent(e){
	var el = Event.element(e);
	var args = new Array(readCookie("master"),getElementXPath(el));
	new Ajax.Request('/DemoGateway/submitClickEvent',{method: 'post', postBody: Object.toJSON(args), asynchronous: false});
}

function masterChangeEvent(e){
	var el = Event.element(e);
	var args = new Array(readCookie("master"),getElementXPath(el),el.value);
	new Ajax.Request('/DemoGateway/submitChangeEvent',{method: 'post',postBody: Object.toJSON(args),asynchronous: false});
}

function masterMouseoverEvent(e){
	var el = Event.element(e);
	var args = new Array(readCookie("master"),getElementXPath(el));
	new Ajax.Request('/DemoGateway/submitMouseoverEvent',{method: 'post', postBody: Object.toJSON(args)});
}

function masterMouseoutEvent(e){
	var el = Event.element(e);
	var args = new Array(readCookie("master"),getElementXPath(el));
	new Ajax.Request('/DemoGateway/submitMouseoutEvent',{method: 'post', postBody: Object.toJSON(args)});
}

function masterFocusEvent(e){
	var el = Event.element(e);
	var args = new Array(readCookie("master"),getElementXPath(el));
	new Ajax.Request('/DemoGateway/submitFocusEvent',{method: 'post', postBody: Object.toJSON(args)});
}

function masterSelectChangeEvent(e){
	var el = Event.element(e);
	var args = new Array(readCookie("master"),getElementXPath(el),el.selectedIndex);
	new Ajax.Request('/DemoGateway/submitSelectChangeEvent',{method: 'post',postBody: Object.toJSON(args)});
}


function masterPopulate(){

	var elements = null;
	var el = null;
	var args = null;
	var i,j;
	var type = null;

	elements = document.getElementsByTagName('a');

	for(i = 0;i < elements.length;i++){
		el = elements[i];
		if(Element.readAttribute(el,"ep:event") == null){
			Element.writeAttribute(el,"ep:event","true");
			Event.observe(el,"click",masterClickEvent);
			Event.observe(el,"mouseover",masterMouseoverEvent);
			Event.observe(el,"mouseout",masterMouseoutEvent);
		}
	}

	elements = document.getElementsByTagName('input');

	for(i = 0;i < elements.length;i++){
		el = elements[i];

		if(Element.readAttribute(el,"ep:event") == null){

			if(Element.readAttribute(el,"type") != null){
				type = Element.readAttribute(el,"type");
			}else{
				type = "submit";
			}

			if(type == "submit" || type == "button" || type == "image"){
				Event.observe(el,"click",masterClickEvent);
			}else{
				Event.observe(el,"change",masterChangeEvent);
			}
			
			Event.observe(el,"mouseover",masterMouseoverEvent);
			Event.observe(el,"mouseout",masterMouseoutEvent);
			Event.observe(el,"focus",masterFocusEvent);

			Element.writeAttribute(el,"ep:event","true");
		}
	}

	elements = document.getElementsByTagName('select');

	for(i = 0;i < elements.length;i++){
		el = elements[i];

		if(Element.readAttribute(el,"ep:event") == null){
			Event.observe(el,"mouseover",masterMouseoverEvent);
			Event.observe(el,"mouseout",masterMouseoutEvent);
			Event.observe(el,"change",masterSelectChangeEvent);
			Element.writeAttribute(el,"ep:event","true");
		}
	}


	elements = document.getElementsByTagName("textarea");

	for(i = 0;i < elements.length;i++){
		el = elements[i];

		if(Element.readAttribute(el,"ep:event") == null){
			Event.observe(el,"change",masterChangeEvent);			
			Event.observe(el,"mouseover",masterMouseoverEvent);
			Event.observe(el,"mouseout",masterMouseoutEvent);
			el.setAttribute("ep:event","true");
		}
	}
}

function masterInitStatus(){
	masterStatusDiv = document.createElement("div");
	document.body.appendChild(window.masterStatusDiv);
	masterStatusDiv.style.position = "absolute";
	masterStatusDiv.style.top = "0px";
	masterStatusDiv.style.left = "0px";
	window.masterStatusInput = document.createElement("input");
	window.masterStatusInput.style.width = "2em";
	masterStatusDiv.appendChild(window.masterStatusInput);
}

function masterPollStatus(){
	var args = new Array(readCookie("master"));
	new Ajax.Request('/DemoGateway/getSessionEventCount',{method: 'post',postBody: Object.toJSON(args),onSuccess: masterPollStatusResponse});
}

function masterPollStatusResponse(transport){
	var pendingEvents = transport.responseText.evalJSON(true);
	masterStatusInput.value = pendingEvents;
}

function initSlaveMouse(){
	slaveMouseImage = new Image();
	slaveMouseImage.src = "/images/am_cursor.gif";

	window.slaveMouseDiv = document.createElement("div");
	var imgEl = document.createElement("img");
	
	document.body.appendChild(slaveMouseDiv);

	window.slaveMouseDiv.appendChild(imgEl);
	Element.writeAttribute(imgEl,"src",slaveMouseImage.src);

	window.slaveMouseDiv.style.position = "absolute";
	window.slaveMouseDiv.style.top = "0px";
	window.slaveMouseDiv.style.left = "0px";
	window.targetPosition = new Array(0,0);
	window.currentPosition = new Array(0,0);
	window.currentSpeed = new Array(0,0);
	window.positions = new Array();
	setInterval("intervalSlaveMouse()",10);
}

function intervalSlaveMouse(){
	var maxSpeed = 50;


	if(Math.abs(currentPosition[0] - targetPosition[0]) < 2 && Math.abs(currentPosition[1] - targetPosition[1]) < 2 && positions.length > 0){
		targetPosition = positions.shift();
	}


	if(Math.abs(currentPosition[0] - targetPosition[0]) > 1 || Math.abs(currentPosition[1] - targetPosition[1]) > 1){

		currentSpeed[0] = Math.abs(currentPosition[0] - targetPosition[0]) / 10;

		if(currentSpeed[0] > maxSpeed){
			currentSpeed[0] = maxSpeed;
		}

		if(currentSpeed[0] < 1){
			currentSpeed[0] = 1;
		}
		
		currentSpeed[1] = Math.abs(currentPosition[1] - targetPosition[1]) / 10;

		if(currentSpeed[1] > maxSpeed){
			currentSpeed[1] = maxSpeed;
		}

		if(currentSpeed[1] < 1){
			currentSpeed[1] = 1;
		}

		if(currentPosition[0] > targetPosition[0]){
			currentPosition[0]-= currentSpeed[0];
		}else if(currentPosition[0] < targetPosition[0]){
			currentPosition[0]+= currentSpeed[0];
		}

		if(currentPosition[1] > targetPosition[1]){
			currentPosition[1]-= currentSpeed[1];
		}else if(currentPosition[1] < targetPosition[1]){
			currentPosition[1]+= currentSpeed[1];
		}
	}

	slaveMouseDiv.style.top = currentPosition[1] + "px";
	slaveMouseDiv.style.left = currentPosition[0] + "px";

	var dialog = $('overlay_modal');

	if(dialog != null){
		slaveMouseDiv.style.zIndex = dialog.style.zIndex + 2;
	}
}

function slaveClickMouse(){
	currentPosition[1] += 6;
	slaveMouseDiv.style.top = currentPosition[1] + "px";
}

function slavePollTimeout(){
	var d = new Date();
	if(d.getTime() - window.slaveStatus < 3000){
		return;
	}

	slavePoll();
}

function slavePoll(){
	var d = new Date();
	window.slaveStatus = d.getTime();
	var args = new Array(readCookie("slave"));
	new Ajax.Request('/DemoGateway/getNextEvent',{method: 'post',postBody: Object.toJSON(args),onSuccess: slavePollResponse});
}

function slavePollResponse(transport){
	var response = transport.responseText.evalJSON(true);
	var eventId = parseInt(response[0]);
	var eventType = parseInt(response[1]);
	var args;


	if(eventId){
		switch(eventType){
			case 1:
				args = new Array(readCookie("slave"),eventId);
				new Ajax.Request('/DemoGateway/getClickEvent',{method: 'post', postBody: Object.toJSON(args),onSuccess: slaveClickResponse});
				break;

			case 2:
				args = new Array(readCookie("slave"),eventId);	
				new Ajax.Request('/DemoGateway/getChangeEvent',{method: 'post', postBody: Object.toJSON(args),onSuccess: slaveChangeResponse});
				break;

			case 3:
				args = new Array(readCookie("slave"),eventId);
				new Ajax.Request('/DemoGateway/getFocusEvent',{method: 'post', postBody: Object.toJSON(args),onSuccess: slaveFocusResponse});
				break;

			case 4:
				args = new Array(readCookie("slave"),eventId);
				new Ajax.Request('/DemoGateway/getSelectChangeEvent',{method: 'post', postBody: Object.toJSON(args),onSuccess: slaveSelectChangeResponse});
				break;

			case 5:
				args = new Array(readCookie("slave"),eventId);
				new Ajax.Request('/DemoGateway/getMouseoverEvent',{method: 'post', postBody: Object.toJSON(args),onSuccess: slaveMouseoverResponse});
				break;
			
			case 6:
				args = new Array(readCookie("slave"),eventId);
				new Ajax.Request('/DemoGateway/getMouseoutEvent',{method: 'post', postBody: Object.toJSON(args),onSuccess: slaveMouseoutResponse});
				break;
				

			default:
				break;
		}
	}else{
		window.slaveStatus = false;
	}
}

function slaveClickResponse(transport){
	var response = transport.responseText.evalJSON(true);
	var eventId = response[0];
	var xPath = response[1];
	var elements;
	var i,j;
	var element;
	var evt;

	if(eventId){
		elements = $x(xPath);
		for(i = 0;i < elements.length;i++){
			element = elements[i];
			slaveClickMouse();
			var def = fireEvent(element,"click");
			if(def && element.tagName == "A"){
				var href = Element.readAttribute(element,"href");
				if(href != ""){
					window.location = href;
				}	
			}

			if(def && element.tagName == "INPUT"){
				var type = Element.readAttribute(element,"type");
				if(type == "submit"){
					element.form.submit();
				}
			}
		}
		slavePoll();
	}else{
		window.slaveStatus = false;
	}
}

function slaveChangeResponse(transport){
	var response = transport.responseText.evalJSON(true);
	var eventId = response[0];
	var xPath = response[1];
	var value = response[2];
	var elements;
	var i;

	if(eventId){
		elements = $x(xPath);
		for(i = 0;i < elements.length;i++){
			var type = Element.readAttribute(elements[i],"type");

			if(type == "checkbox" || type == "radio"){
				var def = fireEvent(elements[i],"change");
				if(def){
					elements[i].checked = !elements[i].checked;
				}
			}else{
				elements[i].value = value;
				var def = fireEvent(elements[i],"change");
			}

		}
		slavePoll();
	}else{
		window.slaveStatus = false;
	}
}

function slaveSelectChangeResponse(transport){
	var response = transport.responseText.evalJSON(true);
	var eventId = response[0];
	var xPath = response[1];
	var index = response[2];
	var elements;

	if(eventId){
		elements = $x(xPath);
		for(i = 0;elements.length;i++){
			slaveClickMouse();
			elements[i].selectedIndex = index;
			fireEvent(elements[i],"change");
		}
		slavePoll();
	}else{
		window.slaveStatus = false;
	}
}


function slaveFocusResponse(transport){
	var response = transport.responseText.evalJSON(true);
	var eventId = response[0];
	var xPath = response[1];
	var elements;

	if(eventId){
		elements = $x(xPath);
		if(elements.length > 0){
			fireEvent(elements[0],"focus");
		}
		slavePoll();
	}else{
		window.slaveStatus = false;
	}
}

function slaveMouseoverResponse(transport){
	var response = transport.responseText.evalJSON(true);
	var eventId = response[0];
	var xPath = response[1];
	var elements;
	var postion;
	var height;
	var hOffset;
	var width;
	var wOffset;

	if(eventId){
		elements = $x(xPath);
		if(elements.length > 0){
			fireEvent(elements[0],"mouseover");
			position = Element.cumulativeOffset(elements[0]);
			height = Element.getHeight(elements[0]);
			hOffset = height / 2;
			width = Element.getWidth(elements[0]);
			wOffset = width / 2;

			window.positions.push(new Array(position[0] + wOffset,position[1] + hOffset));
		}
		slavePoll();
	}else{
		window.slaveStatus = false;
	}
}

function slaveMouseoutResponse(transport){
	var response = transport.responseText.evalJSON(true);
	var eventId = response[0];
	var xPath = response[1];
	var elements;

	if(eventId){
		elements = $x(xPath);
		if(elements.length > 0){
			fireEvent(elements[0],"mouseout");
		}
		slavePoll();
	}else{
		window.slaveStatus = false;
	}
}

function initPump(){
	if(readCookie("master")){
		masterInitStatus();
		masterPopulate();
		window.setInterval('masterPopulate()',1000);
		window.setInterval('masterPollStatus()',500);
	}else if(readCookie("slave")){
		window.setInterval('slavePollTimeout()',1000);
		initSlaveMouse();
	}
}

Event.observe(window,'load',initPump);

