/*
	Workflow
	
	This object controls the sequencing of the other interface objects in the application. It provides
	a "next" & "prev" ability as well as ability to go directly to a step by name or number.
	
	The steps are numbered 1 .. n with next(1)->2 and prev(2)-> 1.  There is a special state 0 which
	can be used for initialization. next(0)->1, but prev(1)=null;
	
	Workflow can operation as a mediated object and responds to the trigger event. It does not have 
	an attach method because it is not associated with a container.
	
*/

function Workflow() {

	var state=new Array();
	var stateNames=new Array();
	var stateControllers = new Array();
	var stateElements = new Array();
	var curstate=0;

	Workflow.stateEnter=1;
	Workflow.stateExit=2;
	this.isVisible=true;		// this is needed to make a Workflow item work with the mediator
	
	this.trigger=trigger_;
	this.next=next_;
	this.prev=prev_;
	this.gotoState=gotoState_;
	this.setState=setState_;
	this.delay=delay_;
	this.colorMenu = colorMenu_;
	
	function next_() {
		if (curstate<state.length) {
			gotoState_(curstate+1);
		}
	}

	function prev_() {
		if (curstate>1) {
			gotoState_(curstate-1);
		}
	}		

	this.focusFirstElement = function() {
		if (stateControllers[curstate] != null) {
			stateControllers[curstate].focusFirstElement();
		}
	}
	
	function colorMenu_(className) {
		document.getElementById(stateElements[curstate]).className = className;
	}
	
	function gotoState_(newState, aControl) {
		//var inMenu=false;	//only change states if a string is passed as newState
		var inMenu=aControl != undefined;	//only change states if a string is passed as newState
		
		if (isNaN(newState)) {		// the state name was passed convert to number
			if (stateNames[newState] != undefined) {
				newState=stateNames[newState];
				//inMenu = true;	
			} else
				return;
		}			

		if (state[newState] != undefined ) {			// ignore stated change if target state doesn't exist
			/*
			 * This check allows you to go backwards to previous states
			 * Short circuiting was not working, thus the repeat in code
			 */
			if (newState > curstate) {
				if (stateControllers[curstate] == null || stateControllers[curstate].isValid()) {
					/*
					 * You have to check any states in the middle of a jump to see if they
					 * are valid before allowing them to move to a greater state than them
					 */
					if ((newState - curstate) > 1) {
						for (var tmpState = curstate + 1; tmpState < newState; tmpState++) {

							/* 
							 * Turn any menu option dark and move to that state.
							 * If it does not validate correctly it will stop there
							 * and it should be dark anyway.
							 */
							document.getElementById(stateElements[tmpState]).className = 'MenuDark';
							state[curstate](Workflow.stateExit);
							state[curstate=tmpState](Workflow.stateEnter);

							if (stateControllers[tmpState].isValid() == false) {
								return;
							}
						}
					}
										 
					/*
					 * This is counter intuitive
					 * Since the mouse out event reverse the color you want to set it light
					 * so it will reverse if clicking the menu.  Big shout out and thanks to 
					 * George for shedding light on this for me.  -REM
					 *
					 * newState == 5 is so the Preview menu will turn colors
					 */
					if (stateControllers[newState] != null || newState == 5) {
						document.getElementById(stateElements[newState]).className = inMenu?'MenuLight':'MenuDark';
					}

					state[curstate](Workflow.stateExit);
					state[curstate=newState](Workflow.stateEnter);
				} 
			} else {
				/*
				 * This is counter intuitive
				 * Since the mouse out event reverse the color you want to set it light
				 * so it will reverse if clicking the menu.  Big shout out and thanks to 
				 * George for shedding light on this for me.  -REM
				 */
				if (stateControllers[newState] != null) {
					document.getElementById(stateElements[newState]).className = inMenu?'MenuLight':'MenuDark';
				}

				state[curstate](Workflow.stateExit);
				state[curstate=newState](Workflow.stateEnter);
			}
		}
	}

	function delay_(gap) { /* gap is in millisecs */
		var then
		var now; 
		then=new Date().getTime();
		now=then;
		while((now-then)<gap) {
			now=new Date().getTime();
		}
	}

	function setState_(aName, aFunction, aController) {  // this currently doesn't check to see if state already set
		var aNumber = Workflow.numStates++;
		state[aNumber]=aFunction;
		stateNames[aName]=aNumber;
		stateElements[aNumber]=aName;
		stateControllers[aNumber]=aController || null;
		}
		
	this.mouseIn = function(aControl) {
		if (aControl.className == 'MenuLight') {
 			aControl.className = 'MenuDark';
 		} else {
 			aControl.className = 'MenuLight';
 		}
	}		
	
	this.mouseOut = function(aControl) {
 		if (aControl.className == 'MenuDark') {
 			aControl.className = 'MenuLight';
 		} else {
 			aControl.className = 'MenuDark';
 		}
	}

	function trigger_(aControl, anEvent) {
		var p=event.srcElement;
		do {
			if (p.id != "") {
				return this.gotoState(p.id);
			} else
				p=p.parentElement;
		} while (p != null)
	}
}

Workflow.numStates=0;