require('./style.scss');
var Component = require('vn/component');
var Step = require('../step');
var Toast = require('../toast');

/**
 * A simple assistant with steps.
 */
module.exports = new Class({
	Extends: Component,
	Tag: 'htk-assistant',
	Properties: {
		/**
		 * The current step index.
		 */
		step: {
			type: Number,
			set(x) {
				this.setStep(x);
			},
			get() {
				return this._stepIndex;
			}
		},
		/**
		 * The current step name.
		 */
		stepName: {
			type: String,
			set(x) {
				this.setStepByName(x);
			},
			get() {
				return this._stepName;
			}
		},
		/**
		 * The steps index.
		 */
		stepsIndex: {
			type: Array,
			set(x) {
				this._stepsIndex = x;
				this.setStep(this._stepIndex);
				this.emit('steps-change');
			},
			get() {
				return this._stepsIndex;
			}
		},
		/**
		 * The total number of steps in the assistant.
		 */
		stepCount: {
			type: Number,
			get() {
				if (this._stepsIndex)
					return this._stepsIndex.length;
				return 0;
			}
		},
		/**
		 * Function to call on every step change.
		 */
		stepFunc: {
			type: Function,
			value: null
		},
		/**
		 * Function to call on every step change.
		 */
		endFunc: {
			type: Function,
			value: null
		},
	},

	_stepNode: null,
	_stepIndex: 0,
	_stepName: null,
	steps: {},

	initialize(props) {
		Component.prototype.initialize.call(this, props);
		this.createRoot('div');
	},

	appendChild(step) {
		if (!(step instanceof Step))
			throw new Error('Invalid child for assistant');

		this.node.appendChild(step.node);
		this.steps[step.name] = step;
	},

	setStepByName(stepName) {
		if (this._stepsIndex)
			this.setStep(this._stepsIndex.indexOf(stepName));
	},

	setStep(stepIndex) {
		if ((this.currentStep && stepIndex == this._stepIndex)
		|| !this._stepsIndex
		|| !(stepIndex >= -1 && stepIndex < this._stepsIndex.length))
			return;

		if (stepIndex > this._stepIndex) {
			var validateIni = Math.max(this._stepIndex, 0);

			try {
				for (var i = validateIni; i < stepIndex; i++) {
					var validateName = this._stepsIndex[i];
					var validateStep = this.steps[validateName];
					validateStep.validate();
				}
			} catch(e) {
				Toast.showError(e.message);
				if (i == this._stepIndex) return;
				stepIndex = i;
			}
		}

		var stepName = this._stepsIndex[stepIndex];
		var step = this.steps[stepName];
		var currentStep = this.currentStep;

		if (currentStep)
			currentStep.hide();

		this._stepIndex = stepIndex;
		this._stepName = stepName;
		this.currentStep = step;
		step.show();
		this.emit('step-change', stepIndex);
		
		if (this.stepFunc)
			this.stepFunc(step);
	},

	/**
	 * Moves the assistant to the previous step.
	 */
	movePrevious() {
		this.setStep(this._stepIndex - 1);
	},
	
	/**
	 * Moves the assistant to the next step.
	 */
	moveNext() {
		this.setStep(this._stepIndex + 1);
	},

	/**
	 * Ends the assistant. If defined, the stepFunc will be called.
	 */
	end() {
		if (this.endFunc)
			this.endFunc();
	}
});
