/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2012, Ajax.org B.V.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * Contributor(s):
 * 
 * Garen J. Torikian <gjtorikian @ gmail DOT com>
 *
 * ***** END LICENSE BLOCK ***** */

/*
 THIS FILE WAS AUTOGENERATED BY mode_highlight_rules.tmpl.js (UUID: C5B73B98-5F2A-42E3-9F0E-028A74A9FE4B)
 */

define(function (require, exports, module) {
    "use strict";

    var oop = require("../lib/oop");
    var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
    var MarkdownHighlightRules = require("./markdown_highlight_rules").MarkdownHighlightRules;
    var SassHighlightRules = require("./scss_highlight_rules").ScssHighlightRules;
    var LessHighlightRules = require("./less_highlight_rules").LessHighlightRules;
    var CoffeeHighlightRules = require("./coffee_highlight_rules").CoffeeHighlightRules;
    var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules;

    function mixin_embed(tag, prefix) {
        return {
            token: "entity.name.function.jade",
            regex: "^\\s*\\:" + tag,
            next: prefix + "start"
        };
    }

    var JadeHighlightRules = function () {

        var escapedRe = "\\\\(?:x[0-9a-fA-F]{2}|" + // hex
            "u[0-9a-fA-F]{4}|" + // unicode
            "[0-2][0-7]{0,2}|" + // oct
            "3[0-6][0-7]?|" + // oct
            "37[0-7]?|" + // oct
            "[4-7][0-7]?|" + //oct
            ".)";

        // regexp must not have capturing parentheses. Use (?:) instead.
        // regexps are ordered -> the first match is used

        this.$rules =
            {
                "start": [
                    {
                        token: "keyword.control.import.include.jade",
                        regex: "\\s*\\binclude\\b"
                    },
                    {
                        token: "keyword.other.doctype.jade",
                        regex: "^!!!\\s*(?:[a-zA-Z0-9-_]+)?"
                    },
                    {
                        onMatch: function (value, currentState, stack) {
                            stack.unshift(this.next, value.length - 2, currentState);
                            return "comment";
                        },
                        regex: /^\s*\/\//,
                        next: "comment_block"
                    },
                    mixin_embed("markdown", "markdown-"),
                    mixin_embed("sass", "sass-"),
                    mixin_embed("less", "less-"),
                    mixin_embed("coffee", "coffee-"),
                    /*
                     {
                     token: {
                     "2": {
                     "name": "entity.name.function.jade"
                     }
                     },
                     regex: "^(\\s*)(\\:cdata)",
                     next: "state_9"
                     },*/
                    // match stuff like: mixin dialog-title-desc(title, desc)
                    {
                        token: ["storage.type.function.jade",
                            "entity.name.function.jade",
                            "punctuation.definition.parameters.begin.jade",
                            "variable.parameter.function.jade",
                            "punctuation.definition.parameters.end.jade"
                        ],
                        regex: "^(\\s*mixin)( [\\w\\-]+)(\\s*\\()(.*?)(\\))"
                    },
                    // match stuff like: mixin dialog-title-desc
                    {
                        token: ["storage.type.function.jade", "entity.name.function.jade"],
                        regex: "^(\\s*mixin)( [\\w\\-]+)"
                    },
                    {
                        token: "source.js.embedded.jade",
                        regex: "^\\s*(?:-|=|!=)",
                        next: "js-start"
                    },
                    /*{
                     token: "entity.name.tag.script.jade",
                     regex: "^\\s*script",
                     next: "js_code_tag"
                     },*/
                    {
                        token: "string.interpolated.jade",
                        regex: "[#!]\\{[^\\}]+\\}"
                    },
                    // Match any tag, id or class. skip AST filters
                    {
                        token: "meta.tag.any.jade",
                        regex: /^\s*(?!\w+:)(?:[\w-]+|(?=\.|#)])/,
                        next: "tag_single"
                    },
                    {
                        token: "suport.type.attribute.id.jade",
                        regex: "#\\w+"
                    },
                    {
                        token: "suport.type.attribute.class.jade",
                        regex: "\\.\\w+"
                    },
                    {
                        token: "punctuation",
                        regex: "\\s*(?:\\()",
                        next: "tag_attributes"
                    }
                ],
                "comment_block": [
                    {
                        regex: /^\s*(?:\/\/)?/, onMatch: function (value, currentState, stack) {
                        if (value.length <= stack[1]) {
                            if (value.slice(-1) == "/") {
                                stack[1] = value.length - 2;
                                this.next = "";
                                return "comment";
                            }
                            stack.shift();
                            stack.shift();
                            this.next = stack.shift();
                            return "text";
                        } else {
                            this.next = "";
                            return "comment";
                        }
                    }, next: "start"
                    },
                    {defaultToken: "comment"}
                ],
                /*

                 "state_9": [
                 {
                 token: "TODO",
                 regex: "^(?!\\1\\s+)",
                 next: "start"
                 },
                 {
                 token: "TODO",
                 regex: ".+",
                 next: "state_9"
                 }
                 ],*/
                /*"js_code": [
                 {
                 token: "keyword.control.js",
                 regex: "\\beach\\b"
                 },
                 {
                 token: "text",
                 regex: "$",
                 next: "start"
                 }
                 ],*/
                /*"js_code_tag": [
                 {
                 "include": "source.js"
                 },
                 {
                 token: "TODO",
                 regex: "^((?=(\\1)([\\w#\\.]|$\\n?))|^$\\n?)",
                 next: "start"
                 }
                 ],*/
                "tag_single": [
                    {
                        token: "entity.other.attribute-name.class.jade",
                        regex: "\\.[\\w-]+"
                    },
                    {
                        token: "entity.other.attribute-name.id.jade",
                        regex: "#[\\w-]+"
                    },
                    {
                        token: ["text", "punctuation"],
                        regex: "($)|((?!\\.|#|=|-))",
                        next: "start"
                    }
                ],
                "tag_attributes": [
                    {
                        token: "string",
                        regex: "'(?=.)",
                        next: "qstring"
                    },
                    {
                        token: "string",
                        regex: '"(?=.)',
                        next: "qqstring"
                    },
                    {
                        token: ["entity.other.attribute-name.jade", "punctuation"],
                        regex: "([a-zA-Z:\\.-]+)(=)?",
                        next: "attribute_strings"
                    },
                    {
                        token: "punctuation",
                        regex: "\\)",
                        next: "start"
                    }
                ],
                "attribute_strings": [
                    {
                        token: "string",
                        regex: "'(?=.)",
                        next: "qstring"
                    },
                    {
                        token: "string",
                        regex: '"(?=.)',
                        next: "qqstring"
                    },
                    {
                        token: "string",
                        regex: '(?=\\S)',
                        next: "tag_attributes"
                    }
                ],
                "qqstring": [
                    {
                        token: "constant.language.escape",
                        regex: escapedRe
                    }, {
                        token: "string",
                        regex: '[^"\\\\]+'
                    }, {
                        token: "string",
                        regex: "\\\\$",
                        next: "qqstring"
                    }, {
                        token: "string",
                        regex: '"|$',
                        next: "tag_attributes"
                    }
                ],
                "qstring": [
                    {
                        token: "constant.language.escape",
                        regex: escapedRe
                    }, {
                        token: "string",
                        regex: "[^'\\\\]+"
                    }, {
                        token: "string",
                        regex: "\\\\$",
                        next: "qstring"
                    }, {
                        token: "string",
                        regex: "'|$",
                        next: "tag_attributes"
                    }
                ]
            };

        this.embedRules(JavaScriptHighlightRules, "js-", [{
            token: "text",
            regex: ".$",
            next: "start"
        }]);
        /*
         this.embedRules(MarkdownHighlightRules, "markdown-", [{
         token : "support.function",
         regex : "^\\1\\s+",
         captures: "1",
         next  : "start"
         }]);

         this.embedRules(SassHighlightRules, "sass-", [{
         token : "support.function",
         regex : "^(?!\\1\\s+)",
         captures: "1",
         next  : "start"
         }]);

         this.embedRules(LessHighlightRules, "less-", [{
         token : "support.function",
         regex : "^(?!\\1\\s+)",
         captures: "1",
         next  : "start"
         }]);

         this.embedRules(CoffeeHighlightRules, "coffee-", [{
         token : "support.function",
         regex : "^(?!\\1\\s+)",
         captures: "1",
         next  : "start"
         }]);

         this.embedRules(JavaScriptHighlightRules, "js-", [{
         token : "support.function",
         regex : "$",
         captures: "1",
         next  : "start"
         }]); */
    };

    oop.inherits(JadeHighlightRules, TextHighlightRules);

    exports.JadeHighlightRules = JadeHighlightRules;
});
