
// WebBrick Javascript API version 1.0
// Amnon Silverstein, Feb 2001
// Code works for IE and Netscape
// Requires WebBrick 2.3 or greater

// This code is very full featured, and it is probably more than you need for your
// application.


///////////////////////////////
//////   Variables
//////

/// Setup variables 
		              // PUT YOUR URL HERE
	var WebBrickURL="http://YOUR URL HERE:7070/";
	var Attempts  = 10; // Number of attempts to reach the WebBrick server
	var TryFor_msec = 100; // msec per wait for reply

/// Global variables
	var DataImage = new Image();
	var Timeout=0;
	var Sensor=0;
	Queue_Tasks=new Array(); 
	Queue_Active=0;
	AlphaCodes="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	sensor_types= new
		Array(
			"None",
			"Touch",
			"Temperature",
			"Light",
			"Rotation"
		);

	sensor_modes = new
		Array(
			"Raw",
			"Boolean",
			"Transition Counter",
			"Period Counter",
			"Percent",
			"Celsius",
			"Fahrenheit",
			"Angle Steps"
		);

///////////////////////////////////
///// WebBrick Helper Functions 
///// You probably want to keep these.

	function GetNumber(){
		return ((DataImage.width-1)+(DataImage.height-1)*256*256);
	}

	function TryReading(OnReading,OnFailure){
		Timeout++;
		if (Timeout>Attempts){
			Timeout=0;
			eval(OnFailure);
			ClearQueue(); // Cleans out the queue until the problem can be solved
		}
		else if (DataImage.complete){
			Reading=GetNumber();
			Timeout=0;
		        eval(OnReading);
			Queue();  // Runs the next task in the queue
		}
		else	window.setTimeout("TryReading("+Freeze(OnReading)+","+Freeze(OnFailure)+")",TryFor_msec);	
	}	

	function AlertFailure(){
		// This code runs when the reading fails, by default
		// You can increase the number of connect attempts if you like.
		alert("WebBrick not responding, or maybe the network is clogged.");
	}

	function Freeze(task){
		// Inverse of Eval
		// eval(Freeze(foo)) => foo
		// Converts a task into a string that can later be evaled
		// replace every " with \"
		// replace every \ with \\
		quote = '"';
		slash = '\\';
		i=0;
		while (i<task.length){
			if (task.charAt(i)==quote || task.charAt(i)==slash){				
				head=task.substring(0,i);
				tail=task.substring(i,task.length);
				task=head+slash+tail;
				i++;
			}
			i++;
		}
		return (quote+task+quote);
	}


///////////////////////////////////
///// Main WebBrick Functions 
///// It is usually better to call these with the queued versions instead of directly

	function Execute(RCXprogram,RCXtask,OnExecuted,OnFailure){
		delete DataImage;
 		DataImage = new Image();
		DataImage.src = WebBrickURL+"X"+RCXprogram+RCXtask+Math.random();		
		window.setTimeout("TryReading("+Freeze(OnExecuted)+","+Freeze(OnFailure)+")",1000);
	}
	function Set(RCXvar,RCXval,OnSet,OnFailure){
		delete DataImage;
 		DataImage = new Image();
		code=AlphaCodes.charAt(RCXvar);
		DataImage.src = WebBrickURL+"S"+code+RCXval+ "0."+Math.random();
		window.setTimeout("TryReading("+Freeze(OnSet)+","+Freeze(OnFailure)+")",1000);
	}
	function Poll(PollSource,PollNumber,OnReading,OnFailure){
		code = AlphaCodes.charAt(PollSource)+AlphaCodes.charAt(PollNumber);
		delete DataImage;
 		DataImage = new Image();
		DataImage.src=WebBrickURL+"P"+code+Math.random();
		task="TryReading("+Freeze(OnReading)+","+Freeze(OnFailure)+")";
		window.setTimeout(task,1000);
	}		

//////////////////////////////////////
/////// Task Queue

	function Queue(task){
		// Stacks up tasks on a todo list, and executes them as fast as your robot
		// can acknowledge them.
		if (!Queue_Active && task){
			Queue_Active=1;
			eval(task)
		}
		else if (task){
			Queue_Tasks[Queue_Tasks.length]=task;
		}
		else if (Queue_Tasks.length==0)
			Queue_Active=0;
		else{
		 	next_task=Queue_Tasks[0];
			Queue_Tasks.reverse();  
			Queue_Tasks.length--;
			Queue_Tasks.reverse();
			eval(next_task);
		}				
	}
	function ClearQueue(){
		// Clears out all queued tasks.
		Queue_Tasks.length=0;
		Queue_Active=0;
	}
	function DontQueue(task){
		// Runs the task only if not currently busy. 
		// If your user is mashing buttons too fast, 
		// you might want this to toss out commands until the last command finishes.
		if (!Queue_Active)
			Queue(task);
	}
	function OverrideQueue(task){
		// This is for stuff that you want to run immediately,
		// and to override all previous commands.
		// Useful for Halt All, for example.
		ClearQueue();
		eval(task);
	}

////////////////////////////////////////////////////
////  Functions you probably want to use in your code
////  These functions deal with the queue for you

	function ExecuteNow(RCXprogram,RCXtask){
		// Simplified Execute command
		// Forgets what it was doing before and starts this new task.
		// Do not use this if you want your robot to do several things
		// in sequence with one button press.
		OverrideQueue("Execute("+RCXprogram+","+RCXtask+","+Freeze("")+","+Freeze("AlertFailure()")+")");
	}
	function DoExecute(RCXprogram,RCXtask){
		// Simplified Execute command
		// Puts the command in the queue, and executes it in turn.
		Queue("Execute("+RCXprogram+","+RCXtask+","+Freeze("")+","+Freeze("AlertFailure()")+")");
	}
	function DoSet(RCXvar,RCXval){
		// Puts the set instruction in the queue, and executes it in turn.
		Queue("Set("+RCXvar+","+RCXval+","+Freeze("")+","+Freeze("AlertFailure()")+")");
	}

	function DoPoll(PollSource,PollNumber,OnReading){
		task="Poll("+PollSource+","+PollNumber+","+Freeze(OnReading)+","+Freeze("AlertFailure()")+")";
		Queue(task);
	}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// END OF API

