/*
 * This is an javascript file that handles all the Userinput
 * and XMPP evenent's of this example.
 * 
 * All the credits why this is so fast and easy to do goes to Strophe library.
 * Read more about Strophe from: "http://code.stanziq.com/strophe/".
 */

// Domain where we will be connecting.
var domain 			= "www.lobstermonster.org";

// Username we'll use. Since in this example we are going to
// log in as anonymous, we'll set it empty.
var username 		= "xmpp.lobstermonster.org";

// Password will be left empty, since we'll log in as anonymous.
var password		= "";

// Address where our XMPP Bosh service is listening connections.
var BOSH_SERVICE	= "http://" + domain + "/http-bind-punjab/";

// This is the main Stophe connection.
// Read more about it from:
// (http://people.chesspark.com/~jack/strophe-preview/doc/files/strophe-js.html#Strophe.Connection.Strophe.Connection)
var connection 		= null; 

// Here we have some variables to to keep the code more readable later on.
var EVERY_NAMESPACE      = null;
var EVERY_IQ_TYPE        = null;
var EVERY_IQ_WITH_ANY_ID = null;
var FROM_ANY_SERNDER     = null;

/*
 * When the HTML page is loaded (document ready), we try to connect
 * automatically to the XMPP Server and we define handers to catch
 * users' inputs
 */
$(document).ready(function () {
	
	connection 				= new Strophe.Connection(BOSH_SERVICE);               
	
	// Here we set 2 handlers to catch all the received(rawInput) and send(rawOutput)
	// data of the connection to the XMPP Server. We will use these callbacks to
	// log the incoming/outgoing traffic.
	connection.rawInput 	= rawInputHandler;
	connection.rawOutput 	= rawOutputHandler;
	
	// We start the connection process to the XMPP Server. The third parameter
	// "onConnectCallbackHandler" will handle all the "connection states".
	connection.connect( username, password, onConnectCallbackHandler);
	
	/* End of XMPP connection stuff.*/
	
	/*
	 * What happends when user clicks the Calculate button on the 
	 * form.
	 */
	$("#calculate-button").bind("click", function () {
		
		var atomsToCount = $("#atoms").get(0).value;
		if(atomsToCount == "") {		
			log("Atoms not set. Will not do nothing.");    
    		alert("Add some atoms first.");
            return false;
        }
		
		/*
		 * Next we need to send something like this:
		 * <iq id='JSO-0.12.5-6' 
		 *     to='cdk.ws1.bmc.uu.se' 
		 *     type='set'>
		 *     <command xmlns='http://jabber.org/protocol/commands' 
		 *     			action='execute' 
		 *     			node='calculateMass'>
		 *     			<iodata xmlns='urn:xmpp:tmp:io-data' 
		 *     					type='input'>
		 *     					<in>
		 *     						<smiles xmlns='urn:xws:cdk:input'>CCC</smiles>
		 *     					</in>
		 *     			</iodata>
		 *     </command>
		 * </iq>
		 */
		
		// Here we create the IQ we need to send. 
		//
		// Please read more about the $iq() -function from :
		// http://people.chesspark.com/~jack/strophe-preview/doc/files/strophe-js.html#$iq
		//
		// More about the other .c() and .t() -methods, read from there:
		// http://people.chesspark.com/~jack/strophe-preview/doc/files/strophe-js.html#Strophe.Builder.Strophe.Builder
		var calCommand = $iq({"id":connection.getUniqueId("LM"), "to":"cdk.ws1.bmc.uu.se", "type":"set"})
						 .c("command", {"xmlns":"http://jabber.org/protocol/commands", "action":"execute", "node":"calculateMass"})
						 .c("iodata", {"xmlns":"urn:xmpp:tmp:io-data", "type":"input"})
						 .c("in")
						 .c("smiles", {"xmlns":"urn:xws:cdk:input"}).t(atomsToCount);
		
		// And we send the created IQ
		connection.send(calCommand.tree());
		
		// And we change the status text to the textarea with ID="results".
		$("#results").val("Calculation Command Send."); 	
	});
	
});

// Handler that will get all data as a string we
// receive from the XMPP Server.
function rawInputHandler(data)	{                      
	log("XMPP RECV: " + data);
} 

// Handler that will get all the data as string we will send 
// to the XMPP connection.
function rawOutputHandler(data)	{                      
	log("XMPP SEND: " + data);
} 

// Just a simple helper function to add  log to the log -div.
function log(msg) {
	var logMessage = $("<div>").text(document.createTextNode(msg).nodeValue);
	$("#log").prepend(logMessage.html() + "</div><hr />");    
}

// Handler that will handle all the states of the connection.
// As the connection process proceeds, the callback will be triggered 
// multiple times with status updates.  The callback should take two arguments - the status code and the error condition.
// The status code will be one of the values in the Strophe.Status constants.  
// The error condition will be one of the conditions defined in RFC 3920 or the condition ‘strophe-parsererror’.
function onConnectCallbackHandler(status, errorCond) {
	
	switch (status) {
		case Strophe.Status.CONNECTING:
			$("#xmpp-connection-status").text("Connecting to XMPP Server");
		break;
		
		case Strophe.Status.CONNFAIL:
			$("#xmpp-connection-status").text("Connection to XMPP server failed!");
		break;
			
		case Strophe.Status.AUTHENTICATING:
			$("#xmpp-connection-status").text("Authenticating to '" + domain + "'...");	
		break;
	
		case Strophe.Status.AUTHFAIL:
			$("#xmpp-connection-status").text("Authentication to '" + domain + "' failed!");
		break;
	
		case Strophe.Status.DISCONNECTING:
			$("xmpp-connection-status").text("Disconnecting from XMPP server.");	
		break;
	
		case Strophe.Status.DISCONNECTED:
			$("#xmpp-connection-status").text("Disconnected from XMPP Server");	
		break;
	
		case Strophe.Status.CONNECTED:
			
			// Jeee, finaly we are connected. We first change the status on the WEB page:
			$("#xmpp-connection-status").text("Connected and authenticated to '" + domain + "'");
			
			// We send empty presence to the XMPP server to say we are online and ready to receive stuff.
			connection.send($pres().tree());
			
			// Now we create a handler that will handle all the IQ's our XMPP Connection receives.
			// Please read more about addHandler -method of Strophe from here:
			// http://people.chesspark.com/~jack/strophe-preview/doc/files/strophe-js.html#Strophe.Connection.addHandler
			connection.addHandler(onIqCallbackHandler, 
                                  EVERY_NAMESPACE, 
                                  "iq", 
                                  EVERY_IQ_TYPE, 
                                  EVERY_IQ_WITH_ANY_ID, 
                                  FROM_ANY_SERNDER);
		break;
	
		case Strophe.Status.ERROR:
			$("xmpp-connection-status").text("Error, error error: '" + errorCond + "'");	
		break;
			
		default:
			$("xmpp-connection-status").text("O'ou, something happened that should not happen. Go to have beer, this will not work for some reason...");
		break;
	}              
}

// Function that will handle all the received IQ's our connection object to XMPP server
// receives.
function onIqCallbackHandler(iq) {
	
	log("Received IQ");
	
	/*
	 * In this example we are expecting to receive something like this.
	 * 
	 * <iq 	from="cdk.ws1.bmc.uu.se" 
	 * 	   	type="result" 
	 * 		to="tuomas@xmpp.lobstermonster.org/Psi" 
	 * 		id="JSO-0.12.5-6" >
	 * 		<command xmlns="http://jabber.org/protocol/commands" 
	 * 				 status="completed" 
	 * 				 node="calculateMass" 
	 * 				 sessionid="XWS-22" >
	 * 				 <iodata xmlns="urn:xmpp:tmp:io-data" 
	 * 				 type="output" >
	 * 				 	<out>
	 * 				 		<mass xmlns="urn:xws:cdk:input">36.032207690364004</mass>
	 * 				 	</out>
	 * 				 </iodata>
	 * 				 <note type="info">Done</note>
	 * 		</command>
	 * </iq>
	 */
	
	var command = iq.getElementsByTagNameNS("http://jabber.org/protocol/commands", "command");
	if(command.length > 0) {
		
		var cmd_status = command[0].getAttribute("status");
		var cmd_node = command[0].getAttribute("node");
		var cmd_sessionid = command[0].getAttribute("sessionid");
		
		log("We have command elements.");
		log("Command Status : '" + cmd_status + "'");
		log("Command Node   : '" + cmd_node + "'");
		log("Command SessionID : '" + cmd_sessionid + "'");
		
		var massReplies = command[0].getElementsByTagNameNS("urn:xws:cdk:input", "mass");
		var result = "";
		if(massReplies.length > 0) {
			result_mass = Strophe.getText(massReplies[0]);
			log("Mass: '" + result_mass + "'");
			result      = "RESULT:\n";
			result = result + "=======\n";
			result = result + "Status    : '" + cmd_status + "'\n";
			result = result + "Session ID: '" + cmd_sessionid + "'\n";
			result = result + "Node      : '" + cmd_node + "'\n";
			result = result + "Mass      : '" + result_mass + "'";
		} else {
			log("No luck getting the mass elements. But always look on the bright side of life, tydy, tydyttydyttydy.");
			result      = "RESULT:\n";
			result = result + "=======\n";
			result = result + "Received command reply but for some reason did not have mass -reply.\n";
			result = result + "Status    : '" + cmd_status + "'\n";
			result = result + "Session ID: '" + cmd_sessionid + "'\n";
			result = result + "Node      : '" + cmd_node + "'\n";
		}
		$("#results").val(result);
	} else {
		log("Bugger, no luck. No Command elements in this IQ :("); 
	}
	
	// If we return false, Strophe connection will remove this handler from the handler list.
	return true;
}
