/**
 * Created by rockyl on 2019-01-31.
 */

import Vue from 'vue'

const showLog = true;

export default class History extends Vue{
	constructor(max = 200) {
		super();

		this.actions = {};
		this.history = [];
		this.position = -1;
		this.max = max;
	}

	regActions(name, forward, backward) {
		this.actions[name] = {
			forward,
			backward
		};
	}

	reset() {
		this.history.splice(0);
		this._setPosition(- 1, true);
	}

	_setPosition(v, reset=false){
		this.position = v;

		this.$emit('change', {canUndo: this.canUndo, canRedo: this.canRedo, position: v, reset})
	}

	done(action, ...input) {
		this.history.splice(this.position + 1);
		this.history.push({
			action,
			input,
		});
		if (this.history.length > this.max) {
			this.history.shift();
		} else {
			this._setPosition(this.history.length - 1);
		}

		if(showLog) console.log('done>', action, input);
	}

	undo() {
		if (this.canUndo) {
			const {action, input} = this.history[this.position];
			let {backward} = this.actions[action];
			backward(...input);

			this._setPosition(this.position - 1);

			if(showLog) console.log('undo>', action, input);
		}

		return this.canUndo;
	}

	redo() {
		if (this.canRedo) {
			this._setPosition(this.position + 1);

			let {action, input} = this.history[this.position];
			let {forward} = this.actions[action];
			forward(...input);

			if(showLog) console.log('redo>', action, input);
		}

		return this.canRedo;
	}

	get canUndo(){
		return this.position >= 0
	}

	get canRedo(){
		return this.position < this.history.length - 1
	}
}


