// Copyright (c) 2012, 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.

library csslib.visitor;

import 'package:source_maps/span.dart' show Span;
import 'parser.dart';

part 'src/css_printer.dart';
part 'src/tree.dart';
part 'src/tree_base.dart';
part 'src/tree_printer.dart';

abstract class VisitorBase {
  void visitCssComment(CssComment node);
  void visitCommentDefinition(CommentDefinition node);
  void visitStyleSheet(StyleSheet node);
  void visitNoOp(NoOp node);
  void visitTopLevelProduction(TopLevelProduction node);
  void visitDirective(Directive node);
  void visitMediaExpression(MediaExpression node);
  void visitMediaQuery(MediaQuery node);
  void visitMediaDirective(MediaDirective node);
  void visitHostDirective(HostDirective node);
  void visitPageDirective(PageDirective node);
  void visitCharsetDirective(CharsetDirective node);
  void visitImportDirective(ImportDirective node);
  void visitKeyFrameDirective(KeyFrameDirective node);
  void visitKeyFrameBlock(KeyFrameBlock node);
  void visitFontFaceDirective(FontFaceDirective node);
  void visitStyletDirective(StyletDirective node);
  void visitNamespaceDirective(NamespaceDirective node);
  void visitVarDefinitionDirective(VarDefinitionDirective node);
  void visitMixinDefinition(MixinDefinition node);
  void visitMixinRulesetDirective(MixinRulesetDirective node);
  void visitMixinDeclarationDirective(MixinDeclarationDirective node);
  void visitIncludeDirective(IncludeDirective node);
  void visitContentDirective(ContentDirective node);

  void visitRuleSet(RuleSet node);
  void visitDeclarationGroup(DeclarationGroup node);
  void visitMarginGroup(DeclarationGroup node);
  void visitDeclaration(Declaration node);
  void visitVarDefinition(VarDefinition node);
  void visitIncludeMixinAtDeclaration(IncludeMixinAtDeclaration node);
  void visitExtendDeclaration(ExtendDeclaration 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 visitPseudoClassFunctionSelector(PseudoClassFunctionSelector node);
  void visitPseudoElementFunctionSelector(PseudoElementFunctionSelector node);
  void visitNegationSelector(NegationSelector node);
  void visitSelectorExpression(SelectorExpression node);

  void visitUnicodeRangeTerm(UnicodeRangeTerm 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 visitResolutionTerm(ResolutionTerm node);
  void visitChTerm(ChTerm node);
  void visitRemTerm(RemTerm node);
  void visitViewportTerm(ViewportTerm node);
  void visitFunctionTerm(FunctionTerm node);
  void visitGroupTerm(GroupTerm node);
  void visitItemTerm(ItemTerm node);
  void visitIE8Term(IE8Term node);
  void visitOperatorSlash(OperatorSlash node);
  void visitOperatorComma(OperatorComma node);
  void visitOperatorPlus(OperatorPlus node);
  void visitOperatorMinus(OperatorMinus node);
  void visitVarUsage(VarUsage node);

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

  void visitIdentifier(Identifier node);
  void visitWildcard(Wildcard node);
  void visitThisOperator(ThisOperator node);
  void visitNegation(Negation node);

  void visitDartStyleExpression(DartStyleExpression node);
  void visitFontExpression(FontExpression node);
  void visitBoxExpression(BoxExpression node);
  void visitMarginExpression(MarginExpression node);
  void visitBorderExpression(BorderExpression node);
  void visitHeightExpression(HeightExpression node);
  void visitPaddingExpression(PaddingExpression node);
  void visitWidthExpression(WidthExpression node);
}

/** Base vistor class for the style sheet AST. */
class Visitor implements VisitorBase {
  /** Helper function to walk a list of nodes. */
  void _visitNodeList(list) {
    // Don't use iterable otherwise the list can't grow while using Visitor.
    // It certainly can't have items deleted before the index being iterated
    // but items could be added after the index.
    for (var index = 0; index < list.length; index++) {
      list[index].visit(this);
    }
  }

  void visitTree(StyleSheet tree) => visitStyleSheet(tree);

  void visitStyleSheet(StyleSheet ss) {
    _visitNodeList(ss.topLevels);
  }

  void visitNoOp(NoOp node) { }

  void visitTopLevelProduction(TopLevelProduction node) { }

  void visitDirective(Directive node) { }

  void visitCssComment(CssComment node) { }

  void visitCommentDefinition(CommentDefinition node) { }

  void visitMediaExpression(MediaExpression node) {
    visitExpressions(node.exprs);
  }

  void visitMediaQuery(MediaQuery node) {
    for (var mediaExpr in node.expressions) {
      visitMediaExpression(mediaExpr);
    }
  }

  void visitMediaDirective(MediaDirective node) {
    for (var mediaQuery in node.mediaQueries) {
      visitMediaQuery(mediaQuery);
    }
    for (var ruleset in node.rulesets) {
      visitRuleSet(ruleset);
    }
  }

  void visitHostDirective(HostDirective node) {
    for (var ruleset in node.rulesets) {
      visitRuleSet(ruleset);
    }
  }

  void visitPageDirective(PageDirective node) {
    for (var declGroup in node._declsMargin) {
      if (declGroup is MarginGroup) {
        visitMarginGroup(declGroup);
      } else {
        visitDeclarationGroup(declGroup);
      }
    }
  }

  void visitCharsetDirective(CharsetDirective node) { }

  void visitImportDirective(ImportDirective node) {
    for (var mediaQuery in node.mediaQueries) {
      visitMediaQuery(mediaQuery);
    }
  }

  void visitKeyFrameDirective(KeyFrameDirective node) {
    visitIdentifier(node._name);
    _visitNodeList(node._blocks);
  }

  void visitKeyFrameBlock(KeyFrameBlock node) {
    visitExpressions(node._blockSelectors);
    visitDeclarationGroup(node._declarations);
  }

  void visitFontFaceDirective(FontFaceDirective node) {
    visitDeclarationGroup(node._declarations);
  }

  void visitStyletDirective(StyletDirective node) {
    _visitNodeList(node._rulesets);
  }

  void visitNamespaceDirective(NamespaceDirective node) { }

  void visitVarDefinitionDirective(VarDefinitionDirective node) {
    visitVarDefinition(node.def);
  }

  void visitMixinRulesetDirective(MixinRulesetDirective node) {
    _visitNodeList(node.rulesets);
  }

  void visitMixinDefinition(MixinDefinition node) { }

  void visitMixinDeclarationDirective(MixinDeclarationDirective node) {
    visitDeclarationGroup(node.declarations);
  }

  void visitIncludeDirective(IncludeDirective node) {
    for (var index = 0; index < node.args.length; index++) {
      var param = node.args[index];
      _visitNodeList(param);
    }
  }

  void visitContentDirective(ContentDirective node) {
    // TODO(terry): TBD
  }

  void visitRuleSet(RuleSet node) {
    visitSelectorGroup(node._selectorGroup);
    visitDeclarationGroup(node._declarationGroup);
  }

  void visitDeclarationGroup(DeclarationGroup node) {
    _visitNodeList(node._declarations);
  }

  void visitMarginGroup(MarginGroup node) => visitDeclarationGroup(node);

  void visitDeclaration(Declaration node) {
    visitIdentifier(node._property);
    if (node._expression != null) node._expression.visit(this);
  }

  void visitVarDefinition(VarDefinition node) {
    visitIdentifier(node._property);
    if (node._expression != null) node._expression.visit(this);
  }

  void visitIncludeMixinAtDeclaration(IncludeMixinAtDeclaration node) {
    visitIncludeDirective(node.include);
  }

  void visitExtendDeclaration(ExtendDeclaration node) {
    _visitNodeList(node.selectors);
  }

  void visitSelectorGroup(SelectorGroup node) {
    _visitNodeList(node.selectors);
  }

  void visitSelector(Selector node) {
    _visitNodeList(node._simpleSelectorSequences);
  }

  void visitSimpleSelectorSequence(SimpleSelectorSequence node) {
    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 PseudoClassFunctionSelector) {
      visitPseudoClassFunctionSelector(selector);
    } else if (selector is PseudoElementFunctionSelector) {
      visitPseudoElementFunctionSelector(selector);
    } else if (selector is PseudoClassSelector) {
      visitPseudoClassSelector(selector);
    } else if (selector is PseudoElementSelector) {
      visitPseudoElementSelector(selector);
    } else if (selector is NegationSelector) {
      visitNegationSelector(selector);
    } else if (selector is SelectorExpression) {
      visitSelectorExpression(selector);
    } else if (selector is AttributeSelector) {
      visitAttributeSelector(selector);
    } else {
      visitSimpleSelector(selector);
    }
  }

  void visitSimpleSelector(SimpleSelector node) => node._name.visit(this);

  void visitNamespaceSelector(NamespaceSelector node) {
    var namespace = node._namespace;
    if (namespace is Identifier) {
      visitIdentifier(namespace);
    } else if (namespace is Wildcard) {
      visitWildcard(namespace);
    }

    visitSimpleSelector(node.nameAsSimpleSelector);
  }

  void visitElementSelector(ElementSelector node) => visitSimpleSelector(node);

  void visitAttributeSelector(AttributeSelector node) {
    visitSimpleSelector(node);
  }

  void visitIdSelector(IdSelector node) => visitSimpleSelector(node);

  void visitClassSelector(ClassSelector node) => visitSimpleSelector(node);

  void visitPseudoClassSelector(PseudoClassSelector node) =>
      visitSimpleSelector(node);

  void visitPseudoElementSelector(PseudoElementSelector node) =>
      visitSimpleSelector(node);

  void visitPseudoClassFunctionSelector(PseudoClassFunctionSelector node) =>
      visitSimpleSelector(node);

  void visitPseudoElementFunctionSelector(PseudoElementFunctionSelector node) =>
      visitSimpleSelector(node);

  void visitNegationSelector(NegationSelector node) =>
      visitSimpleSelector(node);

  void visitSelectorExpression(SelectorExpression node) {
    _visitNodeList(node._expressions);
  }

  void visitUnicodeRangeTerm(UnicodeRangeTerm node) { }

  void visitLiteralTerm(LiteralTerm node) { }

  void visitHexColorTerm(HexColorTerm node) { }

  void visitNumberTerm(NumberTerm node) { }

  void visitUnitTerm(UnitTerm node) { }

  void visitLengthTerm(LengthTerm node) {
    visitUnitTerm(node);
  }

  void visitPercentageTerm(PercentageTerm node) {
    visitLiteralTerm(node);
  }

  void visitEmTerm(EmTerm node) {
    visitLiteralTerm(node);
  }

  void visitExTerm(ExTerm node) {
    visitLiteralTerm(node);
  }

  void visitAngleTerm(AngleTerm node) {
    visitUnitTerm(node);
  }

  void visitTimeTerm(TimeTerm node) {
    visitUnitTerm(node);
  }

  void visitFreqTerm(FreqTerm node) {
    visitUnitTerm(node);
  }

  void visitFractionTerm(FractionTerm node) {
    visitLiteralTerm(node);
  }

  void visitUriTerm(UriTerm node) {
    visitLiteralTerm(node);
  }

  void visitResolutionTerm(ResolutionTerm node) {
    visitUnitTerm(node);
  }

  void visitChTerm(ChTerm node) {
    visitUnitTerm(node);
  }

  void visitRemTerm(RemTerm node) {
    visitUnitTerm(node);
  }

  void visitViewportTerm(ViewportTerm node) {
    visitUnitTerm(node);
  }

  void visitFunctionTerm(FunctionTerm node) {
    visitLiteralTerm(node);
    visitExpressions(node._params);
  }

  void visitGroupTerm(GroupTerm node) {
    for (var term in node._terms) {
      term.visit(this);
    }
  }

  void visitItemTerm(ItemTerm node) {
    visitNumberTerm(node);
  }

  void visitIE8Term(IE8Term node) { }

  void visitOperatorSlash(OperatorSlash node) { }

  void visitOperatorComma(OperatorComma node) { }

  void visitOperatorPlus(OperatorPlus node) { }

  void visitOperatorMinus(OperatorMinus node) { }

  void visitVarUsage(VarUsage node) {
    _visitNodeList(node.defaultValues);
  }

  void visitExpressions(Expressions node) {
    _visitNodeList(node.expressions);
  }

  void visitBinaryExpression(BinaryExpression node) {
    // TODO(terry): TBD
    throw UnimplementedError;
  }

  void visitUnaryExpression(UnaryExpression node) {
    // TODO(terry): TBD
    throw UnimplementedError;
  }

  void visitIdentifier(Identifier node) { }

  void visitWildcard(Wildcard node) { }

  void visitThisOperator(ThisOperator node) { }

  void visitNegation(Negation node) { }

  void visitDartStyleExpression(DartStyleExpression node) { }

  void visitFontExpression(FontExpression node) {
    // TODO(terry): TBD
    throw UnimplementedError;
  }

  void visitBoxExpression(BoxExpression node) {
    // TODO(terry): TBD
    throw UnimplementedError;
  }

  void visitMarginExpression(MarginExpression node) {
    // TODO(terry): TBD
    throw UnimplementedError;
  }

  void visitBorderExpression(BorderExpression node) {
    // TODO(terry): TBD
    throw UnimplementedError;
  }

  void visitHeightExpression(HeightExpression node) {
    // TODO(terry): TB
    throw UnimplementedError;
  }

  void visitPaddingExpression(PaddingExpression node) {
    // TODO(terry): TBD
    throw UnimplementedError;
  }

  void visitWidthExpression(WidthExpression node) {
    // TODO(terry): TBD
    throw UnimplementedError;
  }
}
