/*******************************************************************************
* Copyright 2003-2020 Intel Corporation.
*
* This software and the related documents are Intel copyrighted  materials,  and
* your use of  them is  governed by the  express license  under which  they were
* provided to you (License).  Unless the License provides otherwise, you may not
* use, modify, copy, publish, distribute,  disclose or transmit this software or
* the related documents without Intel's prior written permission.
*
* This software and the related documents  are provided as  is,  with no express
* or implied  warranties,  other  than those  that are  expressly stated  in the
* License.
*******************************************************************************/

#if !defined(__MIC__)

#ifndef __BASE_RENDERER_H__
#define __BASE_RENDERER_H__

#include "base.h"
#include "base_image.h"
#include "base_window.h"
#include "vm_thread.h"

class BaseRenderer
{
public:
    BaseRenderer(void) {};
    virtual ~BaseRenderer(void) {};

    virtual Status Init(RendererContext *pContext) = 0;

    virtual Status Close() = 0;

    virtual Status InitForThread() = 0;

    virtual void   SetViewport(Rect rect) = 0;

    virtual Rect   ScaleViewRect(Rect rect) = 0;

    virtual Status DrawImage(Image *pFrame, bool bForce, Rect rect = Rect()) = 0;

    virtual Status SwapBuffers() = 0;
};

#ifdef ENABLE_RENDERING

#if defined _WIN32
#include <GL/gl.h>
#else
#include <GL/glx.h>
#endif

class Textures
{
public:
    Textures();
    ~Textures();
    void Release();
    void Generate(GLsizei num);

    GLuint *m_pTextures;
    GLsizei m_texNum;
};

class RendererOpenGL : public BaseRenderer
{
public:
    RendererOpenGL(void);
    virtual ~RendererOpenGL(void);

    Status Init(RendererContext *pContext);

    Status Close();

    Status InitForThread();

    void   SetViewport(Rect rect);

    Rect   ScaleViewRect(Rect rect);

    Status DrawImage(Image *pFrame, bool bForce, Rect rect = Rect());

    Status SwapBuffers();

protected:
#if defined _WIN32
    HDC         m_wdc;
    HGLRC       m_glContext;
    HWND        m_hWnd;
#else
    GLXContext   m_glContext;
    Display*     m_display;
    Window       m_window;
    XVisualInfo* m_pvisinfo;
    unsigned int m_iScreen;
#endif

    Image        m_template;
    Rect         m_rectPrev;
    bool         m_bInitialized;
    bool         m_bKeepAspect;

    Textures m_imageTiles;
    Size     m_texTile;
};

#endif

/*
// Window helpers
*/
#define WF_FIT_TO_IMAGE 0x0001

class WindowDraw
{
public:
    WindowDraw();
    WindowDraw(const char* name, unsigned int flags = 0);
    ~WindowDraw();

    bool     Create(const char* name, unsigned int flags = 0);
    void     Close();

    Status   DrawImage(Image *name, bool bForce = false, bool bDelayed = false);

    Status   SwapBuffers();
    bool     IsClosed();
    bool     IsInvalidated();
    int      CheckKey();
    int      WaitKey();
    Status   WaitQuit();
    void     ProcWindow();

    Point    GetMouseCoordinates();

    inline bool IsInitialized() {return m_bInitialized;}

    WindowBase      *m_pWndClass;
    BaseRenderer    *m_pRenClass;
    DString          m_wndName;

    int                 m_wndStyle;
    vm_thread           m_wndProcThread;
    vm_event            m_wndInited;
    volatile bool       m_bKillWndThread;

    bool                m_bFirstFrame;

    unsigned int        m_flags;

    bool m_bInitialized;

private:
    WindowDraw(WindowDraw&) {};
    WindowDraw& operator = (const WindowDraw&) { return *this; };

    void reset();
};

#endif

#endif      // __MIC__
