// 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.write(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.write(stmt.globalInitializers());
    }

    return buff.toString();
  }

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

    for (final CGStatement stmt in _stmts) {
      buff.write(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.write(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.write("// Generated Dart class from HTML template.\n");
    buff.write("// DO NOT EDIT.\n\n");

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

    for (final template in templates) {
      // Emit the template class.
      TemplateSignature sig = template.signature;
      buff.write(_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.write("\n\n// Inject all templates stylesheet once into the head.\n");
    buff.write("bool ${filename}_stylesheet_added = false;\n");
    buff.write("void ${addStylesheetFuncName}() {\n");
    buff.write("  if (!${filename}_stylesheet_added) {\n");
    buff.write("    StringBuffer styles = new StringBuffer();\n\n");

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

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

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

    buff.write("    document.head.elements.add(new Element.html('<style>"
             "\${styles.toString()}</style>'));\n");
    buff.write("  }\n");
    buff.write("}\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.write("\n  // CSS class selectors for this template.\n");
      for (int i = 0; i < classes.length; i++) {
        buff.write(
          "  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.write("class ${className} {\n");

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

    bool anyParams = false;
    for (final param in params) {
      buff.write("  ${param['type']} ${param['name']};\n");
      anyParams = true;
    }
    if (anyParams) buff.write("\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.write("\n  // Elements bound to a variable:\n");
      buff.write("${decls}\n");
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    buff.write("}\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.write('  String ${getter.getterSignatureAsString()} {\n');
      buff.write('    return \'\'\'');
      var docFrag = getter.docFrag.children[0];
      for (final child in docFrag.children) {
        buff.write(child.toString().trim());
      }
      buff.write('\'\'\';\n');
      buff.write('  }\n\n');
    }

    return buff.toString();
  }
}

class ElemCG {
  // List of identifiers and quoted strings (single and double quoted).
  var identRe = new 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.codeUnitAt(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.write("${spaces}_scopes[\"${item}\"] = ${item};\n");
  }

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

    if (item == null) {
      item = "_item";
    }
    buff.write("${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.write("    // Local scoped block names.\n");
      for (String name in names) {
        buff.write("    var ${name} = _scopes[\"${name}\"];\n");
      }
      buff.write("\n");
    }

    return buff.toString();
  }

}
