
/*
Copyright 2007 GroundWork Open Source, Inc. ("GroundWork")
All rights reserved. This program is free software; you can redistribute it and/or modify it under 
the terms of the GNU General Public License version 2 as published by the Free Software Foundation.

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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
Boston, MA 02110-1301, USA.  
*/
dojo.provide("guava.core.NodeManager");


guava.core.NodeManager = {
	
	role : "unknown",
	nodes : new Array(),
	
	initialized : 0,
	
	startWait : function() {
		// start a timer to check for init.
		if((opener == null) || opener.guava == undefined ||  opener.guava.core.NodeManager.role == undefined) {
			// We're the first window
			guava.core.NodeManager.load();
		}
		else {
			setTimeout("guava.core.NodeManager.load()", 1000);
		}
	},
	
	getMaster : function() {
		return this.nodes[0];
	},
	
	unloadObject : function(identifier) {
		addMessage('framework', 'objectunload', [{'name' : 'identifier', 'type' : 'string', 'value' : identifier}]);
		sendMessageQueue();
	},
	
	load : function() {
		debug("Guava NodeManager initializing for this window.");
		if(!this.initialized) {
			this.initialized = 1;
			if(opener != null && opener.guava != undefined) {
				opener.guava.core.NodeManager.finishSpawn(window);
			}
			else {
				role = "master";
			}
			this.addNode(window);
		}
		setTimeout("guava.core.NodeManager.pollNodes()", 1000);
		
		// Set another timer which will do the "polling" of guava (if enabled)
		setTimeout("guava.core.NodeManager.poll()", (pollSettings.timer * 1000));
	},
	
	poll : function() {
		if(pollSettings.enabled == 1 && role == "master") {
			guava.core.NodeManager.pollguava();
			setTimeout("guava.core.NodeManager.poll()", (pollSettings.timer * 1000));
		}
	},
	
	pollguava : function () {
			if(guava.core.NodeManager.getMaster.__guavaProgression == false || guava.core.NodeManager.getMaster.__guavaProgression == undefined) {
				// We aren't in the middle of a request.
				start_time = new Date();
				dojo.io.bind({ url: prepareURL('rpc.php?action=poll'), load: guava.core.NodeManager.handleRPCResponse, method: "GET"});
			}
	},
	
	publish : function(response) {
		numOfNodes = this.nodes.length;
		for(mycounter = 0; mycounter < numOfNodes; mycounter++) {
			try {
				this.nodes[mycounter].handleWorkload(response, mycounter);
			}
			catch(e) {
				// do nothing
			}
		}
	},
	
	handleRPCResponse : function (type, data) {
		debugInbound(data);
		try {
			response = dojo.dom.createDocumentFromText(data);
		}
		catch(e) {
			//alert("There was a fatal error inside Guava.  Guava cannot continue.  Will attempt to logout and restart your session.");
			//location.href="logout.php";
			return;
		}
		if(response.documentElement.tagName == "parserError" || response.documentElement.namespaceURI == "http://www.mozilla.org/newlayout/xml/parsererror.xml") {
			guava.core.NodeManager.getMaster.__guavaProgression = true;	// In case it wasn't set.  This will stop polling.
			guava.core.NodeManager.getMaster.__guavaError = true;
			toggleProgression(true);
			widget = dojo.widget.getWidgetById('__errorDialog');
			if(widget) {
				document.getElementById('__errorDialog.error').value = data;
				widget.show();
			}
			//location.href="logout.php";
			return;	
		}
		debug("Successfully received Response XML.  Passing to all nodes for processing.");

		guava.core.NodeManager.publish(response);
		
		sysstats = response.getElementsByTagName("systemstats");
		if(sysstats.length) {
			properties = sysstats[0].getElementsByTagName("property");
			numOfProperties = properties.length;
			for(propertycounter = 0; propertycounter < numOfProperties; propertycounter++) {
				targetName = properties[propertycounter].getAttribute("name");
				if(typeof(properties[propertycounter].childNodes[0]) == 'undefined') {
					propertyValue = '';
				}
				else {
					propertyValue = properties[propertycounter].childNodes[0].nodeValue;
				}
				if(document.getElementById(targetName)) {
					document.getElementById(targetName).innerHTML = propertyValue;
				}	
			}
		}
		guava.core.NodeManager.getMaster.__guavaProgression = false;
		toggleProgression(true);
	},
	
	update : function() {
		if(role == "master") {
			numOfNodes = this.nodes.length;
			for(mycounter = 0; mycounter < numOfNodes; mycounter++) {
				// Currently empty
			}
		}
		setTimeout("guava.core.NodeManager.update()", 1000);
	
	},
	
	pollNodes : function() {
		numOfNodes = this.nodes.length;
		buffer = '';
		for(mycounter = 0; mycounter < numOfNodes; mycounter++) {
			try {
			if((this.nodes[mycounter] == null) || this.nodes[mycounter].closed) {
				// First check to see if it was the master, if so, elect the next sibling
				// to become the new master
				if(mycounter == 0) {
					// Was master, notify second
					if(this.nodes[mycounter + 1] == null) {
						// I'm the only one left!
						this.changeRole("master");
					}
					else {
						this.nodes[mycounter + 1].guava.core.NodeManager.changeRole("master");
					}
				}
				// We need to remove this sibling!  Ack pfft!
				this.nodes.splice(mycounter, 1);
			}
			else {
				// Check to see if it lost init data (the browser was refreshed for some reason)
				if(this.nodes[mycounter].guava.core.NodeManager.initialized == undefined) {
					// This is no longer part of the browser net
					this.nodes.splice(mycounter, 1);
				}
				else if(this.nodes[mycounter].guava.core.NodeManager.initialized == 0) {
					this.nodes[mycounter].guava.core.NodeManager.initialized = 1;
					// We need to transfer stuff over.
					if(mycounter == 0) {
						this.nodes[mycounter].guava.core.NodeManager.changeRole("master");
					}
					else {
						this.nodes[mycounter].guava.core.NodeManager.changeRole("child");
					}
					// Transfer all our nodes over
					
					numOfNodes = this.nodes.length;
					found = 0;
					for(mysubcounter = 0; mysubcounter < numOfNodes; mysubcounter++) {
						this.nodes[mycounter].guava.core.NodeManager.addNode(this.nodes[mysubcounter]);
					}
				}
			}
			}
			catch(e) {
				// do nothing
			}
		}
		setTimeout("guava.core.NodeManager.pollNodes()", 1000);
	},
	
	
	changeRole : function (newRole) {
		role = newRole;
	},
	
	
	addNode : function (nodeWindow) {
		this.nodes.push(nodeWindow);
	},
	
	
	finishSpawn : function (newNode) {
		newNode.guava.core.NodeManager.changeRole("child");
		// Transfer all our nodes over
		numOfNodes = this.nodes.length;
		found = 0;
		for(mycounter = 0; mycounter < numOfNodes; mycounter++) {
			if(this.nodes[mycounter] == newNode) {
				found = 1;
			}
			newNode.guava.core.NodeManager.addNode(this.nodes[mycounter]);
		}
		if((found == 0)) {
			newNode.guava.core.NodeManager.announceMembership();
		}
	},
	
	
	announceMembership : function() {
		numOfNodes = this.nodes.length;
		for(mycounter = 0; mycounter < numOfNodes; mycounter++) {
			this.nodes[mycounter].guava.core.NodeManager.addNode(window);
		}
	}
	

}


// Attach event to document load
dojo.addOnLoad(guava.core.NodeManager.startWait);
