/*

Siesta 5.1.0
Copyright(c) 2009-2018 Bryntum AB
https://bryntum.com/contact
https://bryntum.com/products/siesta/license

*/
Ext.define('Siesta.Recorder.UI.Model.Action', {
    extend      : 'Ext.data.TreeModel',

    fields      : Object.keys ? Object.keys(Siesta.Recorder.Action.meta.getAttributes().properties) : [],

    actionClass : Siesta.Recorder.Action,

    $action     : null,

    // initialized in the prototype (see below), shared by all instances
    formatStringHelper      : null,


    constructor : function (data) {
        if (!data.children && !('leaf' in data) && !data.root) data.leaf = true;

        // surprisingly the change in "data" variable will be reflected in "arguments"
        this.callParent([ data ]);

        if (data && !data.root) {
            var action      = data;

            if (!(action instanceof this.actionClass)) {
                action      = new this.actionClass(action)
            }

            this.$action    = action;

            Ext.applyIf(action, this.data);

            this.data       = action;
        }

    },


    getReadableStringWithModifierKeys : function (text, options) {
        options = options || {};

        var modifierKeys = '';
        var modifierRe   = /CTRL|CMD|SHIFT|ALT/;
        var ctrlKey      = options.ctrlKey,
            metaKey      = options.metaKey && Ext.isMac,
            shiftKey     = options.shiftKey,
            altKey       = options.altKey;

        if (altKey) {
            modifierKeys = '[ALT]';
        }

        if (ctrlKey) {
            modifierKeys = '[CTRL]';
        }

        if (metaKey) {
            modifierKeys += '[CMD]';
        }

        if (shiftKey) {
            modifierKeys += '[SHIFT]';
        }

        // Prepend modifier keys to all chars typed
        if (modifierKeys) {
            var keys            = this.formatStringHelper.extractKeysAndSpecialKeys(text);

            var prependedKeys   = keys.map(function (character) {
                // Don't prepend recorded special keys
                if (!modifierRe.test(character)) {
                    // should use single quotes
                    return "<span class='modifierkeys'>" + modifierKeys + '</span>' + Ext.String.htmlEncode(character);
                }

                return '';
            });

            text                = prependedKeys.join('');
        }

        return text;
    }
//    ,


//    setTargetByType : function (targetType, target) {
//        return this.$action.setTargetByType()
//    },


//    resetValues : function () {
//        this.$action.resetValues()
//
//        this.afterEdit([ 'targets', 'value', '__offset__' ])
//    },
//
//
//    clearTargetOffset : function () {
//        this.$action.clearTargetOffset()
//
//        this.afterEdit([ 'targets' ])
//    },
//
//
//    setTargetOffset : function (value) {
//        this.$action.setTargetOffset(value)
//
//        this.afterEdit([ '__offset__' ])
//    }


}, function () {
    var prototype   = this.prototype

    // anonymous class that consumes the "CanFormatStrings" role
    var cls         = Class({ does : Siesta.Util.Role.CanFormatStrings })

    // anonymous helper instance of anonymous class :)
    prototype.formatStringHelper = new cls()


    //var attributeNames  = [];
    //Siesta.Recorder.Action.meta.getAttributes().each(function(attr){ attributeNames.push(attr.name)});
    //
    //if (this.addFields) {
    //    this.addFields(attributeNames);
    //} else {
    //    var fields      = prototype.fields
    //    fields.addAll(attributeNames);
    //}

    Joose.A.each([
        'getTargetOffset', 'isMouseAction', 'parseOffset', 'getTarget', 'getTargets', 'hasTarget', 'asStep', 'asCode'
    ], function (methodName) {
        prototype[ methodName ] = function () {
            return this.$action[ methodName ].apply(this.$action, arguments)
        }
    })

    Joose.O.each({
        clearTargetOffset       : [ 'target' ],
        setTargetOffset         : [ 'target' ],
        resetValues             : [ 'target', 'value' ],
        setAction               : [ 'action', 'target' ]
    }, function (fields, methodName) {
        prototype[ methodName ] = function () {
            var res     = this.$action[ methodName ].apply(this.$action, arguments)

            // TODO not needed since we do refreshNode
            //this.afterEdit(fields)

            return res
        }
    })
});