#include <vector>
#include <cmath>
#include <cstdio>


template <typename T>
class Flags
{
public:
  Flags(T val) : value((int)val) {}
  operator T()
  {
    return (T)value;
  }
  inline Flags<T>& operator|=(T val)
  {
    value |= (int)val;
    return *this;
  }
  int value;
};


class Quadtree;
class SpatialObject // : public Object
{
public:
  // delete constructor except via a Quadtree
  ~SpatialObject() { parent->removeItem(this); }

  //Property<vec3f> position; // set position -> move
  vec3f position() { return pos; }
  void setPosition(vec3f p) { parent->moveItem(pos, p); p = pos; }

private:
  vec3f      pos;
  Quadtree*  parent;
};


class Quadtree
{
public:
  Quadtree(float resolution = 1.0f);
  ~Quadtree();

  SpatialObject* createObject(float x, float y); // adds it

private:
  class QuadtreeImpl;
  QuadtreeImpl* d;

  // probably needs to be a shared_ptr or may be a way to remove it from the quadtree when it is destroyed
  void addItem(std::shared_ptr<SpatialObject> item, float x, float y);
  void removeItem(std::shared_ptr<SpatialObject> item, float x, float y); // need to quickly test the item belongs to the quadtree
  void moveItem(std::shared_ptr<SpatialObject> item, float oldX, float oldY, float newX, float newY);
};



