#include "sceneview.h"
using namespace std;


SceneView::SceneView(QWidget *parent) :
    QWidget(parent)
{
    this->setFocusPolicy(Qt::StrongFocus);
    scene = NULL;
}


SceneView::~SceneView()
{
    if(scene != NULL)
        delete scene;
}


void SceneView::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);

    //painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::black);

    if(scene != NULL)
        camera.Render(scene, &painter);
}


void SceneView::keyPressEvent(QKeyEvent * event)
{
    Qt::KeyboardModifiers modifiers = event->modifiers();
    bool Shift = modifiers & Qt::ShiftModifier;

    switch (event->key())
    {
        case Qt::Key_Q:       camera.TurnLeft(3);                 break;
        case Qt::Key_E:       camera.TurnRight(3);                break;
        case Qt::Key_R:       camera.PanUp(3);                    break;
        case Qt::Key_F:       camera.PanDown(3);                  break;
        case Qt::Key_Space:
        case Qt::Key_PageUp:  camera.MoveUp(200);                 break;
        case Qt::Key_PageDown:
        case Qt::Key_Control: camera.MoveDown(200);               break;
        case Qt::Key_W:       camera.MoveForward(600+600*Shift);  break;
        case Qt::Key_S:       camera.MoveBackward(600+600*Shift); break;
        case Qt::Key_A:       camera.StrafeLeft(400+400*Shift);   break;
        case Qt::Key_D:       camera.StrafeRight(400+400*Shift);  break;
    }

    this->update();
}


int GrabbedMouseX = -1;
int GrabbedMouseY = -1;

void SceneView::mousePressEvent(QMouseEvent * event)
{
    this->grabMouse();
    this->cursor().setShape(Qt::BlankCursor);
    GrabbedMouseX = event->x();
    GrabbedMouseY = event->y();
}

void SceneView::mouseReleaseEvent(QMouseEvent *)
{
    this->releaseMouse();
    this->cursor().setShape(Qt::ArrowCursor);
    GrabbedMouseX = -1;
    GrabbedMouseY = -1;
}

void SceneView::mouseMoveEvent(QMouseEvent * event)
{
    if(GrabbedMouseX >= 0)
    {
        static double Sensitivity = 0.1;
        camera.TurnRight(Sensitivity * (event->x() - GrabbedMouseX));
        camera.PanDown(Sensitivity * (event->y() - GrabbedMouseY));
        GrabbedMouseX = event->x();
        GrabbedMouseY = event->y();
        this->update();
    }
}


void SceneView::wheelEvent(QWheelEvent *event)
{
    camera.ZoomIn(100 * event->delta());
    this->update();
}
