// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.

#ifndef toolx_Qt_glarea
#define toolx_Qt_glarea

#include <QtCore/qglobal.h> //For QT_VERSION.

#if QT_VERSION < 0x060000
#include <QtOpenGL/qgl.h>
#else
#include <QtOpenGLWidgets/qopenglwidget.h>
#endif

#include <QtGui/qevent.h>

#include "gl_functions"

#include "../sg/GL_action"
#include "../sg/GL_viewer"

namespace toolx {
namespace sg {
  using GL_action = GL_action_T<toolx::Qt::gl_functions>;
  using GL_manager = GL_manager_T<toolx::Qt::gl_functions>;
  using GL_viewer = GL_viewer_T<GL_manager,GL_action>;
}}

#include <tools/sg/device_interactor>

namespace toolx {
namespace Qt {

class glarea
#if QT_VERSION < 0x060000
:public QGLWidget
#else
:public QOpenGLWidget
#endif
{
#if QT_VERSION < 0x060000
  typedef QGLWidget parent;
#else
  using parent = QOpenGLWidget;
#endif
  TOOLS_SCLASS(toolx::Qt::glarea)
public:
  virtual void initializeGL() {}
  virtual void paintGL() {
#if QT_VERSION < 0x050000
    m_viewer.set_size(width(),height());
#else
    m_viewer.set_size(devicePixelRatio()*width(),devicePixelRatio()*height());
#endif
    m_viewer.render();
  }

  virtual void keyPressEvent(QKeyEvent* a_event) {
    if(!m_interactor) return;
    tools::sg::key_down_event _event(convert_key(a_event->key()));
    m_interactor->key_press(_event);
  }
  virtual void keyReleaseEvent(QKeyEvent* a_event) {
    if(!m_interactor) return;
    tools::sg::key_up_event _event(convert_key(a_event->key()));
    m_interactor->key_release(_event);
  }
  virtual void mousePressEvent(QMouseEvent* a_event) {
    if(!m_interactor) return;

    bool shift_modifier = a_event->modifiers() & ::Qt::ShiftModifier;
    bool control_modifier = a_event->modifiers() & ::Qt::ControlModifier;

#if QT_VERSION < 0x060000
    tools::sg::mouse_down_event _event(a_event->x(),a_event->y(),shift_modifier,control_modifier);
#else
    tools::sg::mouse_down_event _event(a_event->position().x(),a_event->position().y(),shift_modifier,control_modifier);
#endif
    m_interactor->mouse_press(_event);
  }
  virtual void mouseReleaseEvent(QMouseEvent* a_event) {
    if(!m_interactor) return;

    bool shift_modifier = a_event->modifiers() & ::Qt::ShiftModifier;
    bool control_modifier = a_event->modifiers() & ::Qt::ControlModifier;

#if QT_VERSION < 0x060000
    tools::sg::mouse_up_event _event(a_event->x(),a_event->y(),shift_modifier,control_modifier);
#else
    tools::sg::mouse_up_event _event(a_event->position().x(),a_event->position().y(),shift_modifier,control_modifier);
#endif
    m_interactor->mouse_release(_event);
  }
  virtual void mouseMoveEvent(QMouseEvent* a_event) {
    if(!m_interactor) return;

    bool shift_modifier = a_event->modifiers() & ::Qt::ShiftModifier;
    bool control_modifier = a_event->modifiers() & ::Qt::ControlModifier;

#if QT_VERSION < 0x060000
    tools::sg::mouse_move_event _event(a_event->x(),a_event->y(),shift_modifier,control_modifier,0,0,false);
#else
    tools::sg::mouse_move_event _event(a_event->position().x(),a_event->position().y(),shift_modifier,control_modifier,0,0,false);
#endif
    m_interactor->mouse_move(_event);
  }
  virtual void wheelEvent(QWheelEvent* a_event) {
    if(!m_interactor) return;

    bool shift_modifier = a_event->modifiers() & ::Qt::ShiftModifier;
    bool control_modifier = a_event->modifiers() & ::Qt::ControlModifier;

#if QT_VERSION < 0x050f00  //5.15.00
    tools::sg::wheel_rotate_event _event(a_event->angleDelta().y(),a_event->x(),a_event->y(),shift_modifier,control_modifier);
#else
    tools::sg::wheel_rotate_event _event(a_event->angleDelta().y(),a_event->position().x(),a_event->position().y(),shift_modifier,control_modifier);
#endif
    m_interactor->wheel_rotate(_event);
  }

public:
  glarea(QWidget* a_parent,toolx::sg::GL_viewer& a_viewer):parent(a_parent),m_viewer(a_viewer),m_interactor(0){
  }
  virtual ~glarea(){
  }
public:
  void set_device_interactor(tools::sg::device_interactor* a_interactor) {m_interactor = a_interactor;} //we do not have ownership.
protected:
  tools::key_code convert_key(/*Qt::Key*/int a_key) {return a_key;}
protected:
  toolx::sg::GL_viewer& m_viewer;
  tools::sg::device_interactor* m_interactor;
};

}}

#endif
