// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Provides an implementation the parts of the RTree data structure that don't
// require knowledge of the generic key type. Don't use these objects directly,
// rather specialize the RTree<> object in r_tree.h. This file defines the
// internal objects of an RTree, namely Nodes (internal nodes of the tree) and
// Records, which hold (key, rectangle) pairs.

#ifndef UI_GFX_GEOMETRY_R_TREE_BASE_H_
#define UI_GFX_GEOMETRY_R_TREE_BASE_H_

#include <list>
#include <vector>

#include "base/containers/hash_tables.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/gfx_export.h"

namespace gfx {

class GFX_EXPORT RTreeBase {
 protected:
  class NodeBase;
  class RecordBase;

  typedef std::vector<const RecordBase*> Records;
  typedef ScopedVector<NodeBase> Nodes;

  RTreeBase(size_t min_children, size_t max_children);
  ~RTreeBase();

  // Protected data structure class for storing internal Nodes or leaves with
  // Records.
  class GFX_EXPORT NodeBase {
   public:
    virtual ~NodeBase();

    // Appends to |records_out| the set of Records in this subtree with rects
    // that intersect |query_rect|.  Avoids clearing |records_out| so that it
    // can be called recursively.
    virtual void AppendIntersectingRecords(const Rect& query_rect,
                                           Records* records_out) const = 0;

    // Returns all records stored in the subtree rooted at this node. Appends to
    // |matches_out| without clearing.
    virtual void AppendAllRecords(Records* records_out) const = 0;

    // Returns NULL if no children. Does not recompute bounds.
    virtual scoped_ptr<NodeBase> RemoveAndReturnLastChild() = 0;

    // Returns -1 for Records, or the height of this subtree for Nodes.  The
    // height of a leaf Node (a Node containing only Records) is 0, a leaf's
    // parent is 1, etc. Note that in an R*-Tree, all branches from the root
    // Node will be the same height.
    virtual int Level() const = 0;

    // Recomputes our bounds by taking the union of all child rects, then calls
    // recursively on our parent so that ultimately all nodes up to the root
    // recompute their bounds.
    void RecomputeBoundsUpToRoot();

    NodeBase* parent() { return parent_; }
    const NodeBase* parent() const { return parent_; }
    void set_parent(NodeBase* parent) { parent_ = parent; }
    const Rect& rect() const { return rect_; }
    void set_rect(const Rect& rect) { rect_ = rect; }

   protected:
    NodeBase(const Rect& rect, NodeBase* parent);

    // Bounds recomputation without calling parents to do the same.
    virtual void RecomputeLocalBounds();

   private:
    friend class RTreeTest;
    friend class RTreeNodeTest;

    // This Node's bounding rectangle.
    Rect rect_;

    // A weak pointer to our parent Node in the RTree. The root node will have a
    // NULL value for |parent_|.
    NodeBase* parent_;

    DISALLOW_COPY_AND_ASSIGN(NodeBase);
  };

  class GFX_EXPORT RecordBase : public NodeBase {
   public:
    explicit RecordBase(const Rect& rect);
    virtual ~RecordBase();

    virtual void AppendIntersectingRecords(const Rect& query_rect,
                                           Records* records_out) const OVERRIDE;
    virtual void AppendAllRecords(Records* records_out) const OVERRIDE;
    virtual scoped_ptr<NodeBase> RemoveAndReturnLastChild() OVERRIDE;
    virtual int Level() const OVERRIDE;

   private:
    friend class RTreeTest;
    friend class RTreeNodeTest;

    DISALLOW_COPY_AND_ASSIGN(RecordBase);
  };

  class GFX_EXPORT Node : public NodeBase {
   public:
    // Constructs an empty Node with |level_| of 0.
    Node();
    virtual ~Node();

    virtual void AppendIntersectingRecords(const Rect& query_rect,
                                           Records* records_out) const OVERRIDE;
    virtual scoped_ptr<NodeBase> RemoveAndReturnLastChild() OVERRIDE;
    virtual int Level() const OVERRIDE;
    virtual void AppendAllRecords(Records* matches_out) const OVERRIDE;

    // Constructs a new Node that is the parent of this Node and already has
    // this Node as its sole child. Valid to call only on root Nodes, meaning
    // Nodes with |parent_| NULL. Note that ownership of this Node is
    // transferred to the parent returned by this function.
    scoped_ptr<Node> ConstructParent();

    // Removes |number_to_remove| children from this Node, and appends them to
    // the supplied list. Does not repair bounds upon completion. Nodes are
    // selected in the manner suggested in the Beckmann et al. paper, which
    // suggests that the children should be sorted by the distance from the
    // center of their bounding rectangle to their parent's bounding rectangle,
    // and then the n closest children should be removed for re-insertion. This
    // removal occurs at most once on each level of the tree when overflowing
    // nodes that have exceeded the maximum number of children during an Insert.
    void RemoveNodesForReinsert(size_t number_to_remove, Nodes* nodes);

    // Given a pointer to a child node within this Node, removes it from our
    // list. If that child had any children, appends them to the supplied orphan
    // list. Returns the removed child. Does not recompute bounds, as the caller
    // might subsequently remove this node as well, meaning the recomputation
    // would be wasted work.
    scoped_ptr<NodeBase> RemoveChild(NodeBase* child_node, Nodes* orphans);

    // Returns the best parent for insertion of the provided |node| as a child.
    Node* ChooseSubtree(NodeBase* node);

    // Adds |node| as a child of this Node, and recomputes the bounds of this
    // node after the addition of the child. Returns the new count of children
    // stored in this Node. This node becomes the owner of |node|.
    size_t AddChild(scoped_ptr<NodeBase> node);

    // Returns a sibling to this Node with at least min_children and no greater
    // than max_children of this Node's children assigned to it, and having the
    // same parent. Bounds will be valid on both Nodes after this call.
    scoped_ptr<NodeBase> Split(size_t min_children, size_t max_children);

    size_t count() const { return children_.size(); }
    const NodeBase* child(size_t i) const { return children_[i]; }
    NodeBase* child(size_t i) { return children_[i]; }

   private:
    typedef std::vector<Rect> Rects;

    explicit Node(int level);

    // Given two arrays of bounds rectangles as computed by BuildLowBounds()
    // and BuildHighBounds(), returns the index of the element in those arrays
    // along which a split of the arrays would result in a minimum amount of
    // overlap (area of intersection) in the two groups.
    static size_t ChooseSplitIndex(size_t start_index,
                                   size_t end_index,
                                   const Rects& low_bounds,
                                   const Rects& high_bounds);

    // R*-Tree attempts to keep groups of rectangles that are roughly square
    // in shape. It does this by comparing the "margins" of different bounding
    // boxes, where margin is defined as the sum of the length of all four sides
    // of a rectangle. For two rectangles of equal area, the one with the
    // smallest margin will be the rectangle whose width and height differ the
    // least. When splitting we decide to split along an axis chosen from the
    // rectangles either sorted vertically or horizontally by finding the axis
    // that would result in the smallest sum of margins between the two bounding
    // boxes of the resulting split. Returns the smallest sum computed given the
    // sorted bounding boxes and a range to look within.
    static int SmallestMarginSum(size_t start_index,
                                 size_t end_index,
                                 const Rects& low_bounds,
                                 const Rects& high_bounds);

    // Sorts nodes primarily by increasing y coordinates, and secondarily by
    // increasing height.
    static bool CompareVertical(const NodeBase* a, const NodeBase* b);

    // Sorts nodes primarily by increasing x coordinates, and secondarily by
    // increasing width.
    static bool CompareHorizontal(const NodeBase* a, const NodeBase* b);

    // Sorts nodes by the distance of the center of their rectangles to the
    // center of their parent's rectangles.
    static bool CompareCenterDistanceFromParent(
        const NodeBase* a, const NodeBase* b);

    // Given two vectors of Nodes sorted by vertical or horizontal bounds,
    // populates two vectors of Rectangles in which the ith element is the union
    // of all bounding rectangles [0,i] in the associated sorted array of Nodes.
    static void BuildLowBounds(const std::vector<NodeBase*>& vertical_sort,
                               const std::vector<NodeBase*>& horizontal_sort,
                               Rects* vertical_bounds,
                               Rects* horizontal_bounds);

    // Given two vectors of Nodes sorted by vertical or horizontal bounds,
    // populates two vectors of Rectangles in which the ith element is the
    // union of all bounding rectangles [i, count()) in the associated sorted
    // array of Nodes.
    static void BuildHighBounds(const std::vector<NodeBase*>& vertical_sort,
                                const std::vector<NodeBase*>& horizontal_sort,
                                Rects* vertical_bounds,
                                Rects* horizontal_bounds);

    virtual void RecomputeLocalBounds() OVERRIDE;

    // Returns the increase in overlap value, as defined in Beckmann et al. as
    // the sum of the areas of the intersection of all child rectangles
    // (excepting the candidate child) with the argument rectangle. Here the
    // |candidate_node| is one of our |children_|, and |expanded_rect| is the
    // already-computed union of the candidate's rect and |rect|.
    int OverlapIncreaseToAdd(const Rect& rect,
                             const NodeBase* candidate_node,
                             const Rect& expanded_rect) const;

    // Returns a new node containing children [split_index, count()) within
    // |sorted_children|.  Children before |split_index| remain with |this|.
    scoped_ptr<NodeBase> DivideChildren(
        const Rects& low_bounds,
        const Rects& high_bounds,
        const std::vector<NodeBase*>& sorted_children,
        size_t split_index);

    // Returns a pointer to the child node that will result in the least overlap
    // increase with the addition of node_rect, or NULL if there's a tie found.
    // Requires a precomputed vector of expanded rectangles where the ith
    // rectangle in the vector is the union of |children_|[i] and node_rect.
    // Overlap is defined in Beckmann et al. as the sum of the areas of
    // intersection of all child rectangles with the |node_rect| argument
    // rectangle.  This heuristic attempts to choose the node for which adding
    // the new rectangle to their bounding box will result in the least overlap
    // with the other rectangles, thus trying to preserve the usefulness of the
    // bounding rectangle by keeping it from covering too much redundant area.
    Node* LeastOverlapIncrease(const Rect& node_rect,
                               const Rects& expanded_rects);

    // Returns a pointer to the child node that will result in the least area
    // enlargement if the argument node rectangle were to be added to that
    // node's bounding box. Requires a precomputed vector of expanded rectangles
    // where the ith rectangle in the vector is the union of children_[i] and
    // |node_rect|.
    Node* LeastAreaEnlargement(const Rect& node_rect,
                               const Rects& expanded_rects);

    const int level_;

    Nodes children_;

    friend class RTreeTest;
    friend class RTreeNodeTest;

    DISALLOW_COPY_AND_ASSIGN(Node);
  };

  // Inserts |node| into the tree. The |highest_reinsert_level| supports
  // re-insertion as described by Beckmann et al. As Node overflows progagate
  // up the tree the algorithm performs a reinsertion of the overflow Nodes
  // (instead of a split) at most once per level of the tree. A starting value
  // of -1 for |highest_reinsert_level| means that reinserts are permitted for
  // every level of the tree. This should always be set to -1 except by
  // recursive calls from within InsertNode().
  void InsertNode(scoped_ptr<NodeBase> node, int* highest_reinsert_level);

  // Removes |node| from the tree without deleting it.
  scoped_ptr<NodeBase> RemoveNode(NodeBase* node);

  // If |root_| has only one child, deletes the |root_| Node and replaces it
  // with its only descendant child. Otherwise does nothing.
  void PruneRootIfNecessary();

  // Deletes the entire current tree and replaces it with an empty Node.
  void ResetRoot();

  const Node* root() const { return root_.get(); }

 private:
  friend class RTreeTest;
  friend class RTreeNodeTest;

  // A pointer to the root node in the RTree.
  scoped_ptr<Node> root_;

  // The parameters used to define the shape of the RTree.
  const size_t min_children_;
  const size_t max_children_;

  DISALLOW_COPY_AND_ASSIGN(RTreeBase);
};

}  // namespace gfx

#endif  // UI_GFX_GEOMETRY_R_TREE_BASE_H_
