// 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 = 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.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();
  }

}
