#ifndef _NUUOGLRENDERER_H_
#define _NUUOGLRENDERER_H_

#include <QGraphicsWidget>
#include <QMutex>
#include "qgl.h"
#ifdef WIN32
	#include <GL/glprocs.h> // OpenGL {1.2, 1.3, 1.4, 1.5} and extension functions
#elif defined(Q_OS_LINUX)
	#include <GL/glext.h>
#endif
#include "DisplaySetting.h"
#include "CameraViewMesh.h"

class NuuoGLRenderer : public QGraphicsWidget, public IDisplaySetting
{
    Q_OBJECT
public:
    NuuoGLRenderer(int nViews, QGraphicsItem* parent = NULL);
    ~NuuoGLRenderer();
    void    setTransientTick(int count);
    int     transientTick();
    void    setDisplayTick(int count);
    int     displayTick();
    int     viewCount();
  //void    OnImageArrival(int imageWidth, int imageHeight, int imageNumbytes, SysUtils::RefcntPointer<unsigned char> yuvbuf, int viewIndex = 0);
    void    OnImageArrival(int imageWidth, int imageHeight, int imageNumbytes, uchar* yuv, int viewIndex = 0);
    void    OnBGRArrival(int width, int height, int widthPerLine, uchar* pBuf, int viewIndex = 0);
    void    animate();
    void    play();
    void    pause();
    void    forward();
    void    backward();

	//////Snapshot Temp///////
	uchar* GetBuffer(int viewIdx){return m_ListCameraView[viewIdx].m_textureInfo.buf;}
	int    GetWidth(int viewIdx){return m_ListCameraView[viewIdx].m_textureInfo.iWidth;}
	int    GetHeight(int viewIdx){return m_ListCameraView[viewIdx].m_textureInfo.iHeight;}

    // IDisplaySetting
    void SetNumOfViews(int nViews);
    void SetupCameraViews(int viewIdx, float* TransMatrix, float* HomoMatrix);
    void EnableKeepAspectRatio(bool bEnable);
    void EnableKeepFieldOfView(bool bEnable){ m_bKeepFieldOfView = bEnable; }
    void SetViewRotate(double dHOffset, double dVOffset);
    void SetViewTranslate(double dHOffset, double dVOffset, bool boundaryCheck);
    void SetViewZoom(double dZoomOffset, bool boundaryCheck);
    void GetViewPosition(double* pPosX, double* pPosY);
    void GetZoomFactor(double* pdZoomFactor);
    void ResetViewPosition();
    void ResetViewMovement();
    void SetEyeRotation(double dHorizontal, double dVertical);
    void GetEyeRotation(double* pdHorizontal, double* pdVertical);
    void EnableOverview(bool bEnable){ m_bOverview = bEnable; }

    void ReleaseARB();
    void ResetRender();

protected:
    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget /* = 0 */);
    virtual void resizeEvent(QGraphicsSceneResizeEvent* event);
    //virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
    //virtual void wheelEvent(QGraphicsSceneWheelEvent *event);

signals:
    void InitARB();

private slots:
    void DoInitARB();

private:
    void SetPerspProjection(float fViewportW, float fViewPortH);
    void SetPerspProjection();
    void CheckBoundary();
    void CheckAspectRatio();

    void BindTexture(int viewIdx);

    typedef enum
    {
        LEFT2RIGHT = 1,
        RIGHT2LEFT,
    } DIRECTION;

    void      releaseTexture();
    void      drawQuads(int tick);
    bool      m_initARB, m_PlayOrPause, m_ForwardOrBackward, m_RGBorYUV;
    DIRECTION m_direction;
    int       m_nViews, m_transientTick, m_displayTick, m_period, m_tick;
    GLuint    m_program;
    qreal     m_depth;

    bool m_bPartialDisplay;
    int m_initViewportW;
    double m_dZoomFactor;
    bool m_bKeepAspectRatio;
    bool m_bKeepFieldOfView;    // whether the field of view can be changed when viewport size is changed or not.
    bool m_bOverview;
    float m_eyePosY;

    float m_eyeTransH;          //eye translation movement on X-axis
    float m_eyeTransV;          //eye translation movement on Y-axis

    float m_eyeRotateH;         //eye rotation angle degree about Y-axis
    float m_eyeRotateV;         //eye rotation angle degree about X-axis

    CCameraViewMesh* m_ListCameraView;
    Matrix4X4 m_projMatrix;

    QMutex m_BufferMutex;       // buffer access protection. 
                                // (the yuv buffer pointer will be access by 2 threads, main thread and decoding thread.)
};

#endif // end of _NUUOGLRENDERER_H_