
#ifndef _JL_Box_H_
#define _JL_Box_H_

#include <stdlib.h>
#include <iostream.h>

#include "prim.h"
#include "vec4.h"
#include "bounds3d.h"

class Ray;

class Box : public Prim {

	private:
		enum BoxSide { _box_left, _box_right,
					   _box_bottom, _box_top,
					   _box_back, _box_front };
		Bounds3d _bounds;
	private:
		real	_x1, _y1, _z1, _x2, _y2, _z2;
		int		_last_intersection_side;

  inline int equal (real f1, real f2) const
  {
    real diff = f2 - f1;
    if ((diff > T_FUDGE) || (diff < -T_FUDGE)) return 0; 
    else return 1;
  }

	public: 
		Box();
		Box(real x1, real y1, real z1, real x2, real y2, real z2);
		Box(const Box &B) { CopyFrom(B); }
		virtual ~Box();

		virtual Prim* CopyPrim() const { return new Box(*this); }
		virtual const char* PrimName() const { return "Box"; }

		Box& CopyFrom(const Box&);
		Box& operator=(const Box &B) { return CopyFrom(B); }

//		friend ostream& operator<<(ostream&, const Box&);
//		friend istream& operator>>(istream&, Box&);

		virtual void Intersect(const Ray &ray, Hit &hit);
		virtual void IntersectCertain(const Ray &ray, Hit &hit);
		virtual void IntersectProbable(const Ray &ray, Hit &hit) {Intersect (ray, hit);}

		virtual int IntersectLinespace(const Ray &R1, const Ray &R2,
									   const Ray &R3, const Ray &R4,
									   const Vec4 &N1, const Vec4 &N2,
									   const Vec4 &N3, const Vec4 &N4);

//XXX this only works if normalatpoint is called right after the intersection. BAD!
		virtual void NormalAtPoint(const Vec4&, Vec4 &N) const {
				switch (_last_intersection_side) {
					case _box_left:		N.Set(-1, 0, 0); break;
					case _box_right:	N.Set(1, 0, 0);  break;
					case _box_bottom:	N.Set(0, -1, 0); break;
					case _box_top:		N.Set(0, 1, 0);  break;
					case _box_back:		N.Set(0, 0, -1); break;
					case _box_front:	N.Set(0, 0, 1);  break;
					default: cerr << "Error in Box::NormalAtPoint()" << endl;
							 exit(-1);
				}
			}


		virtual const Bounds3d &bbox (void) const {return _bounds;}

                virtual void calcST (const Vec4 &pt, real &s, real &t) const;

};

#endif
