#pragma once

#ifndef __gx_gamecamera_h__
	#define __gx_gamecamera_h__

#include "foundation.h"
#include "foundation/PxMat44.h"
#include "foundation/PxTransform.h"

using namespace physx;

namespace Gx
{
	// prosta klasa kamery oparta o klase PxTransform = wektor + kwaternion
	class GX_API GameCamera
	{
	public:
		GameCamera();

		// przenosi kamere na podana pozycje w kierunku target
		void lookAt(const PxVec3& position, const PxVec3& target);

		//
		void lookAt(const PxVec3& target);

		// przenosi kamere do przodu lub tylu
		void walk(GxF32 direction, GxF32 amount);

		// przenosi kamere w lewo lub w prawo
		void strafe(GxF32 direction, GxF32 amount);

		// przenosi kamere do gory lub na dol
		void fly(GxF32 direction, GxF32 amount);

		// przenosi kamere w zadanym kierunku
		void move(const PxVec3& direction, const PxVec3& amount);

		// obraca kamere wokol globalnej osi Y (rozgladanie sie w lewo w prawo)
		void yaw(GxF32 angle);

		// obraca kamere wokol lokalnej osi X (rozgladanie sie do gory na dol)
		void pitch(GxF32 angle);

		// obraca kamere wokol lokalnej osi Z (przechylanie sie w lewo w prawo)
		void roll(GxF32 angle);

		// obraca kamere
		void rotate(GxF32 yawAngle, GxF32 pitchAngle, GxF32 rollAngle = GxF32(0));

		void rotate(const PxQuat& q) {
			m_transform.q *= q;
		}

		PxTransform getTransform() const {
			return m_transform;
		}

		PxMat44 getViewMatrix() const {
			return PxMat44(m_transform.getInverse());
		}

		PxVec3 getPosition() const {
			return m_transform.p;
		}

		PxVec3 getViewDir() const {
			return m_dir;
		}

		void setPosition(const PxVec3& p) {
			m_transform.p = p;
		}

		void setTransform(const PxTransform& t);

	private:
		mutable PxVec3 m_dir;
		mutable PxVec3 m_right;
		mutable PxTransform m_transform;
	};
}

#endif /* __gx_gamecamera_h__ */