
#ifndef SPECTRE_SCENE_CAMERA2D_H
#define SPECTRE_SCENE_CAMERA2D_H


#include "ICamera.h"
#include <Spectre/Math/Transform.h>

// 2D camera implementation.

// TODO: Support unprojection, from Screenspace -> Worldspace.

// TODO: Zoom is implemented using a scale matrix. 
// It's abit weird to control. Must be a better solution.

class Camera2D : public ICamera
{
public :
	Camera2D();
	Camera2D(const Vector2f& position, const Vector2f& size);

	void reset(const Vector2f& position, const Vector2f& size);

	// Position

	void setPosition(float x, float y);
	void setPosition(const Vector2f& position);
	const Vector2f& getPosition() const;

	void move(float x, float y);
	void move(const Vector2f& vec);
	
	void moveUp(float delta);
	void moveRight(float delta);

	// Size

	void setSize(unsigned int w, unsigned int h);
	void setSize(const Vector2u& size);
	const Vector2u& getSize() const;

	// Zoom

	void setZoom(float factor);
	void zoom(float factor);

	// Rotation

	void setRotation(float angle);
	void rotate(float delta);

	float getRotation() const;

	// Current view matrix.
	const Matrix4f& getViewMatrix() const;

	const Matrix4f& getProjectionMatrix() const;

	const Matrix4f& getProjectionViewMatrix() const;

	const Transform& getTransform() const;

protected :

	Vector2f	m_position;
	float		m_rotation;
	float		m_zoom;

	Vector2u	m_size;

	// View matrix. should transform world <-> eye space.
	mutable Transform	m_view;
	mutable bool		m_viewNeedsUpdate;

	// Projection matrix. transforms eye -> Clipping space.
	mutable Matrix4f	m_proj;
	mutable bool		m_projNeedsUpdate;

	mutable Matrix4f	m_projView;
	mutable bool		m_projViewNeedsUpdate;
};

#endif /* SPECTRE_SCENE_CAMERA2D_H */