// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

class CGBlock {
  int _blockType;             // Code type of this block
  int _indent;                // Number of spaces to prefix for each statement
  bool _inEach;               // This block or any currently active blocks is a
                              // #each.  If so then any element marked with a
                              // var attribute is repeated therefore the var
                              // is a List type instead of an Element type.
  String _localName;          // optional local name for #each or #with
  List<CGStatement> _stmts;
  int localIndex;             // Local variable index (e.g., e0, e1, etc.)

  // Block Types:
  static const int CONSTRUCTOR = 0;
  static const int EACH = 1;
  static const int WITH = 2;

  CGBlock([this._indent = 4,
           this._blockType = CGBlock.CONSTRUCTOR,
           this._inEach = false,
           this._localName = null]) :
      _stmts = new List<CGStatement>(), localIndex = 0 {
    assert(_blockType >= CGBlock.CONSTRUCTOR && _blockType <= CGBlock.WITH);
  }

  bool get anyStatements => !_stmts.isEmpty();
  bool get isConstructor => _blockType == CGBlock.CONSTRUCTOR;
  bool get isEach => _blockType == CGBlock.EACH;
  bool get isWith => _blockType == CGBlock.WITH;

  bool get hasLocalName => _localName != null;
  String get localName => _localName;

  CGStatement push(var elem, var parentName, [bool exact = false]) {
    var varName;
    if (elem is TemplateElement && elem.hasVar) {
      varName = elem.varName;
    } else {
      varName = localIndex++;
    }

    CGStatement stmt = new CGStatement(elem, _indent, parentName, varName,
        exact, _inEach);
    _stmts.add(stmt);

    return stmt;
  }

  void pop() {
    _stmts.removeLast();
  }

  void add(String value) {
    if (_stmts.last() != null) {
      _stmts.last().add(value);
    }
  }

  CGStatement get last => _stmts.length > 0 ? _stmts.last() : null;

  /**
   * Returns mixed list of elements marked with the var attribute.  If the
   * element is inside of a #each the name exposed is:
   *
   *      List varName;
   *
   * otherwise it's:
   *
   *      var varName;
   *
   * TODO(terry): For scalars var varName should be Element tag type e.g.,
   *
   *                   DivElement varName;
   */
  String get globalDeclarations {
    StringBuffer buff = new StringBuffer();
    for (final CGStatement stmt in _stmts) {
      buff.add(stmt.globalDeclaration());
    }

    return buff.toString();
  }

  /**
   * List of statement constructors for each var inside a #each.
   *
   *    ${#each products}
   *      <div var=myVar>...</div>
   *    ${/each}
   *
   * returns:
   *
   *    myVar = [];
   */
  String get globalInitializers {
    StringBuffer buff = new StringBuffer();
    for (final CGStatement stmt in _stmts) {
      buff.add(stmt.globalInitializers());
    }

    return buff.toString();
  }

  String get codeBody {
    StringBuffer buff = new StringBuffer();

    for (final CGStatement stmt in _stmts) {
      buff.add(stmt.emitDartStatement());
    }

    return buff.toString();
  }
}

class CGStatement {
  bool _exact;                  // If True not HTML construct instead exact stmt
  bool _repeating;              // Stmt in a #each this block or nested block.
  StringBuffer _buff;
  var _elem;
  int _indent;
  var parentName;
  String varName;
  bool _globalVariable;
  bool _closed;

  CGStatement(this._elem, this._indent, this.parentName, var varNameOrIndex,
      [this._exact = false, this._repeating = false]) :
        _buff = new StringBuffer(), _closed = false {

    if (varNameOrIndex is String) {
      // We have the global variable name
      varName = varNameOrIndex;
      _globalVariable = true;
    } else {
      // local index generate local variable name.
      varName = "e${varNameOrIndex}";
      _globalVariable = false;
    }
  }

  bool get hasGlobalVariable => _globalVariable;
  String get variableName => varName;

  String globalDeclaration() {
    if (hasGlobalVariable) {
      String spaces = Codegen.spaces(_indent);
      return (_repeating) ?
        "  List ${varName};    // Repeated elements.\n" : "  var ${varName};\n";
    }

    return "";
  }

  String globalInitializers() {
    if (hasGlobalVariable && _repeating) {
      return "    ${varName} = [];\n";
    }

    return "";
  }

  void add(String value) {
    _buff.add(value);
  }

  bool get isClosed => _closed;

  void close() {
    if (_elem is TemplateElement && _elem.scoped) {
      add("</${_elem.tagName}>");
    }
    _closed = true;
  }

  String emitDartStatement() {
    StringBuffer statement = new StringBuffer();

    String spaces = Codegen.spaces(_indent);

    if (_exact) {
      statement.add("${spaces}${_buff.toString()};\n");
    } else {
      String localVar = "";
      String tmpRepeat;
      if (hasGlobalVariable) {
        if (_repeating) {
          tmpRepeat = "tmp_${varName}";
          localVar = "var ";
        }
      } else {
        localVar = "var ";
      }

      /* Emiting the following code fragment where varName is the attribute
         value for var=

            varName = new Element.html('HTML GOES HERE');
            parent.elements.add(varName);

         for repeating elements in a #each:

            var tmp_nnn = new Element.html('HTML GOES HERE');
            varName.add(tmp_nnn);
            parent.elements.add(tmp_nnn);

         for elements w/o var attribute set:

            var eNNN = new Element.html('HTML GOES HERE');
            parent.elements.add(eNNN);
       */
      if (_elem is TemplateCall) {
        // Call template NameEntry2
        String cls = _elem.toCall;
        String params = _elem.params;
        statement.add("\n${spaces}// Call template ${cls}.\n");
        statement.add(
            "${spaces}${localVar}${varName} = new ${cls}${params};\n");
        statement.add(
            "${spaces}${parentName}.elements.add(${varName}.root);\n");
      } else {
        bool isTextNode = _elem is TemplateText;
        String createType = isTextNode ? "Text" : "Element.html";
        if (tmpRepeat == null) {
          statement.add("${spaces}${localVar}${varName} = new ${createType}('");
        } else {
          statement.add(
              "${spaces}${localVar}${tmpRepeat} = new ${createType}('");
        }
        statement.add(isTextNode ? _buff.toString().trim() : _buff.toString());

        if (tmpRepeat == null) {
          statement.add(
            "');\n${spaces}${parentName}.elements.add(${varName});\n");
        } else {
          statement.add(
            "');\n${spaces}${parentName}.elements.add(${tmpRepeat});\n");
          statement.add("${spaces}${varName}.add(${tmpRepeat});\n");
        }
      }
    }

    return statement.toString();
  }
}

class Codegen {
  static const String SPACES = "                                              ";
  static String spaces(int numSpaces) {
    return SPACES.substring(0, numSpaces);
  }

  // TODO(terry): Before generating Dart class need a validate phase that
  //              checks mangles all class names to be prefix with the
  //              template name to avoid any class name collisions.  Also,
  //              investigate possible runtime check mode to insure that only
  //              valid CSS class names are used (in case someone uses strings
  //              and not the generated getters to the CSS class selector.  This
  //              mode would be slower would require that every class name set
  //              (maybe jQuery too) is for a particular view (requires walking
  //              the HTML tree looking for a parent template prefix that
  //              matches the CSS prefix. (more thinking needed).
  static String generate(List<Template> templates, String filename) {
    List<String> fileParts = filename.split('.');
    assert(fileParts.length == 2);
    filename = fileParts[0];

    StringBuffer buff = new StringBuffer();
    int injectId = 0;         // Inject function id

    buff.add("// Generated Dart class from HTML template.\n");
    buff.add("// DO NOT EDIT.\n\n");

    String addStylesheetFuncName = "add_${filename}_templatesStyles";

    for (final template in templates) {
      // Emit the template class.
      TemplateSignature sig = template.signature;
      buff.add(_emitClass(sig.name, sig.params, template.content,
        addStylesheetFuncName));
    }

    // TODO(terry): Stylesheet aggregator should not be global needs to be
    //              bound to this template file not global to the app.

    // Emit the stylesheet aggregator.
    buff.add("\n\n// Inject all templates stylesheet once into the head.\n");
    buff.add("bool ${filename}_stylesheet_added = false;\n");
    buff.add("void ${addStylesheetFuncName}() {\n");
    buff.add("  if (!${filename}_stylesheet_added) {\n");
    buff.add("    StringBuffer styles = new StringBuffer();\n\n");

    buff.add("    // All templates stylesheet.\n");

    for (final template in templates) {
      TemplateSignature sig = template.signature;
      buff.add("    styles.add(${sig.name}.stylesheet);\n");
    }

    buff.add("\n    ${filename}_stylesheet_added = true;\n");

    buff.add("    document.head.elements.add(new Element.html('<style>"
             "\${styles.toString()}</style>'));\n");
    buff.add("  }\n");
    buff.add("}\n");

    return buff.toString();
  }

  static String _emitCSSSelectors(css.Stylesheet stylesheet) {
    if (stylesheet == null) {
      return "";
    }

    List<String> classes = [];

    for (final production in stylesheet.topLevels) {
      if (production is css.IncludeDirective) {
        for (final topLevel in production.styleSheet.topLevels) {
          if (topLevel is css.RuleSet) {
            classes = css.Generate.computeClassSelectors(topLevel, classes);
          }
        }
      } else if (production is css.RuleSet) {
        classes = css.Generate.computeClassSelectors(production, classes);
      }
    }

    List<String> dartNames = [];

    for (final String knownClass in classes) {
      StringBuffer dartName = new StringBuffer();
      List<String> splits = knownClass.split('-');
      if (splits.length > 0) {
        dartName.add(splits[0]);
        for (int idx = 1; idx < splits.length; idx++) {
          String part = splits[idx];
          // Character between 'a'..'z' mapped to 'A'..'Z'
          dartName.add("${part[0].toUpperCase()}${part.substring(1)}");
        }
        dartNames.add(dartName.toString());
      }
    }

    StringBuffer buff = new StringBuffer();
    if (classes.length > 0) {
      assert(classes.length == dartNames.length);
      buff.add("\n  // CSS class selectors for this template.\n");
      for (int i = 0; i < classes.length; i++) {
        buff.add(
          "  static String get ${dartNames[i]} => \"${classes[i]}\";\n");
      }
    }

    return buff.toString();
  }

  static String _emitClass(String className,
                           List<Map<Identifier, Identifier>> params,
                           TemplateContent content,
                           String addStylesheetFuncName) {
    StringBuffer buff = new StringBuffer();

    // Emit the template class.
    buff.add("class ${className} {\n");

    buff.add("  Map<String, Object> _scopes;\n");
    buff.add("  Element _fragment;\n\n");

    bool anyParams = false;
    for (final param in params) {
      buff.add("  ${param['type']} ${param['name']};\n");
      anyParams = true;
    }
    if (anyParams) buff.add("\n");

    ElemCG ecg = new ElemCG();

    if (!ecg.pushBlock()) {
      world.error("Error at ${content}");
    }

    var root = content.html.children.length > 0 ? content.html.children[0] :
        content.html;
    bool firstTime = true;
    for (var child in root.children) {
      if (child is TemplateText) {
        if (!firstTime) {
          ecg.closeStatement();
        }

        String textNodeValue = child.value.trim();
        if (textNodeValue.length > 0) {
          CGStatement stmt = ecg.pushStatement(child, "_fragment");
        }
      }
      ecg.emitConstructHtml(child, "", "_fragment");
      firstTime = false;
    }

    // Create all element names marked with var.
    String decls = ecg.globalDeclarations;
    if (decls.length > 0) {
      buff.add("\n  // Elements bound to a variable:\n");
      buff.add("${decls}\n");
    }

    // Create the constructor.
    buff.add("  ${className}(");
    bool firstParam = true;
    for (final param in params) {
      if (!firstParam) {
        buff.add(", ");
      }
      buff.add("this.${param['name']}");
      firstParam = false;
    }
    buff.add(") : _scopes = new Map<String, Object>() {\n");

    String initializers = ecg.globalInitializers;
    if (initializers.length > 0) {
      buff.add("    //Global initializers.\n");
      buff.add("${initializers}\n");
    }

    buff.add("    // Insure stylesheet for template exist in the document.\n");
    buff.add("    ${addStylesheetFuncName}();\n\n");

    buff.add("    _fragment = new DocumentFragment();\n");

    buff.add(ecg.codeBody);     // HTML for constructor to build.

    buff.add("  }\n\n");        // End constructor

    buff.add(emitGetters(content.getters));

    buff.add("  Element get root => _fragment;\n");

    // Emit all CSS class selectors:
    buff.add(_emitCSSSelectors(content.css));

    // Emit the injection functions.
    buff.add("\n  // Injection functions:");
    for (final expr in ecg.expressions) {
      buff.add("${expr}");
    }

    buff.add("\n  // Each functions:\n");
    for (var eachFunc in ecg.eachs) {
      buff.add("${eachFunc}\n");
    }

    buff.add("\n  // With functions:\n");
    for (var withFunc in ecg.withs) {
      buff.add("${withFunc}\n");
    }

    buff.add("\n  // CSS for this template.\n");
    buff.add("  static const String stylesheet = ");

    if (content.css != null) {
      buff.add("\'\'\'\n    ${content.css.toString()}\n");
      buff.add("  \'\'\';\n\n");

      // TODO(terry): Emit all known selectors for this template.
      buff.add("  // Stylesheet class selectors:\n");
    } else {
      buff.add("\"\";\n");
    }

    buff.add("  String safeHTML(String html) {\n");
    buff.add("    // TODO(terry): Escaping for XSS vulnerabilities TBD.\n");
    buff.add("    return html;\n");
    buff.add("  }\n");

    buff.add("}\n");              // End class

    return buff.toString();
  }

  // TODO(terry): Need to generate function to inject any TemplateExpressions
  //              to call SafeHTML wrapper.
  static String emitGetters(List<TemplateGetter> getters) {
    StringBuffer buff = new StringBuffer();
    for (final TemplateGetter getter in getters) {
      buff.add('  String ${getter.getterSignatureAsString()} {\n');
      buff.add('    return \'\'\'');
      var docFrag = getter.docFrag.children[0];
      for (final child in docFrag.children) {
        buff.add(child.toString().trim());
      }
      buff.add('\'\'\';\n');
      buff.add('  }\n\n');
    }

    return buff.toString();
  }
}

class ElemCG {
  // List of identifiers and quoted strings (single and double quoted).
  var identRe = const RegExp(
    "\s*('\"\\'\\\"[^'\"\\'\\\"]+'\"\\'\\\"|[_A-Za-z][_A-Za-z0-9]*)");

  List<CGBlock> _cgBlocks;
  StringBuffer _globalDecls;        // Global var declarations for all blocks.
  StringBuffer _globalInits;        // Global List var initializtion for all
                                    // blocks in a #each.
  String funcCall;                  // Func call after element creation?
  List<String> expressions;         // List of injection function declarations.
  List<String> eachs;               // List of each function declarations.
  List<String> withs;               // List of with function declarations.

  ElemCG() :
    expressions = [],
    eachs = [],
    withs = [],
    _cgBlocks = [],
    _globalDecls = new StringBuffer(),
    _globalInits = new StringBuffer();

  bool get isLastBlockConstructor {
    CGBlock block = _cgBlocks.last();
    return block.isConstructor;
  }

  List<String> activeBlocksLocalNames() {
    List<String> result = [];

    for (final CGBlock block in _cgBlocks) {
      if (block.isEach || block.isWith) {
        if (block.hasLocalName) {
          result.add(block.localName);
        }
      }
    }

    return result;
  }

  /**
   * Active block with this localName.
   */
  bool matchBlocksLocalName(String name) {
    for (final CGBlock block in _cgBlocks) {
      if (block.isEach || block.isWith) {
        if (block.hasLocalName && block.localName == name) {
          return true;
        }
      }
    }

    return false;
  }

  /**
   * Any active blocks?
   */
  bool isNestedBlock() {
    for (final CGBlock block in _cgBlocks) {
      if (block.isEach || block.isWith) {
        return true;
      }
    }

    return false;
  }

  /**
   * Any active blocks with localName?
   */
  bool isNestedNamedBlock() {
    for (final CGBlock block in _cgBlocks) {
      if ((block.isEach || block.isWith) && block.hasLocalName) {
        return true;
      }
    }

    return false;
  }

  // Any current active #each blocks.
  bool anyEachBlocks(int blockToCreateType) {
    bool result = blockToCreateType == CGBlock.EACH;

    for (final CGBlock block in _cgBlocks) {
      if (block.isEach) {
        result = result || true;
      }
    }

    return result;
  }

  bool pushBlock([int indent = 4, int blockType = CGBlock.CONSTRUCTOR,
                  String itemName = null]) {
    if (itemName != null && matchBlocksLocalName(itemName)) {
      world.error("Active block already exist with local name: ${itemName}.");
      return false;
    } else if (itemName == null && this.isNestedBlock()) {
      world.error('''
Nested #each or #with must have a localName;
 \n  #each list [localName]\n  #with object [localName]''');
      return false;
    }
    _cgBlocks.add(
        new CGBlock(indent, blockType, anyEachBlocks(blockType), itemName));

    return true;
  }

  void popBlock() {
    _globalDecls.add(lastBlock.globalDeclarations);
    _globalInits.add(lastBlock.globalInitializers);
    _cgBlocks.removeLast();
  }

  CGStatement pushStatement(var elem, var parentName) {
    return lastBlock.push(elem, parentName, false);
  }

  CGStatement pushExactStatement(var elem, var parentName) {
    return lastBlock.push(elem, parentName, true);
  }

  bool get isClosedStatement {
    return (lastBlock != null && lastBlock.last != null) ?
        lastBlock.last.isClosed : false;
  }

  void closeStatement() {
    if (lastBlock != null && lastBlock.last != null &&
        !lastBlock.last.isClosed) {
      lastBlock.last.close();
    }
  }

  String get lastVariableName {
    if (lastBlock != null && lastBlock.last != null) {
      return lastBlock.last.variableName;
    }
  }

  String get lastParentName {
    if (lastBlock != null && lastBlock.last != null) {
      return lastBlock.last.parentName;
    }
  }

  CGBlock get lastBlock => _cgBlocks.length > 0 ? _cgBlocks.last() : null;

  void add(String str) {
    _cgBlocks.last().add(str);
  }

  String get globalDeclarations {
    assert(_cgBlocks.length == 1);    // Only constructor body should be left.
    _globalDecls.add(lastBlock.globalDeclarations);
    return _globalDecls.toString();
  }

  String get globalInitializers {
    assert(_cgBlocks.length == 1);    // Only constructor body should be left.
    _globalInits.add(lastBlock.globalInitializers);
    return _globalInits.toString();
  }

  String get codeBody {
    closeStatement();
    return _cgBlocks.last().codeBody;
  }

  /* scopeName for expression
   * parentVarOrIndex if # it's a local variable if string it's an exposed
   * name (specified by the var attribute) for this element.
   *
   */
  emitElement(var elem,
              [String scopeName = "",
               var parentVarOrIdx = 0,
               bool immediateNestedEach = false]) {
    if (elem is TemplateElement) {
      if (!elem.isFragment) {
        add("<${elem.tagName}${elem.attributesToString()}>");
      }
      String prevParent = lastVariableName;
      for (var childElem in elem.children) {
        if (childElem is TemplateElement) {
          closeStatement();
          if (childElem.hasVar) {
            emitConstructHtml(childElem, scopeName, prevParent,
              childElem.varName);
          } else {
            emitConstructHtml(childElem, scopeName, prevParent);
          }
          closeStatement();
        } else {
          emitElement(childElem, scopeName, parentVarOrIdx);
        }
      }

      // Close this tag.
      closeStatement();
    } else if (elem is TemplateText) {
      String outputValue = elem.value.trim();
      if (outputValue.length > 0) {
        bool emitTextNode = false;
        if (isClosedStatement) {
          String prevParent = lastParentName;
          CGStatement stmt = pushStatement(elem, prevParent);
          emitTextNode = true;
        }

        // TODO(terry): Need to interpolate following:
        //      {sp}  → space
        //      {nil} → empty string
        //      {\r}  → carriage return
        //      {\n}  → new line (line feed)
        //      {\t}  → tab
        //      {lb}  → left brace
        //      {rb}  → right brace

        add("${outputValue}");            // remove leading/trailing whitespace.

        if (emitTextNode) {
          closeStatement();
        }
      }
    } else if (elem is TemplateExpression) {
      emitExpressions(elem, scopeName);
    } else if (elem is TemplateEachCommand) {
      // Signal to caller new block coming in, returns "each_" prefix
      emitEach(elem, "List", elem.listName.name, "parent", immediateNestedEach,
          elem.hasLoopItem ? elem.loopItem.name : null);
    } else if (elem is TemplateWithCommand) {
      // Signal to caller new block coming in, returns "each_" prefix
      emitWith(elem, "var", elem.objectName.name, "parent",
          elem.hasBlockItem ? elem.blockItem.name : null);
    } else if (elem is TemplateCall) {
      emitCall(elem, parentVarOrIdx);
    }
  }

  // TODO(terry): Hack prefixing all names with "${scopeName}." but don't touch
  //              quoted strings.
  String _resolveNames(String expr, String prefixPart) {
    StringBuffer newExpr = new StringBuffer();
    Iterable<Match> matches = identRe.allMatches(expr);

    int lastIdx = 0;
    for (Match m in matches) {
      if (m.start() > lastIdx) {
        newExpr.add(expr.substring(lastIdx, m.start()));
      }

      bool identifier = true;
      if (m.start() > 0)  {
        int charCode = expr.charCodeAt(m.start() - 1);
        // Starts with ' or " then it's not an identifier.
        identifier = charCode != 34 /* " */ && charCode != 39 /* ' */;
      }

      String strMatch = expr.substring(m.start(), m.end());
      if (identifier) {
        newExpr.add("${prefixPart}.${strMatch}");
      } else {
        // Quoted string don't touch.
        newExpr.add("${strMatch}");
      }
      lastIdx = m.end();
    }

    if (expr.length > lastIdx) {
      newExpr.add(expr.substring(lastIdx));
    }

    return newExpr.toString();
  }

  /**
   * Construct the HTML each top-level node get's it's own variable.
   *
   * TODO(terry): Might want to optimize if the other top-level nodes have no
   *              control structures (with, each, if, etc.). We could
   *              synthesize a root node and create all the top-level nodes
   *              under the root node with one innerHTML.
   */
  void emitConstructHtml(var elem,
                         [String scopeName = "",
                          String parentName = "parent",
                          var varIndex = 0,
                          bool immediateNestedEach = false]) {
    if (elem is TemplateElement) {
      CGStatement stmt = pushStatement(elem, parentName);
      emitElement(elem, scopeName, stmt.hasGlobalVariable ?
          stmt.variableName : varIndex);
    } else {
      emitElement(elem, scopeName, varIndex, immediateNestedEach);
    }
  }

  /* Any references to products.sales needs to be remaped to item.sales
   * for now it's a hack look for first dot and replace with item.
   */
  String eachIterNameToItem(String iterName) {
    String newName = iterName;
    var dotForIter = iterName.indexOf('.');
    if (dotForIter >= 0) {
      newName = "_item${iterName.substring(dotForIter)}";
    }

    return newName;
  }

  emitExpressions(TemplateExpression elem, String scopeName) {
    StringBuffer func = new StringBuffer();

    String newExpr = elem.expression;
    bool anyNesting = isNestedNamedBlock();
    if (scopeName.length > 0 && !anyNesting) {
      // In a block #command need the scope passed in.
      add("\$\{inject_${expressions.length}(_item)\}");
      func.add("\n  String inject_${expressions.length}(var _item) {\n");
      // Escape all single-quotes, this expression is embedded as a string
      // parameter for the call to safeHTML.
      newExpr = _resolveNames(newExpr.replaceAll("'", "\\'"), "_item");
    } else {
      // Not in a block #command item isn't passed in.
      add("\$\{inject_${expressions.length}()\}");
      func.add("\n  String inject_${expressions.length}() {\n");

      if (anyNesting) {
        func.add(defineScopes());
      }
    }

    // Construct the active scope names for name resolution.

    func.add("    return safeHTML('\$\{${newExpr}\}');\n");
    func.add("  }\n");

    expressions.add(func.toString());
  }

  emitCall(TemplateCall elem, String scopeName) {
    pushStatement(elem, scopeName);
  }

  emitEach(TemplateEachCommand elem, String iterType, String iterName,
      var parentVarOrIdx, bool nestedImmediateEach, [String itemName = null]) {
    TemplateDocument docFrag = elem.documentFragment;

    int eachIndex = eachs.length;
    eachs.add("");

    StringBuffer funcBuff = new StringBuffer();
    // Prepare function call "each_N(iterName," parent param computed later.
    String funcName = "each_${eachIndex}";

    funcBuff.add("  ${funcName}(${iterType} items, Element parent) {\n");

    String paramName = injectParamName(itemName);
    if (paramName == null) {
      world.error("Use a different local name; ${itemName} is reserved.");
    }
    funcBuff.add("    for (var ${paramName} in items) {\n");

    if (!pushBlock(6, CGBlock.EACH, itemName)) {
      world.error("Error at ${elem}");
    }

    addScope(6, funcBuff, itemName);

    TemplateElement docFragChild = docFrag.children[0];
    var children = docFragChild.isFragment ?
        docFragChild.children : docFrag.children;
    for (var child in children) {
      // If any immediate children of the parent #each is an #each then
      // so we need to pass the outer #each parent not the last statement's
      // variableName when calling the nested #each.
      bool eachChild = (child is TemplateEachCommand);
      emitConstructHtml(child, iterName, parentVarOrIdx, 0, eachChild);
    }

    funcBuff.add(codeBody);

    removeScope(6, funcBuff, itemName);

    popBlock();

    funcBuff.add("    }\n");
    funcBuff.add("  }\n");

    eachs[eachIndex] = funcBuff.toString();

    // If nested each then we want to pass the parent otherwise we'll use the
    // varName.
    var varName = nestedImmediateEach ? "parent" : lastBlockVarName;

    pushExactStatement(elem, parentVarOrIdx);

    // Setup call to each func as "each_n(xxxxx, " the parent param is filled
    // in later when we known the parent variable.
    String eachParam =
        (itemName == null) ? eachIterNameToItem(iterName) : iterName;
    add("${funcName}(${eachParam}, ${varName})");
}

  emitWith(TemplateWithCommand elem, String withType, String withName,
      var parentVarIndex, [String itemName = null]) {
    TemplateDocument docFrag = elem.documentFragment;

    int withIndex = withs.length;
    withs.add("");

    StringBuffer funcBuff = new StringBuffer();
    // Prepare function call "each_N(iterName," parent param computed later.
    String funcName = "with_${withIndex}";

    String paramName = injectParamName(itemName);
    if (paramName == null) {
      world.error("Use a different local name; ${itemName} is reserved.");
    }
    funcBuff.add("  ${funcName}(${withType} ${paramName}, Element parent) {\n");

    if (!pushBlock(4, CGBlock.WITH, itemName)) {
      world.error("Error at ${elem}");
    }

    TemplateElement docFragChild = docFrag.children[0];
    var children = docFragChild.isFragment ?
        docFragChild.children : docFrag.children;
    for (var child in children) {
      emitConstructHtml(child, withName, "parent");
    }

    addScope(4, funcBuff, itemName);
    funcBuff.add(codeBody);
    removeScope(4, funcBuff, itemName);

    popBlock();

    funcBuff.add("  }\n");

    withs[withIndex] = funcBuff.toString();

    // Compute parent node variable before pushing with statement.
    String parentVarName = lastBlockVarName;

    pushExactStatement(elem, parentVarIndex);

    // Setup call to each func as "each_n(xxxxx, " the parent param is filled
    // in later when we known the parent variable.
    add("${funcName}(${withName}, ${parentVarName})");
  }

  String get lastBlockVarName {
    var varName;
    if (lastBlock != null && lastBlock.anyStatements) {
      varName = lastBlock.last.variableName;
    } else {
      varName = "_fragment";
    }

    return varName;
  }

  String injectParamName(String name) {
    // Local name _item is reserved.
    if (name != null && name == "_item") {
      return null;    // Local name is not valid.
    }

    return (name == null) ? "_item" : name;
  }

  addScope(int indent, StringBuffer buff, String item) {
    String spaces = Codegen.spaces(indent);

    if (item == null) {
      item = "_item";
    }
    buff.add("${spaces}_scopes[\"${item}\"] = ${item};\n");
  }

  removeScope(int indent, StringBuffer buff, String item) {
    String spaces = Codegen.spaces(indent);

    if (item == null) {
      item = "_item";
    }
    buff.add("${spaces}_scopes.remove(\"${item}\");\n");
  }

  String defineScopes() {
    StringBuffer buff = new StringBuffer();

    // Construct the active scope names for name resolution.
    List<String> names = activeBlocksLocalNames();
    if (names.length > 0) {
      buff.add("    // Local scoped block names.\n");
      for (String name in names) {
        buff.add("    var ${name} = _scopes[\"${name}\"];\n");
      }
      buff.add("\n");
    }

    return buff.toString();
  }

}
