#include "controler.h"
#include "camera.h"
#include "glview.h"
#include "scene.h"
#include "mainwindow.h"

Controler::Controler(MainWindow *mainwindow,Scene *scene)
{
    this->mainwindow = mainwindow;
    this->scene = scene;
    viewMode = CAMERA;
}

void Controler::mousePressed(GLView* view, QMouseEvent *event)
{
    activeView = view;
    mainwindow->setActiveView(view);

    lastSpeherePos = trackballPoint(event->pos().x(),event->pos().y());
    lastScreenPos = new QPointF(event->screenPos());
    event->accept();
}


void Controler::mouseMoveEvent(GLView* view, QMouseEvent *event)
{
    if(activeView != view)
            qDebug()<<"Active view Change";

    if (event->buttons() & Qt::LeftButton) {
        rotate(trackballPoint(event->pos().x(),event->pos().y()));
        event->accept();
    } else  if (event->buttons() & Qt::RightButton) {
        move(new QPointF(event->screenPos()));
        event->accept();
    }
}

 void Controler::wheelEvent(GLView* view, QWheelEvent *event ) {
     activeView = view;
     mainwindow->setActiveView(view);

     bool ctrlPressed = QApplication::keyboardModifiers() & Qt::ControlModifier;

     QVector3D vec;
     if(event->delta()<0)
         vec = QVector3D(0.0,0.0,1.0);
     else
         vec = QVector3D(0.0,0.0,-1.0);

     if((viewMode == CAMERA) ^ ctrlPressed){
         activeView->getCamera()->move(vec);
     } else if((viewMode == EDIT) ^ ctrlPressed){
        vec = activeView->getCamera()->rotation->conjugate().rotatedVector(vec);
        scene->moveActive(vec);
     } else{
         qDebug()<<"möp"<<viewMode<<" "<<CAMERA<<" "<<EDIT;
     }

     mainwindow->updateGL();
 }


QVector3D* Controler::trackballPoint(int x, int y){
    float xo,yo,zo;

    // qDebug()<<"x:"<< x << " y:"<<y;
    xo = ((2.0*x)-activeView->width())/ activeView->height();
    yo = (activeView->height()-(2.0*y))/activeView->width();

    float d = sqrt(xo*xo+yo*yo);
    zo = qMax(qCos(M_PI_2*d),qreal(0.0)); //qMin(d,1.0f)

    QVector3D *pos = new QVector3D(xo,yo,zo);
    pos->normalize();
    //  qDebug()<<"x:"<< xo << " y:"<<yo<<" z:"<<zo;
    return pos;
}

void Controler::rotate(QVector3D *newPos )
{
    QVector3D axis = QVector3D::crossProduct(*lastSpeherePos,*newPos);

    float angle = 180 / M_PI * asin(sqrt(QVector3D::dotProduct(axis, axis)));
    axis.normalize();

    //axis = rotation->conjugate().rotatedVector(axis);
    bool ctrlPressed = QApplication::keyboardModifiers() & Qt::ControlModifier;
    if((viewMode == CAMERA) ^ ctrlPressed){
        activeView->getCamera()->rotate(QQuaternion::fromAxisAndAngle(axis, angle));
    } else if((viewMode == EDIT) ^ ctrlPressed){
        scene->rotateActive(QQuaternion::fromAxisAndAngle(axis, angle));
    } else{
        qDebug()<<"möp"<<viewMode<<" "<<CAMERA<<" "<<EDIT;
    }

    lastSpeherePos = newPos;
    mainwindow->updateGL();

}

void Controler::move(QPointF * newPos){
    QPointF dt = *newPos;
    dt -= *lastScreenPos;
    dt *= 0.01f;

    float dx = dt.x();
    float dy = dt.y()*-1.0;

    bool ctrlPressed = QApplication::keyboardModifiers() & Qt::ControlModifier;
    if((viewMode == CAMERA) ^ ctrlPressed){
        activeView->getCamera()->move(QVector3D(dx,dy,0.0));
    } else if((viewMode == EDIT) ^ ctrlPressed){
       QVector3D vec = activeView->getCamera()->rotation->conjugate().rotatedVector(QVector3D(dx,dy,0.0));
       scene->moveActive(vec);
    } else{
        qDebug()<<"möp"<<viewMode<<" "<<CAMERA<<" "<<EDIT;
    }

    lastScreenPos = newPos;
    mainwindow->updateGL();
}

void Controler::setCamMode(){
    viewMode = CAMERA;
}

void Controler::setEditMode(){
    viewMode = EDIT;
}
