/*	Created: 01/03/2002, phaedrus											*/

function initYMObj(parentObject)
// create a YM object which stores parameters and methods for a parent object
{
	// parentObject	: the object who needs a YM object

	if (typeof(parentObject.YM) == 'undefined'){
		parentObject.YM = new YMObj(parentObject);
	}	
}	// end function initYMObj(parentObject)

function YMObj(parentObject)
// create a new YM Object
/* Public Methods:
 *
 *	getParentObj()
 *		get the YM object's parent object
 *
 *	set(propertyName,propertyValue)
 *		set a custom property for the YM object
 *		propertyName : the name of the property to set
 *		propertyValue : the value to set the property to
 *
 *	get(propertyName)
 *		get the value of custom property for the YM object
 *		propertyName : the name of the property to get the value of
 *
 *	addHandler(eventType,handlerFnct)
 *		add an event handler for the YM object.  any previously defined event
 *			handlers for the YM object or the parent object will be preserved. 
 *			eventType : the type of event to add a handler for
 *		handlerFnct : the function to run when the event fires.  this should
 *					be a string ending in a semicolon.
 *		NOTE: this function should be invoked AFTER any HTML references to the 
 *			parent object's event handler are made (eg: do not call this method
 *			for an body onload event in the document head and then set an onload
 *			in the body tag).  either later references or the creation of an
 *			init method should get around this issue with no trouble.
*/
{
	// parentObject	: the object tho whom the YM object will belong
	
	// private read only member variables
	var parentObj = null;
	setParentObj(parentObject);
	
	// public method pointers
	this.getParentObj = getParentObj;
	this.addHandler = YM_addHandler;
	this.set = setProperty;
	this.get = getProperty;
	
	// public methods
	function getParentObj() {
		return parentObj;
	}
	function setProperty(propertyName,propertyValue) {
		eval("this." + propertyName + "= propertyValue");
	}
	function getProperty(propertyName) {
		return eval("this." + propertyName);
	}
	
	// private methods
	function setParentObj(parameter) {
		parentObj = parameter;
	}	

	function YM_addHandler(eventType,handlerFnct)
	// add an event handling function to the YM object, creating and event
	// handling object if it does not already exist.
	{
		// eventType	: the type of event to be handled
		// handlerFnct	: the function to be executed when the event fires
		
		function YMEventHandler()
		// private function to create an event handling object.
		{
			// private member variables
			var evalString = "";	// string of commands to evaluate on event
			var prevFunctions = [];	// array of functions called via other means

			// public method pointers
			// defined below because one browser had trouble with it here.
			
			// public methods
			function getEvalString() {
				return evalString;
			}	
			function setPrevFunction(parameter) {
				if( !prevFunctions[0] ) {
					// define the first previous function
					prevFunctions[0] = (parameter) ? parameter :  new Function;
					return;
				} else if( !parameter ) {
					// other previous functions exist, but there's no parameter
					return;
				} else {
					// other previous functions exist, add the new one.
					prevFunctions[prevFunctions.length] = parameter;
					return;
				}
			}	
			function addHandler(parameter) {
				evalString +=  parameter;
			}
			function handleEvent() {
				for (var lcv=0;lcv<prevFunctions.length;lcv++) {
					prevFunctions[lcv]();
				}
				eval(getEvalString());
			}
			
			// public method pointers
			this.getEvalString = getEvalString;
			this.setPrevFunction = setPrevFunction;
			this.addHandler = addHandler;
			this.handleEvent = handleEvent;
			
		}	// end function YMEventHandler()
		
		// make sure we're always working in the same case.
		var strEventType = eventType.toLowerCase();
		// create a temp variable for this event handler
		var theEventHandler = eval("this." + strEventType);
		// create a temp variable for the current browser event handler
		var browserEventHandler = eval("this.getParentObj()." + strEventType);
		
		// if the event handler object does not exist, create it.
		if( typeof(theEventHandler) == 'undefined' )
		{
			theEventHandler = new YMEventHandler();
		}
		
		// if the YM event handler isn't being used, this is either the first time
		// it has been requested, or it has been "stolen" by another routine.  in
		// either case, we should preserve the previous functions and use this one
		if( browserEventHandler != theEventHandler.handleEvent )
		{
			theEventHandler.setPrevFunction(browserEventHandler);
			eval("this.getParentObj()."
					+ strEventType + "= theEventHandler.handleEvent");
		}
	
		// add the handler function to the event handler
		theEventHandler.addHandler(handlerFnct);
		
		// swap the handler object for the temp variable
		eval("this." + strEventType + " = theEventHandler");
	}	// end function YM_addHandler()
}	// end function YMObj()
