// 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 Wildcard extends ASTNode {
  Wildcard(SourceSpan span): super(span);

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

  String toString() => '*';
}

// /*  ....   */
class CssComment extends ASTNode {
  String comment;

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

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

  String toString() => '/* ${comment} */';
}

// CDO/CDC (Comment Definition Open <!-- and Comment Definition Close -->).
class CommentDefinition extends CssComment {
  CommentDefinition(String comment, SourceSpan span): super(comment, span);

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

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

class SelectorGroup extends ASTNode {
  List<Selector> _selectors;

  SelectorGroup(this._selectors, SourceSpan span): super(span);

  List<Selector> get selectors => _selectors;

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

  String toString() {
    StringBuffer buff = new StringBuffer();
    int idx = 0;
    for (final selector in _selectors) {
      if (idx++ > 0) {
        buff.write(', ');
      }
      buff.write(selector.toString());
    }
    return buff.toString();
  }

  /** A multiline string showing the node and its children. */
  String toDebugString() {
    var to = new TreeOutput();
    var tp = new TreePrinter(to);
    this.visit(tp);
    return to.buf.toString();
  }
}

class Selector extends ASTNode {
  List<SimpleSelectorSequence> _simpleSelectorSequences;

  Selector(this._simpleSelectorSequences, SourceSpan span) : super(span);

  List<SimpleSelectorSequence> get simpleSelectorSequences =>
      _simpleSelectorSequences;

  add(SimpleSelectorSequence seq) => _simpleSelectorSequences.add(seq);

  List<SimpleSelectorSequence> get simpleSelectorSquences =>
      _simpleSelectorSequences;

  int get length => _simpleSelectorSequences.length;

  String toString() {
    StringBuffer buff = new StringBuffer();
    for (final simpleSelectorSequence in _simpleSelectorSequences) {
      buff.write(simpleSelectorSequence.toString());
    }
    return buff.toString();
  }

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

class SimpleSelectorSequence extends ASTNode {
  int _combinator;              // +, >, ~, NONE
  SimpleSelector _selector;

  SimpleSelectorSequence(this._selector, SourceSpan span,
      [this._combinator = TokenKind.COMBINATOR_NONE]) : super(span);

  get simpleSelector => _selector;

  bool isCombinatorNone() => _combinator == TokenKind.COMBINATOR_NONE;
  bool isCombinatorPlus() => _combinator == TokenKind.COMBINATOR_PLUS;
  bool isCombinatorGreater() => _combinator == TokenKind.COMBINATOR_GREATER;
  bool isCombinatorTilde() => _combinator == TokenKind.COMBINATOR_TILDE;
  bool isCombinatorDescendant() =>
      _combinator == TokenKind.COMBINATOR_DESCENDANT;

  String _combinatorToString() =>
      isCombinatorDescendant() ? ' ' :
      isCombinatorPlus() ? '+' :
      isCombinatorGreater() ? '>' :
      isCombinatorTilde() ? '~' : '';

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

  String toString() => "${_combinatorToString()}${_selector.toString()}";
}

/* All other selectors (element, #id, .class, attribute, pseudo, negation,
 * namespace, *) are derived from this selector.
 */
class SimpleSelector extends ASTNode {
  var _name;

  SimpleSelector(this._name, SourceSpan span) : super(span);

  // Name can be an Identifier or WildCard we'll return either the name or '*'.
  String get name => isWildcard() ? '*' : _name.name;

  bool isWildcard() => _name is Wildcard;

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

  String toString() => name;
}

// element name
class ElementSelector extends SimpleSelector {
  ElementSelector(var name, SourceSpan span) : super(name, span);

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

  String toString() => "$name";

  /** A multiline string showing the node and its children. */
  String toDebugString() {
    var to = new TreeOutput();
    var tp = new TreePrinter(to);
    this.visit(tp);
    return to.buf.toString();
  }
}

// namespace|element
class NamespaceSelector extends SimpleSelector {
  var _namespace;           // null, Wildcard or Identifier

  NamespaceSelector(this._namespace, var name, SourceSpan span) :
      super(name, span);

  String get namespace => _namespace is Wildcard ? '*' : _namespace.name;

  bool isNamespaceWildcard() => _namespace is Wildcard;

  SimpleSelector get nameAsSimpleSelector => _name;

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

  String toString() => "$namespace|${nameAsSimpleSelector.name}";
}

// [attr op value]
class AttributeSelector extends SimpleSelector {
  int _op;
  var _value;

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

  String matchOperator() {
    switch (_op) {
    case TokenKind.EQUALS:
      return '=';
    case TokenKind.INCLUDES:
      return '~=';
    case TokenKind.DASH_MATCH:
      return '|=';
    case TokenKind.PREFIX_MATCH:
      return '^=';
    case TokenKind.SUFFIX_MATCH:
      return '\$=';
    case TokenKind.SUBSTRING_MATCH:
      return '*=';
    }
  }

  // Return the TokenKind for operator used by visitAttributeSelector.
  String matchOperatorAsTokenString() {
    switch (_op) {
    case TokenKind.EQUALS:
      return 'EQUALS';
    case TokenKind.INCLUDES:
      return 'INCLUDES';
    case TokenKind.DASH_MATCH:
      return 'DASH_MATCH';
    case TokenKind.PREFIX_MATCH:
      return 'PREFIX_MATCH';
    case TokenKind.SUFFIX_MATCH:
      return 'SUFFIX_MATCH';
    case TokenKind.SUBSTRING_MATCH:
      return 'SUBSTRING_MATCH';
    }
  }

  String valueToString() {
    if (_value is Identifier) {
      return _value.name;
    } else {
      return '"${_value}"';
    }
  }

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

  String toString() => "[${name} ${matchOperator()} ${valueToString()}]";
}

// #id
class IdSelector extends SimpleSelector {
  IdSelector(Identifier name, SourceSpan span) : super(name, span);

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

  String toString() => "#$name";
}

// .class
class ClassSelector extends SimpleSelector {
  ClassSelector(Identifier name, SourceSpan span) : super(name, span);

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

  String toString() => ".$name";
}

// :pseudoClass
class PseudoClassSelector extends SimpleSelector {
  PseudoClassSelector(Identifier name, SourceSpan span) :
      super(name, span);

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

  String toString() => ":$name";
}

// ::pseudoElement
class PseudoElementSelector extends SimpleSelector {
  PseudoElementSelector(Identifier name, SourceSpan span) :
      super(name, span);

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

  String toString() => "::$name";
}

// TODO(terry): Implement
// NOT
class NotSelector extends SimpleSelector {
  NotSelector(String name, SourceSpan span) : super(name, span);

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

class Stylesheet extends ASTNode {
  // Contains charset, ruleset, directives (media, page, etc.)
  List<ASTNode> _topLevels;

  Stylesheet(this._topLevels, SourceSpan span) : super(span) {
    for (final node in _topLevels) {
      assert(node is TopLevelProduction || node is Directive);
    }
  }

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

  List<ASTNode> get topLevels => _topLevels;

  String toString() {
    StringBuffer buff = new StringBuffer();
    for (final topLevel in _topLevels) {
      buff.write(topLevel.toString());
    }
    return buff.toString();
  }

  /** A multiline string showing the node and its children. */
  String toDebugString() {
    var to = new TreeOutput();
    var tp = new TreePrinter(to);
    this.visit(tp);
    return to.buf.toString();
  }
}

class TopLevelProduction extends ASTNode {
  TopLevelProduction(SourceSpan span) : super(span);

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

  String toString() => "TopLevelProduction";
}

class RuleSet extends TopLevelProduction {
  SelectorGroup _selectorGroup;
  DeclarationGroup _declarationGroup;

  RuleSet(this._selectorGroup, this._declarationGroup, SourceSpan span) :
      super(span);

  SelectorGroup get selectorGroup => _selectorGroup;
  DeclarationGroup get declarationGroup => _declarationGroup;

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

  String toString() =>
      "\n${_selectorGroup.toString()} {\n"
        "${_declarationGroup.toString()}}\n";
}

class Directive extends ASTNode {
  Directive(SourceSpan span) : super(span);

  String toString() => "Directive";

  bool get isBuiltIn => true;       // Known CSS directive?
  bool get isExtension => false;    // SCSS extension?

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

class ImportDirective extends Directive {
  String _import;
  List<String> _media;

  ImportDirective(this._import, this._media, SourceSpan span) :
      super(span);

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

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

    buff.write('@import url(${_import})');

    int idx = 0;
    for (final medium in _media) {
      buff.write(idx++ == 0 ? ' $medium' : ',$medium');
    }
    buff.write('\n');

    return buff.toString();
  }
}

class MediaDirective extends Directive {
  List<String> _media;
  RuleSet _ruleset;

  MediaDirective(this._media, this._ruleset, SourceSpan span) :
      super(span);

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

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

    buff.write('@media');
    int idx = 0;
    for (var medium in _media) {
      buff.write(idx++ == 0 ? ' $medium' : ',$medium');
    }
    buff.write(' {\n');
    buff.write(_ruleset.toString());
    buff.write('\n\}\n');

    return buff.toString();
  }
}

class PageDirective extends Directive {
  String _pseudoPage;
  DeclarationGroup _decls;

  PageDirective(this._pseudoPage, this._decls, SourceSpan span) :
    super(span);

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

  // @page : pseudoPage {
  //    decls
  // }
  String toString() {
    StringBuffer buff = new StringBuffer();

    buff.write('@page ');
    if (_pseudoPage != null) {
      buff.write(': ${_pseudoPage} ');
    }
    buff.write('{\n${_decls.toString()}\n}\n');

    return buff.toString();
  }
}

class KeyFrameDirective extends Directive {
  var _name;
  List<KeyFrameBlock> _blocks;

  KeyFrameDirective(this._name, SourceSpan span) :
      _blocks = [], super(span);

  add(KeyFrameBlock block) {
    _blocks.add(block);
  }

  String get name => _name;

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

  String toString() {
    StringBuffer buff = new StringBuffer();
    buff.write('@-webkit-keyframes ${_name} {\n');
    for (final block in _blocks) {
      buff.write(block.toString());
    }
    buff.write('}\n');
    return buff.toString();
  }
}

class KeyFrameBlock extends Expression {
  Expressions _blockSelectors;
  DeclarationGroup _declarations;

  KeyFrameBlock(this._blockSelectors, this._declarations, SourceSpan span):
      super(span);

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

  String toString() {
    StringBuffer buff = new StringBuffer();
    buff.write('  ${_blockSelectors.toString()} {\n');
    buff.write(_declarations.toString());
    buff.write('  }\n');
    return buff.toString();
  }
}

// TODO(terry): TBD
class FontFaceDirective extends Directive {
  List<Declaration> _declarations;

  FontFaceDirective(this._declarations, SourceSpan span) : super(span);

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

  String toString() {
    return "TO BE DONE";
  }
}

class IncludeDirective extends Directive {
  String _include;
  Stylesheet _stylesheet;

  IncludeDirective(this._include, this._stylesheet, SourceSpan span) :
      super(span);

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

  bool get isBuiltIn => false;
  bool get isExtension => true;

  Stylesheet get styleSheet => _stylesheet;

  String toString() {
    StringBuffer buff = new StringBuffer();
    buff.write('/****** @include ${_include} ******/\n');
    buff.write(_stylesheet != null ? _stylesheet.toString() : '// <EMPTY>');
    buff.write('/****** End of ${_include} ******/\n\n');
    return buff.toString();
  }
}

class StyletDirective extends Directive {
  String _dartClassName;
  List<RuleSet> _rulesets;

  StyletDirective(this._dartClassName, this._rulesets, SourceSpan span) :
      super(span);

  bool get isBuiltIn => false;
  bool get isExtension => true;

  String get dartClassName => _dartClassName;
  List<RuleSet> get rulesets => _rulesets;

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

  // TODO(terry): Output Dart class
  String toString() => '/* @stylet export as ${_dartClassName} */\n';
}

class Declaration extends ASTNode {
  Identifier _property;
  Expression _expression;
  bool _important;

  Declaration(this._property, this._expression, SourceSpan span) :
      _important = false, super(span);

  String get property => _property.name;
  Expression get expression => _expression;

  bool get important => _important;
  set important(bool value) => _important = value;
  String importantAsString() => _important ? ' !important' : '';

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

  String toString() =>
      "${_property.name}: ${_expression.toString()}${importantAsString()}";
}

class DeclarationGroup extends ASTNode {
  List<Declaration> _declarations;

  DeclarationGroup(this._declarations, SourceSpan span) : super(span);

  List<Declaration> get declarations => _declarations;

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

  String toString() {
    StringBuffer buff = new StringBuffer();
    int idx = 0;
    for (final declaration in _declarations) {
      buff.write("  ${declaration.toString()};\n");
    }
    return buff.toString();
  }
}

class OperatorSlash extends Expression {
  OperatorSlash(SourceSpan span) : super(span);

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

  String toString() => ' /';
}

class OperatorComma extends Expression {
  OperatorComma(SourceSpan span) : super(span);

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

  String toString() => ',';
}

class LiteralTerm extends Expression {
  var _value;
  String _text;

  LiteralTerm(this._value, this._text, SourceSpan span) : super(span);

  get value => _value;
  String get text => _text;

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

  String toString() => _text;
}

class NumberTerm extends LiteralTerm {
  NumberTerm(var value, String t, SourceSpan span) : super(value, t, span);

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

class UnitTerm extends LiteralTerm {
  int _unit;

  UnitTerm(var value, String t, SourceSpan span, this._unit) :
      super(value, t, span);

  int get unit => _unit;

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

  String toString() => '${text}${unitToString()}';
  String unitToString() => TokenKind.unitToString(_unit);
}

class LengthTerm extends UnitTerm {
  LengthTerm(var value, String t, SourceSpan span,
      [int unit = TokenKind.UNIT_LENGTH_PX]) : super(value, t, span, unit) {
    assert(this._unit == TokenKind.UNIT_LENGTH_PX ||
        this._unit == TokenKind.UNIT_LENGTH_CM ||
        this._unit == TokenKind.UNIT_LENGTH_MM ||
        this._unit == TokenKind.UNIT_LENGTH_IN ||
        this._unit == TokenKind.UNIT_LENGTH_PT ||
        this._unit == TokenKind.UNIT_LENGTH_PC);
  }

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

class PercentageTerm extends LiteralTerm {
  PercentageTerm(var value, String t, SourceSpan span) :
      super(value, t, span);

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

  String toString() => '${text}%';

}

class EmTerm extends LiteralTerm {
  EmTerm(var value, String t, SourceSpan span) :
      super(value, t, span);

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

  String toString() => '${text}em';
}

class ExTerm extends LiteralTerm {
  ExTerm(var value, String t, SourceSpan span) :
      super(value, t, span);

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

  String toString() => '${text}ex';
}

class AngleTerm extends UnitTerm {
  AngleTerm(var value, String t, SourceSpan span,
    [int unit = TokenKind.UNIT_LENGTH_PX]) : super(value, t, span, unit) {
    assert(this._unit == TokenKind.UNIT_ANGLE_DEG ||
        this._unit == TokenKind.UNIT_ANGLE_RAD ||
        this._unit == TokenKind.UNIT_ANGLE_GRAD);
  }

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

class TimeTerm extends UnitTerm {
  TimeTerm(var value, String t, SourceSpan span,
    [int unit = TokenKind.UNIT_LENGTH_PX]) : super(value, t, span, unit) {
    assert(this._unit == TokenKind.UNIT_ANGLE_DEG ||
        this._unit == TokenKind.UNIT_TIME_MS ||
        this._unit == TokenKind.UNIT_TIME_S);
  }

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

class FreqTerm extends UnitTerm {
  FreqTerm(var value, String t, SourceSpan span,
    [int unit = TokenKind.UNIT_LENGTH_PX]) : super(value, t, span, unit) {
    assert(_unit == TokenKind.UNIT_FREQ_HZ || _unit == TokenKind.UNIT_FREQ_KHZ);
  }

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

class FractionTerm extends LiteralTerm {
  FractionTerm(var value, String t, SourceSpan span) :
    super(value, t, span);

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

  String toString() => '${text}fr';
}

class UriTerm extends LiteralTerm {
  UriTerm(String value, SourceSpan span) : super(value, value, span);

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

  String toString() => 'url(${text})';
}

class HexColorTerm extends LiteralTerm {
  HexColorTerm(var value, String t, SourceSpan span) :
      super(value, t, span);

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

  String toString() => '#${text}';
}

class FunctionTerm extends LiteralTerm {
  Expressions _params;

  FunctionTerm(var value, String t, this._params, SourceSpan span)
      : super(value, t, span);

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

  String toString() {
    // TODO(terry): Optimize rgb to a hexcolor.
    StringBuffer buff = new StringBuffer();

    buff.write('${text}(');
    buff.write(_params.toString());
    buff.write(')');

    return buff.toString();
  }
}

class GroupTerm extends Expression {
  List<LiteralTerm> _terms;

  GroupTerm(SourceSpan span) : _terms =  [], super(span);

  add(LiteralTerm term) {
    _terms.add(term);
  }

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

  String toString() {
    StringBuffer buff = new StringBuffer();
    buff.write('(');
    int idx = 0;
    for (final term in _terms) {
      if (idx++ > 0) {
        buff.write(' ');
      }
      buff.write(term.toString());
    }
    buff.write(')');
    return buff.toString();
  }
}

class ItemTerm extends NumberTerm {
  ItemTerm(var value, String t, SourceSpan span) : super(value, t, span);

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

  String toString() => '[${text}]';
}

class Expressions extends Expression {
  List<Expression> _expressions;

  Expressions(SourceSpan span): super(span), _expressions = [];

  add(Expression expression) {
    _expressions.add(expression);
  }

  List<Expression> get expressions => _expressions;

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

  String toString() {
    StringBuffer buff = new StringBuffer();
    int idx = 0;
    for (final expression in _expressions) {
      // Add space seperator between terms without an operator.
      // TODO(terry): Should have a BinaryExpression to solve this problem.
      if (idx > 0 &&
          !(expression is OperatorComma || expression is OperatorSlash)) {
        buff.write(' ');
      }
      buff.write(expression.toString());
      idx++;
    }
    return buff.toString();
  }
}

class BinaryExpression extends Expression {
  Token op;
  Expression x;
  Expression y;

  BinaryExpression(this.op, this.x, this.y, SourceSpan span): super(span);

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

class UnaryExpression extends Expression {
  Token op;
  Expression self;

  UnaryExpression(this.op, this.self, SourceSpan span): super(span);

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

abstract class TreeVisitor {
  void visitCssComment(CssComment node);
  void visitCommentDefinition(CommentDefinition node);
  void visitStylesheet(Stylesheet node);
  void visitTopLevelProduction(TopLevelProduction node);
  void visitDirective(Directive node);
  void visitMediaDirective(MediaDirective node);
  void visitPageDirective(PageDirective node);
  void visitImportDirective(ImportDirective node);
  void visitKeyFrameDirective(KeyFrameDirective node);
  void visitKeyFrameBlock(KeyFrameBlock node);
  void visitFontFaceDirective(FontFaceDirective node);
  void visitIncludeDirective(IncludeDirective node);
  void visitStyletDirective(StyletDirective node);

  void visitRuleSet(RuleSet node);
  void visitDeclarationGroup(DeclarationGroup node);
  void visitDeclaration(Declaration node);
  void visitSelectorGroup(SelectorGroup node);
  void visitSelector(Selector node);
  void visitSimpleSelectorSequence(SimpleSelectorSequence node);
  void visitSimpleSelector(SimpleSelector node);
  void visitElementSelector(ElementSelector node);
  void visitNamespaceSelector(NamespaceSelector node);
  void visitAttributeSelector(AttributeSelector node);
  void visitIdSelector(IdSelector node);
  void visitClassSelector(ClassSelector node);
  void visitPseudoClassSelector(PseudoClassSelector node);
  void visitPseudoElementSelector(PseudoElementSelector node);
  void visitNotSelector(NotSelector node);

  void visitLiteralTerm(LiteralTerm node);
  void visitHexColorTerm(HexColorTerm node);
  void visitNumberTerm(NumberTerm node);
  void visitUnitTerm(UnitTerm node);
  void visitLengthTerm(LengthTerm node);
  void visitPercentageTerm(PercentageTerm node);
  void visitEmTerm(EmTerm node);
  void visitExTerm(ExTerm node);
  void visitAngleTerm(AngleTerm node);
  void visitTimeTerm(TimeTerm node);
  void visitFreqTerm(FreqTerm node);
  void visitFractionTerm(FractionTerm node);
  void visitUriTerm(UriTerm node);
  void visitFunctionTerm(FunctionTerm node);
  void visitGroupTerm(GroupTerm node);
  void visitItemTerm(ItemTerm node);
  void visitOperatorSlash(OperatorSlash node);
  void visitOperatorComma(OperatorComma node);

  void visitExpressions(Expressions node);
  void visitBinaryExpression(BinaryExpression node);
  void visitUnaryExpression(UnaryExpression node);

  void visitIdentifier(Identifier node);
  void visitWildcard(Wildcard node);

  // TODO(terry): Defined for ../tree.dart.
  void visitTypeReference(TypeReference node);
}

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

  void visitStylesheet(Stylesheet node) {
    output.heading('Stylesheet', node.span);
    output.depth++;
    output.writeNodeList('productions', node._topLevels);
    output.depth--;
  }

  void visitTopLevelProduction(TopLevelProduction node) {
    output.heading('TopLevelProduction', node.span);
  }

  void visitDirective(Directive node) {
    output.heading('Directive', node.span);
  }

  void visitCssComment(CssComment node) {
    output.heading('Comment', node.span);
    output.depth++;
    output.writeValue('comment value', node.comment);
    output.depth--;
  }

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

  void visitMediaDirective(MediaDirective node) {
    output.heading('MediaDirective', node.span);
    output.depth++;
    output.writeNodeList('media', node._media);
    visitRuleSet(node._ruleset);
    output.depth--;
  }

  void visitPageDirective(PageDirective node) {
    output.heading('PageDirective', node.span);
    output.depth++;
    output.writeValue('pseudo page', node._pseudoPage);
    visitDeclarationGroup(node._decls);
    output.depth;
}

  void visitImportDirective(ImportDirective node) {
    output.heading('ImportDirective', node.span);
    output.depth++;
    output.writeValue('import', node._import);
    output.writeNodeList('media', node._media);
    output.depth--;
  }

  void visitKeyFrameDirective(KeyFrameDirective node) {
    output.heading('KeyFrameDirective', node.span);
    output.depth++;
    output.writeValue('name', node._name);
    output.writeNodeList('blocks', node._blocks);
    output.depth--;
  }

  void visitKeyFrameBlock(KeyFrameBlock node) {
    output.heading('KeyFrameBlock', node.span);
    output.depth++;
    visitExpressions(node._blockSelectors);
    visitDeclarationGroup(node._declarations);
    output.depth--;
  }

  void visitFontFaceDirective(FontFaceDirective node) {
    // TODO(terry): To Be Implemented
  }

  void visitIncludeDirective(IncludeDirective node) {
    output.heading('IncludeDirective', node.span);
    output.writeValue('include', node._include);
    output.depth++;
    if (node._stylesheet != null) {
      visitStylesheet(node._stylesheet);
    } else {
      output.writeValue('StyleSheet', '<EMPTY>');
    }
    output.depth--;
  }

  void visitStyletDirective(StyletDirective node) {
    output.heading('StyletDirective', node.span);
    output.writeValue('dartClassName', node._dartClassName);
    output.depth++;
    output.writeNodeList('rulesets', node._rulesets);
    output.depth--;
}

  void visitRuleSet(RuleSet node) {
    output.heading('Ruleset', node.span);
    output.depth++;
    visitSelectorGroup(node._selectorGroup);
    visitDeclarationGroup(node._declarationGroup);
    output.depth--;
  }

  void visitDeclarationGroup(DeclarationGroup node) {
    output.heading('DeclarationGroup', node.span);
    output.depth++;
    output.writeNodeList('declarations', node._declarations);
    output.depth--;
  }

  void visitDeclaration(Declaration node) {
    output.heading('Declaration', node.span);
    output.depth++;
    output.write('property');
    visitIdentifier(node._property);
    output.writeNode('expression', node._expression);
    if (node.important) {
      output.writeValue('!important', 'true');
    }
    output.depth--;
  }

  void visitSelectorGroup(SelectorGroup node) {
    output.heading('Selector Group', node.span);
    output.depth++;
    output.writeNodeList('selectors', node.selectors);
    output.depth--;
  }

  void visitSelector(Selector node) {
    output.heading('Selector', node.span);
    output.depth++;
    output.writeNodeList('simpleSelectorsSequences',
        node._simpleSelectorSequences);
    output.depth--;
  }

  void visitSimpleSelectorSequence(SimpleSelectorSequence node) {
    output.heading('SimpleSelectorSequence', node.span);
    output.depth++;
    if (node.isCombinatorNone()) {
      output.writeValue('combinator', "NONE");
    } else if (node.isCombinatorDescendant()) {
      output.writeValue('combinator', "descendant");
    } else if (node.isCombinatorPlus()) {
      output.writeValue('combinator', "+");
    } else if (node.isCombinatorGreater()) {
      output.writeValue('combinator', ">");
    } else if (node.isCombinatorTilde()) {
      output.writeValue('combinator', "~");
    } else {
      output.writeValue('combinator', "ERROR UNKNOWN");
    }

    var selector = node._selector;
    if (selector is NamespaceSelector) {
      visitNamespaceSelector(selector);
    } else if (selector is ElementSelector) {
      visitElementSelector(selector);
    } else if (selector is IdSelector) {
      visitIdSelector(selector);
    } else if (selector is ClassSelector) {
      visitClassSelector(selector);
    } else if (selector is PseudoClassSelector) {
      visitPseudoClassSelector(selector);
    } else if (selector is PseudoElementSelector) {
      visitPseudoElementSelector(selector);
    } else if (selector is NotSelector) {
      visitNotSelector(selector);
    } else if (selector is AttributeSelector) {
      visitAttributeSelector(selector);
    } else {
      output.heading('SimpleSelector', selector.span);
      output.depth++;
      visitSimpleSelector(selector);
      output.depth--;
    }

    output.depth--;
  }

  void visitSimpleSelector(SimpleSelector node) {
    visitIdentifier(node._name);
  }

  void visitNamespaceSelector(NamespaceSelector node) {
    output.heading('Namespace Selector', node.span);
    output.depth++;

    var namespace = node._namespace;
    if (namespace is Identifier) {
      visitIdentifier(namespace);
    } else if (namespace is Wildcard) {
      visitWildcard(namespace);
    } else {
      output.writeln("NULL");
    }

    visitSimpleSelector(node.nameAsSimpleSelector);
    output.depth--;
  }

  void visitElementSelector(ElementSelector node) {
    output.heading('Element Selector', node.span);
    output.depth++;
    visitSimpleSelector(node);
    output.depth--;
  }

  void visitAttributeSelector(AttributeSelector node) {
    output.heading('AttributeSelector', node.span);
    output.depth++;
    visitSimpleSelector(node);
    String tokenStr = node.matchOperatorAsTokenString();
    output.writeValue('operator', '${node.matchOperator()} (${tokenStr})');
    output.writeValue('value', node.valueToString());
    output.depth--;
  }

  void visitIdSelector(IdSelector node) {
    output.heading('Id Selector', node.span);
    output.depth++;
    visitSimpleSelector(node);
    output.depth--;
  }

  void visitClassSelector(ClassSelector node) {
    output.heading('Class Selector', node.span);
    output.depth++;
    visitSimpleSelector(node);
    output.depth--;
  }

  void visitPseudoClassSelector(PseudoClassSelector node) {
    output.heading('Pseudo Class Selector', node.span);
    output.depth++;
    visitSimpleSelector(node);
    output.depth--;
  }

  void visitPseudoElementSelector(PseudoElementSelector node) {
    output.heading('Pseudo Element Selector', node.span);
    output.depth++;
    visitSimpleSelector(node);
    output.depth--;
  }

  void visitNotSelector(NotSelector node) {
    visitSimpleSelector(node);
    output.depth++;
    output.heading('Not Selector', node.span);
    output.depth--;
  }

  void visitLiteralTerm(LiteralTerm node) {
    output.heading('LiteralTerm', node.span);
    output.depth++;
    output.writeValue('value', node.text);
    output.depth--;
 }

  void visitHexColorTerm(HexColorTerm node) {
    output.heading('HexColorTerm', node.span);
    output.depth++;
    output.writeValue('hex value', node.text);
    output.writeValue('decimal value', node.value);
    output.depth--;
  }

  void visitNumberTerm(NumberTerm node) {
    output.heading('NumberTerm', node.span);
    output.depth++;
    output.writeValue('value', node.text);
    output.depth--;
  }

  void visitUnitTerm(UnitTerm node) {
    String unitValue;

    output.depth++;
    output.writeValue('value', node.text);
    output.writeValue('unit', node.unitToString());
    output.depth--;
  }

  void visitLengthTerm(LengthTerm node) {
    output.heading('LengthTerm', node.span);
    visitUnitTerm(node);
  }

  void visitPercentageTerm(PercentageTerm node) {
    output.heading('PercentageTerm', node.span);
    output.depth++;
    visitLiteralTerm(node);
    output.depth--;
  }

  void visitEmTerm(EmTerm node) {
    output.heading('EmTerm', node.span);
    output.depth++;
    visitLiteralTerm(node);
    output.depth--;
  }

  void visitExTerm(ExTerm node) {
    output.heading('ExTerm', node.span);
    output.depth++;
    visitLiteralTerm(node);
    output.depth--;
  }

  void visitAngleTerm(AngleTerm node) {
    output.heading('AngleTerm', node.span);
    visitUnitTerm(node);
  }

  void visitTimeTerm(TimeTerm node) {
    output.heading('TimeTerm', node.span);
    visitUnitTerm(node);
  }

  void visitFreqTerm(FreqTerm node) {
    output.heading('FreqTerm', node.span);
    visitUnitTerm(node);
  }

  void visitFractionTerm(FractionTerm node) {
    output.heading('FractionTerm', node.span);
    output.depth++;
    visitLiteralTerm(node);
    output.depth--;
  }

  void visitUriTerm(UriTerm node) {
    output.heading('UriTerm', node.span);
    output.depth++;
    visitLiteralTerm(node);
    output.depth--;
  }

  void visitFunctionTerm(FunctionTerm node) {
    output.heading('FunctionTerm', node.span);
    output.depth++;
    visitLiteralTerm(node);
    visitExpressions(node._params);
    output.depth--;
  }

  void visitGroupTerm(GroupTerm node) {
    output.heading('GroupTerm', node.span);
    output.depth++;
    output.writeNodeList('grouped terms', node._terms);
    output.depth--;
  }

  void visitItemTerm(ItemTerm node) {
    output.heading('ItemTerm', node.span);
    visitNumberTerm(node);
  }

  void visitOperatorSlash(OperatorSlash node) {
    output.heading('OperatorSlash', node.span);
  }

  void visitOperatorComma(OperatorComma node) {
    output.heading('OperatorComma', node.span);
  }

  void visitExpressions(Expressions node) {
    output.heading('Expressions', node.span);
    output.depth++;
    output.writeNodeList('expressions', node._expressions);
    output.depth--;
  }

  void visitBinaryExpression(BinaryExpression node) {
    output.heading('BinaryExpression', node.span);
    // TODO(terry): TBD
  }

  void visitUnaryExpression(UnaryExpression node) {
    output.heading('UnaryExpression', node.span);
    // TODO(terry): TBD
  }

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

  void visitWildcard(Wildcard node) {
    output.heading('Wildcard(*)', node.span);
  }

  // TODO(terry): Defined for frog/tree.dart.
  void visitTypeReference(TypeReference node) {
    output.heading('Unimplemented');
  }
}
