#ifndef PERSPECTIVECAMERA_HXX
#define PERSPECTIVECAMERA_HXX

#include "Camera.hxx"

class PerspectiveCamera : public Camera
{
	// input values
	Vec3f pos,dir,up;
	float angle;
  
	// preprocessed values
	float focus;
	Vec3f xAxis,yAxis,zAxis;
	float aspect;
public:
	PerspectiveCamera(Vec3f pos,Vec3f dir,Vec3f up,
		          float angle,
		          int resX, int resY
		         )
		: Camera(resX,resY),pos(pos),dir(dir),up(up),angle(angle)
	{
		focus  = static_cast<float>(resY) / (tan(angle * M_PI / 360) * 2.0);
		aspect = static_cast<float>(resX) / static_cast<float>(resY);

		Normalize(up);
		Normalize(dir);

		// Axis precomputation. Z contains all further precomputations,
		// including that rays are shot through the middle of the pixels
		// ("+1")
		xAxis = Cross(-up, dir);
		yAxis = Cross(xAxis, dir);
		zAxis = focus * dir - (xAxis * (resX - 1.0) + yAxis * (resY - 1.0)) / 2.0;
	}

	virtual ~PerspectiveCamera(){};

	virtual bool InitRay(float x, float y, Ray &ray)
	{
		ray.org = pos;
		ray.dir = xAxis * x + yAxis * y + zAxis;
		ray.t   = Infinity;
		ray.hit = NULL;

		// Normalize the ray direction
		Normalize(ray.dir);

		return true;
	};
};
#endif
