/*

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

*/
Role('Siesta.Util.Role.CanFormatStrings', {

    has     : {
        serializeFormatingPlaceholders      : true
    },

    methods : {

        formatString: function (string, data) {
            if (!data) return string

            var match
            var variables           = []
            var isRaw               = []
            var regexp              = /\{(\!)?((?:\w|-|_)+?)\}/g

            while (match = regexp.exec(string)) {
                isRaw.push(match[ 1 ])
                variables.push(match[ 2 ])
            }

            var result              = string

            Joose.A.each(variables, function (variable, index) {
                var varIsRaw        = isRaw[ index ]

                result              = result.replace(
                    new RegExp('\\{' + (varIsRaw ? '!' : '') + variable + '\\}', 'g'),
                    data.hasOwnProperty(variable) ?
                        varIsRaw || !this.serializeFormatingPlaceholders ? data[ variable ] + '' : Siesta.Util.Serializer.stringify(data[ variable ])
                    :
                        ''
                )
            }, this)

            return result
        },


        // Extract normal chars, or special keys in brackets such as [TAB], [RIGHT] or [ENTER]
        extractKeysAndSpecialKeys : function (string) {
            var KeyCodes        = Siesta.Test.UserAgent.KeyCodes().keys
            var me              = this

            var res             = []
            // either: [[SPECIAL]] (meaning plain text), [SPECIAL] (meaning special char), or any character
            var tokens          = string.match(/(\[\[(?:\w|-){1,11}\]\])|(\[(?:\w|-){1,11}\])|([\s\S])/g) || [];

            Joose.A.each(tokens, function (token, index) {
                if (token.length > 1) {
                    var isDouble        = /\[\[/.test(token)

                    var specialKey      = token.substring(isDouble ? 2 : 1, token.length - (isDouble ? 2 : 1))
                    var normalText      = KeyCodes[ specialKey.toUpperCase() ] === undefined

                    if (normalText || isDouble) {
                        res.push('[')
                        if (normalText && isDouble) res.push('[')
                        res.push.apply(res, me.extractKeysAndSpecialKeys(specialKey))
                        res.push(']')
                        if (normalText && isDouble) res.push(']')
                    } else {
                        res.push(token)
                    }
                } else
                    res.push(token)
            })

            return res
        }
    }
})