#include "BstmCamera.h"

namespace Brainstem
{
	CameraStatic::CameraStatic(IKernel* kernel, IDirect3DDevice9* device, float fov, float znear, float zfar, Vector3<float> target) 
		: Camera(kernel, device, fov, znear, zfar)
	{
		Target = target;
	}

	CameraStatic::~CameraStatic() { }

	void CameraStatic::Init()
	{ 
		Yaw = 0.0f;
		Pitch = 0.0f;

		Target = Vector3<float>(0.0f, 0.0f, 0.0f);
		AspectRatio = Kernel->GetWindowSize().Width / Kernel->GetWindowSize().Height;

		Update();
	}

	void CameraStatic::Update()
	{
		OldYaw = Yaw;
		OldPitch = Pitch;

		float timeDelta = Kernel->GetDeltaTime() / 1000.0f;

		Yaw = atan2(Position.X - Target.X, Position.Z - Target.Z);
		Pitch = atan2(Target.Y - Position.Y, sqrtf(pow(Position.X - Target.X, 2) + powf(Position.Z - Target.Z, 2)));

		Matrix4<float> cameraRotation;
		cameraRotation.SetRotationRadians(Vector3<float>(Pitch, Yaw, 0.0f));

		Vector3<float> cameraRotatedVector;
		cameraRotation.TransformVector(cameraRotatedVector, Velocity * timeDelta);

		Position += cameraRotatedVector;

		Velocity *= Vector3<float>(0, 0, 0);

		UpdateProjectionMatrix();
		UpdateViewMatrix();

		YawDelta = Yaw - OldYaw;
		PitchDelta = Pitch - OldPitch;

		UpdateFrustumPlanes();
	}

	void CameraStatic::UpdateViewMatrix()
	{
		Matrix4<float> cameraRotation;
		cameraRotation.SetRotationRadians(Vector3<float>(Pitch, Yaw, 0.0f));

		Vector3<float> cameraOriginalTarget = Vector3<float>(0, 0, -1);
		Vector3<float> cameraOriginalUpVec = Vector3<float>(0, 1, 0);

		Vector3<float> cameraRotatedTarget;
		cameraRotation.TransformVector(cameraRotatedTarget, cameraOriginalTarget);

		Vector3<float> cameraFinalTarget = Position + cameraRotatedTarget;

		Vector3<float> cameraRotatedUpVector;
		cameraRotation.TransformVector(cameraRotatedUpVector, cameraOriginalUpVec);

		Matrix4<float> LookAt;
		View = LookAt.CreateCameraLookAtMatrixLH(Position, cameraFinalTarget, cameraRotatedUpVector);
	}

	void CameraStatic::UpdateProjectionMatrix()
	{
		Matrix4<float> PerspFOV;
		Projection = PerspFOV.CreateProjectionMatrixPerspectiveFovLH(FOV, AspectRatio, zNear, zFar);
	}
}