#pragma once

#include "godot_cpp/classes/wrapped.hpp"
#include "godot_cpp/variant/packed_int32_array.hpp"
#include "godot_cpp/variant/packed_vector2_array.hpp"
#include "godot_cpp/variant/vector2.hpp"
#include "rtree.h"
#include <godot_cpp/classes/object.hpp>
#include <godot_cpp/classes/polygon2d.hpp>

using namespace godot;

template <class CoordType = float> struct RectTemplate {
  RectTemplate() {}

  RectTemplate(CoordType a_minX, CoordType a_minY, CoordType a_maxX,
               CoordType a_maxY) {
    min[0] = a_minX;
    min[1] = a_minY;

    max[0] = a_maxX;
    max[1] = a_maxY;
  }

  bool operator==(const RectTemplate &o) const {
    return min[0] == o.min[0] && min[1] == o.min[1] && max[0] == o.max[0] &&
           max[1] == o.max[1];
  }

  CoordType min[2];
  CoordType max[2];
};

// returns an index, accepts 2 dimension floats
typedef RTree<int, float, 2> RecTree;
typedef RectTemplate<float> Rect;

class RectangleTree : public Object {
  GDCLASS(RectangleTree, Object);

protected:
  RecTree tree;

  static void _bind_methods();

public:
  RectangleTree();

  void add(const Vector2 &min_bound, const Vector2 &max_bound,
           const int &polgon_index);
  void remove(const int &polygon_index);
  PackedInt32Array query(const Vector2 &point);
  PackedInt32Array nearest(const Vector2 &point, const int &number);
  PackedInt32Array query_rect(const Vector2 &min, const Vector2 &max);
};
