#ifndef __Camera__
#define __Camera__

#ifndef CORE_DLL 
    #ifdef CORE_BUILD
	    #define CORE_DLL __declspec(dllexport)
    #else
	    #define CORE_DLL __declspec(dllimport)
        #pragma comment(lib, "Core.lib")
    #endif
#endif

#include "../../Core/mathlib.h"
#include "../../Core/Observer.h"
#include "Group.h"
#include "RenderTarget.h"
#include "DepthStencilBuffer.h"


class CORE_DLL Camera : public Group, public Observable {
public:
    enum Projection {
        IDENTITY, ORTHO2D, ORTHOGRAPHIC, PERSPECTIVE
    };

    enum RenderTargetImplementation {
        TEXTURE,
        FRAMEBUFFER
    };

    Camera();
    virtual ~Camera();

    const Matrix4& getView();
    const Matrix4& getProjection();

    void setViewIdentity();
    void setView(const Vector3& eye, const Vector3& center, const Vector3& up);

    void setProjectionIdentity();
    void setOrtho2DProjection(int width, int height);
    void setOrthographicProjection(int width, int height, float zNear, float zFar);
    void setPerspectiveProjection(int width, int height, float fov, float zNear, float zFar);

    void updateProjection(int width, int height);

    const Vector3& getEye();
    const Vector3& getCenter();
    const Vector3& getUp();

    void setRenderTargetImplementation(RenderTargetImplementation renderTargetImplementation);
    RenderTargetImplementation getRenderTargetImplementation();

    void attachInput(RenderTarget* renderTarget, size_t index);
    void attachOutput(RenderTarget* renderTarget, size_t index);

    void attachDepthStencilBuffer(DepthStencilBuffer* depthStencilBuffer);

    RenderTarget** getInputBuffers();
    RenderTarget** getOutputBuffers();

    DepthStencilBuffer* getDepthStencilBuffer();
    
protected:
    Vector3 _eye, _center, _up;
    Matrix4 _view, _projection;

    Projection _projectionType;
    int _width, _height;
    float _fov, _zNear, _zFar;

    RenderTargetImplementation _renderTargetImplementation;
    RenderTarget* _input[16];
    RenderTarget* _output[16];
    DepthStencilBuffer* _depthStencilBuffer;
};

#endif