// JavaScript Document
if( !edi ){	var edi = {}; }
if( !edi.util ){ edi.util = {}; }

edi.util.getChildByClass = function( elem, cname )
{
	var i=0;
	for(i=0; i<elem.childNodes.length; i++)
	{
		if( elem.childNodes[i].className == cname )
		{
			return elem.childNodes[i];
		}
	}
	return null;
}

edi.util.getChildrenByClass = function( elem, cname )
{
	var i=0;
	var es = new Array();
	for(i=0; i<elem.childNodes[i].length; i++)
	{
		if(className == cname ){
			es.push( elem.childNodes[i] );
		}
	}
	return es;
}

edi.util.Scope = function(parent)
{
	this._store = new Array();
	this._names = new Array();
	this._parent = parent;
}

edi.util.Scope.prototype.lookup = function( id )
{
	var i=0;
	for(i=0; i<this._names.length; i++)
	{
		if(this._names[i]==id)
		{
			return this._store[i];
		}
	}
	if( this._parent == null )
	{
		return null;
	}else
	{
		return this._parent.lookup(id);
	}
}

edi.util.Scope.prototype.contains = function( id )
{
	var i=0;
	for(i=0; i<this._names.length; i++)
	{
		if( this._names[i] == id )
		{
			return true;
		}
	}
	if( this._parent == null )
	{
		return false;
	}else
	{
		return this._parent.contains(id);
	}
}

// will replace if it already exists 
// warning: replacement is horribly inefficient
edi.util.Scope.prototype.add = function( id, value )
{
	if( !this.contains( id ) )
	{
		this._names.push( id );
		this._store.push( value );
	}else
	{
		var i=0;
		for(i=0; i<this._names.length; i++)
		{
			if( this._names[i] == id )
			{
				this._value[i] = value;
				return;
			}
		}
		if( this._parent != null )
		{
			this._parent.add( id, value );
		}
	}
}

// delegate sort of thing
// create one of these in your contructor
// other objects can use them to listen to what ur doin
// fname is the name of the function to be called upon each object
// javascript sucks--encode your message as a string if you have more than one param
edi.util.Delegate2 = function( fname )
{
	this._store = new Array();
	this._fname = fname;
}

edi.util.Delegate2.prototype.addListener = function( obj )
{
	this._store.push( obj );
}

edi.util.Delegate2.prototype.fire = function( s )
{
	var i=0;
	for( i=0; i<this._store.length; i++)
	{
		if( this._store[i][this._fname] )
		{
			var f = this._store[i][this._fname];
			f( this._store[i], s );
		}
	}
}

// simple mutex lock type thing. not really thread safe
edi.util.SimpleLock = function()
{
	this._locked = false;
}

edi.util.SimpleLock.prototype.obtain = function()
{
	if( this._locked ) { return false; }
	this._locked = true;
	return true;
}

edi.util.SimpleLock.prototype.release = function()
{
	this._locked = false;
}

edi.util.SimpleLock.prototype.isLocked = function()
{
	return this._locked;
}



/* You can use this callback manager to register callback functions in EDI cotrols 
 * This is a bit different then Nathan's delegate approach 
 * 
 * Author: Ali Goheer (mag97)
 * Created: May 26, 2009
 * Last Modified: May 26, 2009
 */

/* add an addFunction function to the 'function' prototype - that makes it available across all functions  */
Function.prototype.andThen=function(g, arg) {
	var f=this;
	return function() {
		f(arg);g(arg);
	}
};

/* this is to enable default argument values in javascript */
Function.prototype.defaults = function(){
	var _f = this;
	var _a = Array(_f.length-arguments.length).concat(Array.prototype.slice.apply(arguments));
	return function(){
		return _f.apply(_f, Array.prototype.slice.apply(arguments).concat(_a.slice(arguments.length, _a.length)));
	}
}


/* constructor for callback manager class */
function CallManager(){
	var This = this;
	var _Objects = Array(); 
	var _Functions = Array(); 
	var _argument; 
	this._callback=function (s) {}; // do nothing - end the callback cycle 
	
	this.getArgument = function(){
		return _argument; 
	}
	
	/* add another callback function - was trying a fancier version of callback, but it didn't quite work out 
	this.registerCallback_Old=function(callbackFunction) {
		alert(This._argument); 
		This._callback=(This._callback).andThen(callbackFunction, This._argument);
	}

	/* this function will call all the registered callback functions - was trying a fancier version of callback, 
		but didn't quite work out
	this.callback_Old = function(arg){
		This._argument = arg; 
		//alert(arg); 
		This._callback(); 
	}
	*/

	/* add another callback function */
	this.registerCallback=function(callbackFunction) {
		_Functions.push(callbackFunction); 
	}

	/* add another callback function */
	this.addListener=function(callbackFunction) {
		This.registerCallback(callbackFunction); 
	}	

	/* this function will call all the registered callback functions */
	this.callback = function(arg){
		for(i=0; i<_Functions.length; ++i){
			_Functions[i](arg); 
		}
	}


}

/* example usage of callback manager:
		var manager=new Manager();
		manager.registerCallback(sayHi.invoke);
		manager.registerCallback(sayBye.invoke);
		manager.callback(5);
*/

/* test code 
function Alerter(text) {
  this.text=text;
  var me=this;
  this.invoke=function (s) {
	  //s = 'meh'; 
    alert(me.text + '' + s);
  }
}

var sayHi=new Alerter('Hello, world!');
var sayBye=new Alerter('Goodbye, world!');

var manager=new CallManager();
manager.registerCallback(sayHi.invoke);
manager.registerCallback(sayBye.invoke);
manager.callback('blah');
*/