// 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.

library services.src.correction.selection_analyzer;

import 'package:analysis_server/src/services/correction/source_range.dart';
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/source.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 rangeStartEnd(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 = rangeNode(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;
  }
}
