#ifndef _BOUNDS_LOG_H
#define _BOUNDS_LOG_H

#ifdef DISABLE_BOUNDS_LOG
#define BOUNDSLOG(event, entry)
#else
#define BOUNDSLOG(event, entry) LOG(BOUNDS_LOG_ON, event,entry)
#endif

class BoundsIntersect_Start_Entry {
public:
  Bounds3d _box;
  Vec4 _R, _D;

  BoundsIntersect_Start_Entry (const Bounds3d &box, const Vec4 &R, const Vec4 &D) : _box (box), _R(R), _D(D) {}
};

class BoundsWhereLeft_Start_Entry : public BoundsIntersect_Start_Entry {
public:
  BoundsWhereLeft_Start_Entry (const Bounds3d &box, const Vec4 &R, const Vec4 &D) : BoundsIntersect_Start_Entry (box, R, D) {}
};

class BoundsIntersect_Face_Project_Entry {
public:
  float _t, _bestt;
  int _dir, _bestdir;
  int _axis, _bestaxis;

  BoundsIntersect_Face_Project_Entry (int axis, int dir, float t, int bestaxis, int bestdir, float tbest) : _t (t), _dir (dir), _axis (axis), _bestaxis (bestaxis), _bestdir (bestdir), _bestt (tbest) {}
};

class BoundsWhereLeft_Face_Project_Entry : public BoundsIntersect_Face_Project_Entry {
public:
  BoundsWhereLeft_Face_Project_Entry (int axis, int dir, float t, int bestaxis, int bestdir, float tbest) : BoundsIntersect_Face_Project_Entry (axis, dir, t, bestaxis, bestdir, tbest) {}
};

class BoundsWhereLeft_End_Entry {
public:
  int _face, _dir;
  Vec4 _leftpt;
  int _did_leftpt;

  BoundsWhereLeft_End_Entry (int face, int dir, Vec4 *leftpt) : _face (face), _dir (dir) {if (leftpt) {_leftpt = *leftpt; _did_leftpt = 1;} else _did_leftpt = 0;}
};

class BoundsWhereEntered_Start_Entry : public BoundsIntersect_Start_Entry {
public:
  BoundsWhereEntered_Start_Entry (const Bounds3d &box, const Vec4 &R, const Vec4 &D) : BoundsIntersect_Start_Entry (box, R, D) {}
};

class BoundsWhereEntered_Face_Project_Entry : public BoundsIntersect_Face_Project_Entry {
public:
  float _tfar, _tbestfar;

  BoundsWhereEntered_Face_Project_Entry (int axis, int dir, float tnear, float tfar, int bestaxis, int bestdir, float tbestnear, float tbestfar) : BoundsIntersect_Face_Project_Entry (axis, dir, tnear, bestaxis, bestdir, tbestnear), _tfar (tfar), _tbestfar (tbestfar) {}
};

enum WhyWhereEnteredEnd {Missed, Behind, FoundHit};
class BoundsWhereEntered_End_Entry {
public:
  WhyWhereEnteredEnd _why;
  int _face, _dir;
  Vec4 _enterpt;
  int _did_enterpt;

  BoundsWhereEntered_End_Entry (WhyWhereEnteredEnd why, int face, int dir, Vec4 *enterpt) : _why (why), _face (face), _dir (dir) {if (enterpt) {_enterpt = *enterpt; _did_enterpt = 1;} else _did_enterpt = 0;}
};

class BoundsIncludesPt_Start_Entry {
public:
  Bounds3d _box;
  Vec4 _pt;

  BoundsIncludesPt_Start_Entry (const Bounds3d &box, const Vec4 &pt) :_box (box), _pt (pt) {};
};

class BoundsIncludesPt_Face_Check_Entry {
public:
  Bounds3d _box;
  Vec4 _pt;
  int _face, _dir, _in;
  
  BoundsIncludesPt_Face_Check_Entry (const Bounds3d &box, const Vec4 &pt, int face, int dir, int in) : _box (box), _pt (pt), 
    _face (face), _dir (dir), _in(in) {
  };
};


#endif

