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

// Defines a hierarchical bounding rectangle data structure for Rect objects,
// associated with a generic unique key K for efficient spatial queries. The
// R*-tree algorithm is used to build the trees. Based on the papers:
//
// A Guttman 'R-trees:  a dynamic index structure for spatial searching', Proc
// ACM SIGMOD Int Conf on Management of Data, 47-57, 1984
//
// N Beckmann, H-P Kriegel, R Schneider, B Seeger 'The R*-tree: an efficient and
// robust access method for points and rectangles', Proc ACM SIGMOD Int Conf on
// Management of Data, 322-331, 1990

#ifndef COBALT_MATH_R_TREE_H_
#define COBALT_MATH_R_TREE_H_

#include "cobalt/math/r_tree_base.h"

#include "base/hash_tables.h"

namespace cobalt {
namespace math {

template <typename Key>
class RTree : public RTreeBase {
 public:
  typedef base::hash_set<Key> Matches;

  // RTrees organize pairs of keys and rectangles in a hierarchical bounding
  // box structure. This allows for queries of the tree within logarithmic time.
  // |min_children| and |max_children| allows for adjustment of the average size
  // of the nodes within RTree, which adjusts the base of the logarithm in the
  // algorithm runtime. Some parts of insertion and deletion are polynomial
  // in the size of the individual node, so the trade-off with larger nodes is
  // potentially faster queries but slower insertions and deletions. Generally
  // it is worth considering how much overlap between rectangles of different
  // keys will occur in the tree, and trying to set |max_children| as a
  // reasonable upper bound to the number of overlapping rectangles expected.
  // Then |min_children| can bet set to a quantity slightly less than half of
  // that.
  RTree(size_t min_children, size_t max_children);
  ~RTree();

  // Insert a new rect into the tree, associated with provided key. Note that if
  // |rect| is empty, the |key| will not actually be inserted. Duplicate keys
  // overwrite old entries.
  void Insert(const Rect& rect, Key key);

  // If present, remove the supplied |key| from the tree.
  void Remove(Key key);

  // Fills |matches_out| with all keys having bounding rects intersecting
  // |query_rect|.
  void AppendIntersectingRecords(const Rect& query_rect,
                                 Matches* matches_out) const;

  void Clear();

 private:
  friend class RTreeTest;
  friend class RTreeNodeTest;

  class Record : public RecordBase {
   public:
    Record(const Rect& rect, const Key& key);
    virtual ~Record();
    const Key& key() const { return key_; }

   private:
    Key key_;

    DISALLOW_COPY_AND_ASSIGN(Record);
  };

  // A map of supplied keys to their Node representation within the RTree, for
  // efficient retrieval of keys without requiring a bounding rect.
  typedef base::hash_map<Key, Record*> RecordMap;
  RecordMap record_map_;

  DISALLOW_COPY_AND_ASSIGN(RTree);
};

template <typename Key>
RTree<Key>::RTree(size_t min_children, size_t max_children)
    : RTreeBase(min_children, max_children) {}

template <typename Key>
RTree<Key>::~RTree() {}

template <typename Key>
void RTree<Key>::Insert(const Rect& rect, Key key) {
  scoped_ptr<NodeBase> record;
  // Check if this key is already present in the tree.
  typename RecordMap::iterator it(record_map_.find(key));

  if (it != record_map_.end()) {
    // We will re-use this node structure, regardless of re-insert or return.
    Record* existing_record = it->second;
    // If the new rect and the current rect are identical we can skip the rest
    // of Insert() as nothing has changed.
    if (existing_record->rect() == rect) return;

    // Remove the node from the tree in its current position.
    record = RemoveNode(existing_record);

    PruneRootIfNecessary();

    // If we are replacing this key with an empty rectangle we just remove the
    // old node from the list and return, thus preventing insertion of empty
    // rectangles into our spatial database.
    if (rect.IsEmpty()) {
      record_map_.erase(it);
      return;
    }

    // Reset the rectangle to the new value.
    record->set_rect(rect);
  } else {
    if (rect.IsEmpty()) return;

    record.reset(new Record(rect, key));
    record_map_.insert(std::make_pair(key, static_cast<Record*>(record.get())));
  }

  int highest_reinsert_level = -1;
  InsertNode(record.Pass(), &highest_reinsert_level);
}

template <typename Key>
void RTree<Key>::Clear() {
  record_map_.clear();
  ResetRoot();
}

template <typename Key>
void RTree<Key>::Remove(Key key) {
  // Search the map for the leaf parent that has the provided record.
  typename RecordMap::iterator it = record_map_.find(key);
  if (it == record_map_.end()) return;

  Record* record = it->second;
  record_map_.erase(it);
  RemoveNode(record);

  // Lastly check the root. If it has only one non-leaf child, delete it and
  // replace it with its child.
  PruneRootIfNecessary();
}

template <typename Key>
void RTree<Key>::AppendIntersectingRecords(const Rect& query_rect,
                                           Matches* matches_out) const {
  RTreeBase::Records matching_records;
  root()->AppendIntersectingRecords(query_rect, &matching_records);
  for (RTreeBase::Records::const_iterator it = matching_records.begin();
       it != matching_records.end(); ++it) {
    const Record* record = static_cast<const Record*>(*it);
    matches_out->insert(record->key());
  }
}

// RTree::Record --------------------------------------------------------------

template <typename Key>
RTree<Key>::Record::Record(const Rect& rect, const Key& key)
    : RecordBase(rect), key_(key) {}

template <typename Key>
RTree<Key>::Record::~Record() {}

}  // namespace math
}  // namespace cobalt

#endif  // COBALT_MATH_R_TREE_H_
