/// <reference path="leaf.ts"/>
namespace Leaf {
    export namespace CoreLogic {
        export function createDynamicValueConfigs(templateString: string): DynamicValueConfig[] {
            let templates: DynamicValueConfig[] = []
            let reg = /\{\{\s*!?([a-z]+(:[a-z]+)?)\s*\}\}/ig
            let match: RegExpMatchArray
            let lastIndex = 0
            let hasValue = false
            while (match = reg.exec(templateString)) {
                if (match.index > lastIndex) {
                    templates.push({
                        type: "raw",
                        content: templateString.slice(lastIndex, match.index)
                    })
                }
                let content: string = match[0].slice(2).slice(0, -2)
                if (!content) continue
                let [k, v] = content.split(":").map((item) => { return item.trim() })
                let reverse = false
                if (k[0] == "!") {
                    k = k.slice(1)
                    reverse = true
                }
                templates.push({
                    type: "value",
                    content: k,
                    value: v,
                    reverse: reverse
                })
                hasValue = true
                lastIndex = match.index + match[0].length
            }
            if (lastIndex < templateString.length) {
                templates.push({
                    type: "raw",
                    content: templateString.slice(lastIndex)
                })
            }
            return templates
        }
        export const MergablePropertyNames = ["class"]
        export function isPropertyMergable(name: string) {
            return MergablePropertyNames.indexOf(name) >= 0
        }
        export function mergeProperty(name: string, values: string[]): string {
            if (name === "class") {
                let names: string[] = []
                for (let value of values) {
                    let todos = value.split(" ").map(item => item.trim()).filter(item => !!item)
                    for (name of todos) {
                        if (names.indexOf(name) < 0) names.push(name)
                    }
                }
                return names.join(" ")
            } else {
                return values.join(" ")
            }
        }
        export const BubbleEvents = ["click", "mouseup", "mousedown", "mousemove", "mouseleave", "mouseenter", "mouseover", "keydown", "keyup", "keypress"].map((name) => {
            return { name, bubble: true }
        })
        export const UnbubbleEvents = [{
            name: "focus",
            bubble: false,
            target: ["input", "textarea"]
        }, {
            name: "blur",
            bubble: false,
            target: ["input", "textarea"]
        }, {
            name: "submit",
            bubble: false,
            target: ["form"]
        }, {
            name: "change",
            bubble: false,
            target: ["input", "textarea", "select"]
        }]
        export const AllEvents = BubbleEvents.concat(UnbubbleEvents)
        export function explainDynamicString(model: Model<any, any>, config: DynamicStringConfig): string {
            let result = []
            for (let item of config.templates) {
                result.push(explainDynamicValue(model, item))
            }
            return result.join("")
        }
        export function explainDynamicValue(model: Model<any, any>, config: DynamicValueConfig) {
            if (config.type === "raw") {
                return config.content
            } else {
                let mayReverse = (v) => {
                    if (config.reverse) return !v
                    return v
                }
                let vmValue = model.get(config.content)
                if (typeof vmValue === "function") {
                    vmValue = vmValue()
                }
                let value = config.value || null
                // for {{class}} value as true, use name as className
                if (mayReverse(vmValue) === true) {
                    if (value) {
                        return value
                    }
                    value = Leaf.Util.camelToSlug(config.content)
                    return value
                } else if (mayReverse(vmValue) === false) {
                    return ""
                }
                if (mayReverse(vmValue) && value) {
                    return value
                }
                return vmValue || ""
            }
        }
    }
}
