// 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.
// Generated by scripts/tree_gen.py.

/////////////////////////////////////////////////////////////////////////
// CSS specific types:
/////////////////////////////////////////////////////////////////////////

class Identifier extends ASTNode {
  String name;

  Identifier(this.name, SourceSpan span): super(span);

  visit(TreeVisitor visitor) => visitor.visitIdentifier(this);

  String toString() => name;
}

class StringValue extends ASTNode {
  String value;

  StringValue(this.value, SourceSpan span): super(span);

  visit(TreeVisitor visitor) => visitor.visitStringValue(this);

  String toString() => value;
}

// CDO/CDC (Comment Definition Open <!-- and Comment Definition Close -->).
class CommentDefinition extends ASTNode {
  String comment;

  CommentDefinition(this.comment, SourceSpan span): super(span);

  visit(TreeVisitor visitor) => visitor.visitCommentDefinition(this);

  String toString() => '<!-- ${comment} -->';
}

class Template extends ASTNode {
  TemplateSignature signature;
  TemplateContent content;

  Template(this.signature, this.content, SourceSpan span):
      super(span);

  visit(TreeVisitor visitor) => visitor.visitTemplate(this);

  String toString() => "${signature.toString()} \r{\r${content.toString()}\r}\r";
}

class TemplateSignature extends ASTNode {
  String name;
  List<Map<Identifier, Identifier>> params;   // Map of {type:, name:}

  TemplateSignature(this.name, this.params, SourceSpan span): super(span);

  visit(TreeVisitor visitor) => visitor.visitTemplateSignature(this);

  String paramsAsString() {
    StringBuffer buff = new StringBuffer();
    bool first = true;
    for (final param in params) {
      if (!first) {
        buff.write(", ");
      }
      if (param['type'] != null) {
        buff.write(param['type']);
        buff.write(' ');
      }
      buff.write(param['name']);
      first = false;
    }

    return buff.toString();
  }

  String toString() => "template ${name}(${paramsAsString()})";
}

class TemplateChildren extends ASTNode {
  List<ASTNode> children;

  TemplateChildren(this.children, SourceSpan span): super(span);
  TemplateChildren.empty(SourceSpan span): children = [], super(span);

  add(var child) {
    if (children == null) {
      children = new List<ASTNode>();
    }
    children.add(child);
  }

  ASTNode get last => children.last;
  ASTNode removeLast() => children.removeLast();
  bool get anyChildren => children != null && children.length > 0;

  visit(TreeVisitor visitor) => visitor.visitTemplateChildren(this);

  String toString() {
    StringBuffer buff = new StringBuffer();
    if (children != null) {
      for (final child in children) {
        buff.write(child.toString());
      }
    }

    return buff.toString();
  }
}

class TemplateGetter extends ASTNode {
  String name;
  List<Map<Identifier, Identifier>> params;
  TemplateDocument docFrag;

  TemplateGetter(this.name, this.params, this.docFrag, SourceSpan span) :
      super(span);

  visit(TreeVisitor visitor) => visitor.visitTemplateGetter(this);

  String paramsAsString() {
    StringBuffer buff = new StringBuffer();
    bool first = true;
    for (final param in params) {
      if (!first) {
        buff.write(", ");
      }
      if (param['type'] != null && param['type'].length > 0) {
        buff.write(param['type']);
        buff.write(' ');
      }
      buff.write(param['name']);
      first = false;
    }

    return buff.toString();
  }

  String getterSignatureAsString() => "${name}(${paramsAsString()})";
}

class TemplateContent extends ASTNode {
  css.Stylesheet css;
  TemplateDocument html;
  List<TemplateGetter> getters;

  TemplateContent(this.css, this.html, this.getters, SourceSpan span) :
      super(span);

  visit(TreeVisitor visitor) => visitor.visitTemplateContent(this);
}

class TemplateDocument extends TemplateChildren {
  TemplateDocument(List<ASTNode> children, SourceSpan span):
    super(children, span);

  visit(TreeVisitor visitor) => visitor.visitTemplateDocument(this);
}

class TemplateElement extends TemplateChildren {
  int tagTokenId;
  List<TemplateAttribute> attributes;
  StringValue _varName;

  TemplateElement(this.tagTokenId, SourceSpan span): super.empty(span);
  TemplateElement.fragment(SourceSpan span) : super.empty(span), tagTokenId = -1;
  TemplateElement.attributes(this.tagTokenId, this.attributes, this._varName,
    SourceSpan span): super.empty(span);

  bool get isFragment => tagTokenId == -1;
  bool get anyAttributes => attributes != null;

  visit(TreeVisitor visitor) => visitor.visitTemplateElement(this);

  bool get hasVar => _varName != null;
  String get varName => hasVar ? _varName.value : null;

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

    if (attributes != null) {
      for (final attr in attributes) {
        buff.write(' ${attr.toString()}');
      }
    }

    return buff.toString();
  }

  String get tagName => isFragment ?
    'root' : TokenKind.tagNameFromTokenId(tagTokenId);

  bool get scoped => !TokenKind.unscopedTag(tagTokenId);

  String tagStartToString() => "<${tagName}${attributesToString()}>";

  String tagEndToString() => "</${tagName}>";

  String toString() {
    StringBuffer buff = new StringBuffer(tagStartToString());

    if (children != null) {
      for (final child in children) {
        buff.write(child.toString());
      }

      buff.write(tagEndToString());
    }

    return buff.toString();
  }
}

class TemplateAttribute extends ASTNode {
  String name;
  String value;

  TemplateAttribute(this.name, this.value, SourceSpan span): super(span);

  visit(TreeVisitor visitor) => visitor.visitTemplateAttribute(this);

  String toString() => "${name}=\"${value}\"";
}

class TemplateText extends ASTNode {
  String value;

  TemplateText(this.value, SourceSpan span): super(span);

  visit(TreeVisitor visitor) => visitor.visitTemplateText(this);

  String toString() => value;
}

class TemplateExpression extends ASTNode {
  String expression;

  TemplateExpression(this.expression, SourceSpan span): super(span);

  visit(TreeVisitor visitor) => visitor.visitTemplateExpression(this);

  String toString() => "\$\{${expression}}";
}

class TemplateEachCommand extends ASTNode {
  String listName;
  String loopItem;
  TemplateDocument documentFragment;

  TemplateEachCommand(this.listName, this.loopItem, this.documentFragment,
      SourceSpan span): super(span);

  bool get hasLoopItem => loopItem != null;
  String get loopNameOptional => hasLoopItem ? " ${loopItem}" : "";

  visit(TreeVisitor visitor) => visitor.visitTemplateEachCommand(this);

  String toString() => "\$\{#each ${listName}${loopNameOptional}}";
}

class TemplateWithCommand extends ASTNode {
  String objectName;
  String blockItem;
  TemplateDocument documentFragment;

  TemplateWithCommand(this.objectName, this.blockItem, this.documentFragment,
      SourceSpan span): super(span);

  bool get hasBlockItem => blockItem != null;
  String get blockNameOptional => hasBlockItem ? " ${blockItem}" : "";

  visit(TreeVisitor visitor) => visitor.visitTemplateWithCommand(this);

  String toString() => "\$\{#with ${objectName}${blockNameOptional}}";
}

class TemplateCall extends ASTNode {
  String toCall;
  String params;

  TemplateCall(this.toCall, this.params, SourceSpan span): super(span);

  visit(TreeVisitor visitor) => visitor.visitTemplateCall(this);

  String toString() => "\$\{#${toCall}${params}}";
}

interface TreeVisitor {
  void visitIdentifier(Identifier node);
  void visitStringValue(StringValue node);
  void visitCommentDefinition(CommentDefinition node);
  void visitTemplate(Template node);
  void visitTemplateSignature(TemplateSignature node);
  void visitTemplateChildren(TemplateChildren node);
  void visitTemplateDocument(TemplateDocument node);
  void visitTemplateContent(TemplateContent node);
  void visitTemplateElement(TemplateElement node);
  void visitTemplateAttribute(TemplateAttribute node);
  void visitTemplateText(TemplateText node);
  void visitTemplateExpression(TemplateExpression node);
  void visitTemplateEachCommand(TemplateEachCommand node);
  void visitTemplateWithCommand(TemplateWithCommand node);
  void visitTemplateCall(TemplateCall node);
  void visitTemplateGetter(TemplateGetter node);
}

class TreePrinter implements TreeVisitor {
  var output;
  TreePrinter(this.output) { output.printer = this; }

  void visitIdentifier(Identifier node) {
    output.heading('Identifier(${output.toValue(node.name)})', node.span);
  }

  void visitStringValue(StringValue node) {
    output.heading('"${output.toValue(node.value)}"', node.span);
  }

  void visitCommentDefinition(CommentDefinition node) {
    output.heading('CommentDefinition (CDO/CDC)', node.span);
    output.depth++;
    output.writeValue('comment value', node.comment);
    output.depth--;
  }

  void visitTemplate(Template node) {
    output.heading('Template', node.span);
    output.depth++;
    visitTemplateSignature(node.signature);
    visitTemplateContent(node.content);
    output.depth--;
  }

  void visitTemplateSignature(TemplateSignature node) {
    output.heading('TemplateSignature', node.span);
    output.depth++;
    output.writeValue('Template', node);
    output.depth--;
  }

  void visitTemplateChildren(TemplateChildren node) {
    output.writeNodeList('children', node.children);
  }

  void visitTemplateContent(TemplateContent node) {
    visitTemplateDocument(node.html);
    if (node.css != null) {
      output.depth++;
      output.writeValue('---CSS---', node.css.toString());
      output.depth--;
    }
    if (node.getters != null) {
      output.depth++;
      output.writeNodeList('---GETTERS---', node.getters);
      output.depth--;
    }
  }

  void visitTemplateDocument(TemplateDocument node) {
    output.heading('Content', node.span);
    output.depth++;
    // TODO(terry): Ugly use of 'as dynamic' instead of children[0] to
    //              surpress warning.
    assert(node.children.length == 1 &&
        (node.children as dynamic)[0].tagTokenId == -1);
    output.writeNodeList("document", node.children);
    output.depth--;
  }

  void visitTemplateElement(TemplateElement node) {
    output.heading('Element', node.span);
    output.depth++;
    output.writeValue('tag', node.tagName);
    if (node.attributes != null && (node.attributes.length > 0)) {
      output.writeNodeList("attributes", node.attributes);
    }
    visitTemplateChildren(node);
    output.depth--;
  }

  void visitTemplateAttribute(TemplateAttribute node) {
    output.heading('Attribute', node.span);
    output.depth++;
    output.writeValue('name', node.name);
    output.writeValue('value', node.value);
    output.depth--;
  }

  void visitTemplateText(TemplateText node) {
    output.heading('Text', node.span);
    output.writeValue('value', node.value);
  }

  void visitTemplateExpression(TemplateExpression node) {
    output.heading('Interpolate', node.span);
    output.writeValue('expression', "\$\{${node.expression}\}");
  }

  void visitTemplateEachCommand(TemplateEachCommand node) {
    output.heading('#each', node.span);
    output.writeValue('list', node.listName);
    visitTemplateDocument(node.documentFragment);
  }

  void visitTemplateWithCommand(TemplateWithCommand node) {
    output.heading('#with', node.span);
    output.writeValue('object', node.objectName);
    visitTemplateDocument(node.documentFragment);
  }

  void visitTemplateCall(TemplateCall node) {
    output.heading('#call template', node.span);
    output.writeValue('templateToCall', node.toCall);
    output.writeValue('params', node.params);
  }

  void visitTemplateGetter(TemplateGetter node) {
    output.heading('template getter', node.span);
    output.writeValue('getter Signature', node.getterSignatureAsString());
    visitTemplateDocument(node.docFrag);
  }
}

