/***
/***
 * Wizard.js
 *
 * Author: 	Cory Mawhorter
 * Version:	1.0.3
 *
 *	Released by Ephective.  More information for this and other programs can be found at http://www.ephectiveinnovations.com/
 * 
 * =====
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var WZS_NORMAL 		= 1;
var WZS_DISPOSABLE 	= 2;
var WZS_CONDITIONAL 	= 3;
function Wizard() {
	this.activeStep=null;
	this.activeStepNum=-1;
	
	try {
		this.steps = new TreeCollection();
	}catch(err) {
		alert('Error\n\nCould not load TreeCollection.');
	}

	this.stepChanged = null;
}

Wizard.prototype.totalSteps 	= function() { return this.steps.nodes.length; };
Wizard.prototype.getStep 	= function(stepnum) { return this.steps.nodes[(stepnum-1)]; };

Wizard.prototype.addStep 		= function(name,obj,wzs_type) { 
	if(obj == null) return false;
	
	var tn = this.steps.addChild(new TreeNode(name,obj)); 
	tn.wzsType = wzs_type;
	
	switch(wzs_type) {
		case WZS_DISPOSABLE:
			tn.wzsDisposed = false;
			break;
		case WZS_CONDITIONAL:
			tn.wzsCondition = arguments[3];
			break;
		default: case WZS_NORMAL: break;
	}
	
	tn.StepNum = this.steps.nodes.length;
	return tn;
};

Wizard.prototype._getCurrentStepIndex = function() { for(var i in this.steps.nodes) if(this.steps.nodes[i].StepNum == this.activeStepNum) return parseInt(i); };

// future implementation... oooo n-tiered wizards with conditional step changing!
// Wizard.prototype.addChild 		= function(pid,name,obj) { this.steps.getNodeById(pid).addChild(new TreeNode(name,obj)); };

Wizard.prototype.InitializeStep	= function(tn) {  
	if (this.activeStep == tn) tn.data.style.display='block';
	else tn.data.style.display='none';
};

Wizard.prototype.Initialize		= function() {  
	if(this.activeStep == null) {
		this.activeStep = this.steps.nodes[0];
		this.activeStepNum = this.activeStep.StepNum;
		
		if(this.activeStep.wzsType == WZS_DISPOSABLE) this.activeStep.wzsDisposed = true;
	}

	for(var i in this.steps.nodes) this.InitializeStep(this.steps.nodes[i]);
};

Wizard.prototype.Refresh = function() { for(var i in this.steps.nodes) this.InitializeStep(this.steps.nodes[i]); };

Wizard.prototype.showStep 	= function(step) { 
	var func = step > this.activeStepNum ? 'Next' : 'Back';
	var ret;
	if(step==this.activeStepNum) { /* console.warn('Step already displayed'); */ return false; }
	while(this.activeStepNum != step && (ret = this[func](true)));
	this.stepChanged();
};

Wizard.prototype.Next 		= function(bFromShowStep) {
	if(this.activeStep == this.steps.nodes[this.steps.nodes.length-1]) return false;

	if(eval('(typeof '+this.activeStep.data.id+'_onexit == "function"); ')) if(false === eval(this.activeStep.data.id+'_onexit(true); ')) return false;
	this.activeStep.data.style.display='none';
	
	var stepContinue=true;
	var step_change=1;
	while(stepContinue) {
		var prevstep = this.activeStep;
		var tn = this.steps.nodes[(this._getCurrentStepIndex()+step_change)];
		if(typeof tn == 'undefined') return false;
		switch(tn.wzsType) {
			default:
			case WZS_NORMAL:
				this.activeStep = tn;
				this.activeStepNum = tn.StepNum;
				stepContinue=false;
				break;
			case WZS_DISPOSABLE:
				if(!tn.wzsDisposed) {
					this.activeStep = tn;
					this.activeStepNum = tn.StepNum;
					tn.wzsDisposed = true;
					stepContinue=false;
					break;
				}else {
					step_change++;
					break;
				}
			case WZS_CONDITIONAL:
				var val = (typeof tn.wzsCondition == 'function') ? tn.wzsCondition() : tn.wzsCondition;
				if(val) {
					this.activeStep = tn;
					this.activeStepNum = tn.StepNum;
					stepContinue=false;
					break;
				}else {
					step_change++;
					break;
				}
		}
	}
	
	prevstep.complete = true;
	
	if(eval('(typeof '+this.activeStep.data.id+'_onenter == "function"); ')) eval(this.activeStep.data.id+'_onenter(); ');
	this.activeStep.data.style.display='block';
	
	if(this.stepChanged != null && !bFromShowStep) this.stepChanged();
	return true;
};

Wizard.prototype.Back 	= function(bFromShowStep) {
	if(this.activeStep == this.steps.nodes[0]) return false;

	if(eval('(typeof '+this.activeStep.data.id+'_onexit == "function"); ')) if(false === eval(''+this.activeStep.data.id+'_onexit(); ')) return false;
	this.activeStep.data.style.display='none';
	
	var stepContinue=true;
	var step_change=1;
	while(stepContinue) {
		var tn = this.steps.nodes[(this._getCurrentStepIndex()-step_change)];
		if(typeof tn == 'undefined') return false;
		switch(tn.wzsType) {
			default:
			case WZS_NORMAL:
				this.activeStep = tn;
				this.activeStepNum = tn.StepNum;
				stepContinue=false;
				break;
			case WZS_DISPOSABLE:
				if(!tn.wzsDisposed) {
					this.activeStep = tn;
					this.activeStepNum = tn.StepNum;
					tn.wzsDisposed = true;
					stepContinue=false;
					break;
				}else {
					step_change++;
					break;
				}
			case WZS_CONDITIONAL:
				var val = (typeof tn.wzsCondition == 'function') ? tn.wzsCondition() : tn.wzsCondition;
				if(val) {
					this.activeStep = tn;
					this.activeStepNum = tn.StepNum;
					stepContinue=false;
					break;
				}else {
					step_change++;
					break;
				}
		}
	}

	if(eval('(typeof '+this.activeStep.data.id+'_onenter == "function"); ')) eval(''+this.activeStep.data.id+'_onenter(); ');
	this.activeStep.data.style.display='block';
	
	if(this.stepChanged != null && !bFromShowStep) this.stepChanged()
	return true;
};
