
#ifndef _JL_Indexed_Polygon_H_
#define _JL_Indexed_Polygon_H_

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

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

class Ray;
class Vertex;

// SJT: cache for st texture lookup
#define STCACHE 1

// _v4 == NULL: triangle
// _v4 != NULL: quad

class Indexed_Polygon : public Prim {

	private:
                Vertex                 *_v1, *_v2, *_v3, *_v4;
		Vec4			_normal;
		float			_d;						// ax + by + cz + d = 0;
                Bounds3d _bounds;
		int				_max_norm;				// 0:x, 1:y, 2:z
#if STCACHE
                float                   texS, texT;
#endif
  
                float                    _obj_to_bbox_area;
protected:
  virtual void DrawFilled (void) const;
  virtual void DrawWF (void) const;
public: 
		Indexed_Polygon();
		Indexed_Polygon(Vertex *v1, Vertex *v2, Vertex *v3, Vertex *v4 = NULL);
		Indexed_Polygon(const Indexed_Polygon &S) { CopyFrom(S); }
		virtual ~Indexed_Polygon();

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

		Indexed_Polygon& CopyFrom(const Indexed_Polygon&);
		Indexed_Polygon& operator=(const Indexed_Polygon &S)
				{ return CopyFrom(S); }

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

		virtual void Intersect(const Ray &ray, Hit &hit);
		virtual void IntersectProbable(const Ray &ray, Hit &hit);
		virtual void IntersectCertain(const Ray &ray, Hit &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);

		virtual void NormalAtPoint(const Vec4&, Vec4 &N) const
				{ N = _normal; }

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

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

};

#endif
