/// class PD.Manage.Modules.Resources.History

PD.Manage.Modules.Resources.History =
Class.extend({

    //===================================
    // FIELDS
    //===================================

    _options: null,
    _history: null,
    _index: null,
    _suspendRecording: null,

    //===================================
    // CONSTRUCTOR
    //===================================

    init: function (options) {
        this._options = _.extend({}, options);
        this._history = [];
        this._index = -1;
        this._suspendRecording = false;
    },

    //===================================
    // PROPERTIES
    //===================================

    get_options: function (key) {
        if (key !== undefined) {
            return this._options[key];
        }
        return this._options;
    },

    //===================================
    // PUBLIC METHODS
    //===================================

    add: function (item) {

        var callback = this.get_options("add");

        if (this.allowAdd(item)) {

            this.trim();
            this.append(item);
            this._index += 1;

            if (_.isFunction(callback)) {
                callback({
                    type: "add",
                    index: this._index,
                    item: item,
                    items: this._history.slice(0),
                    canMovePrev: this.canMovePrev(),
                    canMoveNext: this.canMoveNext()
                });
            }

        }

        this._suspendRecording = false;

    },

    next: function () {

        var callback = this.get_options("move");

        if (this.canMoveNext()) {
            this._index += 1;
            this._suspendRecording = true; // do not add to the history when traversing the history
            if (_.isFunction(callback)) {
                callback({
                    type: "next",
                    index: this._index,
                    item: this._history[this._index],
                    items: this._history.slice(0),
                    canMovePrev: this.canMovePrev(),
                    canMoveNext: this.canMoveNext()
                });
            }
        }

    },

    prev: function () {

        var callback = this.get_options("move");

        if (this.canMovePrev()) {
            this._index -= 1;
            this._suspendRecording = true; // do not add to the history when traversing the history
            if (_.isFunction(callback)) {
                callback({
                    type: "prev",
                    index: this._index,
                    item: this._history[this._index],
                    items: this._history.slice(0),
                    canMovePrev: this.canMovePrev(),
                    canMoveNext: this.canMoveNext()
                });
            }
        }

    },

    trim: function () {

        var index = this._index,
            result = this._history;

        if (index > -1 && index < result.length - 1) {
            result = result.slice(0, index + 1);
        }

        this._history = result;

    },

    peek: function () {
        return this._history[this._index - 1];
    },

    canAdd: function (item) {

        var result = false,
            callback = this.get_options("canAdd");

        if (_.isFunction(callback)) {
            result = callback({
                add: item,
                index: this._index,
                peek: this.peek(),
                items: this._history.slice(0)
            });
        }
        else {
            result = _.last(this._history) !== item;
        }

        return result;
    },

    allowAdd: function (item) {
        return this._suspendRecording === false 
            && (this._index < 1 || this.canAdd(item))
    },

    canMovePrev: function () {
        return this._index > 0;
    },

    canMoveNext: function () {
        return this._index < this._history.length - 1;
    },

    append: function (item) {
        this._history[this._history.length] = item;
    }

});