text: /* ***** BEGIN LICENSE BLOCK *****
   * Distributed under the BSD license:
   *
   * Copyright (c) 2010, 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.
   *
   * ***** END LICENSE BLOCK ***** */
  
  define(function(require, exports, module) {
  "use strict";
  
  var Tokenizer = require("../tokenizer").Tokenizer;
  var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
  var Behaviour = require("./behaviour").Behaviour;
  var unicode = require("../unicode");
  
  var Mode = function() {
      this.$tokenizer = new Tokenizer(new TextHighlightRules().getRules());
      this.$behaviour = new Behaviour();
  };
  
  (function() {
  
      this.tokenRe = new RegExp("^["
          + unicode.packages.L
          + unicode.packages.Mn + unicode.packages.Mc
          + unicode.packages.Nd
          + unicode.packages.Pc + "\\$_]+", "g"
      );
      
      this.nonTokenRe = new RegExp("^(?:[^"
          + unicode.packages.L
          + unicode.packages.Mn + unicode.packages.Mc
          + unicode.packages.Nd
          + unicode.packages.Pc + "\\$_]|\s])+", "g"
      );
  
      this.getTokenizer = function() {
          return this.$tokenizer;
      };
  
      this.toggleCommentLines = function(state, doc, startRow, endRow) {
      };
  
      this.getNextLineIndent = function(state, line, tab) {
          return this.$getIndent(line);
      };
  
      this.checkOutdent = function(state, line, input) {
          return false;
      };
  
      this.autoOutdent = function(state, doc, row) {
      };
  
      this.$getIndent = function(line) {
          var match = line.match(/^(\s+)/);
          if (match) {
              return match[1];
          }
  
          return "";
      };
      
      this.createWorker = function(session) {
          return null;
      };
  
      this.createModeDelegates = function (mapping) {
          if (!this.$embeds) {
              return;
          }
          this.$modes = {};
          for (var i = 0; i < this.$embeds.length; i++) {
              if (mapping[this.$embeds[i]]) {
                  this.$modes[this.$embeds[i]] = new mapping[this.$embeds[i]]();
              }
          }
          
          var delegations = ['toggleCommentLines', 'getNextLineIndent', 'checkOutdent', 'autoOutdent', 'transformAction'];
  
          for (var i = 0; i < delegations.length; i++) {
              (function(scope) {
                var functionName = delegations[i];
                var defaultHandler = scope[functionName];
                scope[delegations[i]] = function() {
                    return this.$delegator(functionName, arguments, defaultHandler);
                }
              } (this));
          }
      }
      
      this.$delegator = function(method, args, defaultHandler) {
          var state = args[0];
          
          for (var i = 0; i < this.$embeds.length; i++) {
              if (!this.$modes[this.$embeds[i]]) continue;
              
              var split = state.split(this.$embeds[i]);
              if (!split[0] && split[1]) {
                  args[0] = split[1];
                  var mode = this.$modes[this.$embeds[i]];
                  return mode[method].apply(mode, args);
              }
          }
          var ret = defaultHandler.apply(this, args);
          return defaultHandler ? ret : undefined;
      };
      
      this.transformAction = function(state, action, editor, session, param) {
          if (this.$behaviour) {
              var behaviours = this.$behaviour.getBehaviours();
              for (var key in behaviours) {
                  if (behaviours[key][action]) {
                      var ret = behaviours[key][action].apply(this, arguments);
                      if (ret) {
                          return ret;
                      }
                  }
              }
          }
      }
      
  }).call(Mode.prototype);
  
  exports.Mode = Mode;
  });
  