
#ifndef _JL_Sphere_H_
#define _JL_Sphere_H_

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

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

class Ray;

class Sphere : public Prim {

	private:
		Vec4	_center;
		float	_r, _r2;
		Bounds3d _bounds;

                void CalcBounds (void) {_bounds.Set (_center.x() - _r,  _center.x() + _r, _center.y() - _r, _center.y() + _r, _center.z() - _r, _center.z() + _r);       }

		virtual void DrawFilled (void) const;
	public: 
		Sphere();
		Sphere(const Vec4 &v, float r);
		Sphere(const Sphere &S) { CopyFrom(S); }
		virtual ~Sphere();

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

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

		friend ostream& operator<<(ostream&, const Sphere&);
//		friend istream& operator>>(istream&, Sphere&);
		virtual void Output(ostream &co) const { co << *this; }

		virtual void Intersect(const Ray &ray, Hit &hit);
		virtual void IntersectCertain(const Ray &ray, Hit &hit);
		virtual void IntersectProbable(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 &P, Vec4 &N) const {
				Vec4FastSub(N, P, _center);
				N /= _r;
			}

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

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

};

#endif
