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

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';

/**
 * A visitor for visiting [AstNode]s covered by a selection [SourceRange].
 */
class SelectionAnalyzer extends GeneralizingAstVisitor<Object> {
  final SourceRange selection;

  AstNode _coveringNode;
  List<AstNode> _selectedNodes;

  SelectionAnalyzer(this.selection);

  /**
   * Return the [AstNode] with the shortest length which completely covers the
   * specified selection.
   */
  AstNode get coveringNode => _coveringNode;

  /**
   * Returns the first selected [AstNode], may be `null`.
   */
  AstNode get firstSelectedNode {
    if (_selectedNodes == null || _selectedNodes.isEmpty) {
      return null;
    }
    return _selectedNodes[0];
  }

  /**
   * Returns `true` if there are [AstNode]s fully covered by the
   * selection [SourceRange].
   */
  bool get hasSelectedNodes =>
      _selectedNodes != null && !_selectedNodes.isEmpty;

  /**
   * Returns `true` if there was no selected nodes yet.
   */
  bool get isFirstNode => _selectedNodes == null;

  /**
   * Returns the last selected [AstNode], may be `null`.
   */
  AstNode get lastSelectedNode {
    if (_selectedNodes == null || _selectedNodes.isEmpty) {
      return null;
    }
    return _selectedNodes[_selectedNodes.length - 1];
  }

  /**
   * Returns the [SourceRange] which covers selected [AstNode]s, may be `null`
   * if there are no [AstNode]s under the selection.
   */
  SourceRange get selectedNodeRange {
    if (_selectedNodes == null || _selectedNodes.isEmpty) {
      return null;
    }
    AstNode firstNode = _selectedNodes[0];
    AstNode lastNode = _selectedNodes[_selectedNodes.length - 1];
    return range.startEnd(firstNode, lastNode);
  }

  /**
   * Return the [AstNode]s fully covered by the selection [SourceRange].
   */
  List<AstNode> get selectedNodes {
    if (_selectedNodes == null || _selectedNodes.isEmpty) {
      return [];
    }
    return _selectedNodes;
  }

  /**
   * Adds first selected [AstNode].
   */
  void handleFirstSelectedNode(AstNode node) {
    _selectedNodes = [];
    _selectedNodes.add(node);
  }

  /**
   * Adds second or more selected [AstNode].
   */
  void handleNextSelectedNode(AstNode node) {
    if (firstSelectedNode.parent == node.parent) {
      _selectedNodes.add(node);
    }
  }

  /**
   * Notifies that selection ends in given [AstNode].
   */
  void handleSelectionEndsIn(AstNode node) {}

  /**
   * Notifies that selection starts in given [AstNode].
   */
  void handleSelectionStartsIn(AstNode node) {}

  /**
   * Resets selected nodes.
   */
  void reset() {
    _selectedNodes = null;
  }

  @override
  Object visitNode(AstNode node) {
    SourceRange nodeRange = range.node(node);
    if (selection.covers(nodeRange)) {
      if (isFirstNode) {
        handleFirstSelectedNode(node);
      } else {
        handleNextSelectedNode(node);
      }
      return null;
    } else if (selection.coveredBy(nodeRange)) {
      _coveringNode = node;
      node.visitChildren(this);
      return null;
    } else if (selection.startsIn(nodeRange)) {
      handleSelectionStartsIn(node);
      node.visitChildren(this);
      return null;
    } else if (selection.endsIn(nodeRange)) {
      handleSelectionEndsIn(node);
      node.visitChildren(this);
      return null;
    }
    // no intersection
    return null;
  }
}
