#include "controler.h"
#include "camera.h"
#include "glview.h"
#include "scene.h"
#include "mainwindow.h"
#include <iostream>

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;
}

void Controler::addVolume()
{
    QString fn = QFileDialog::getOpenFileName(NULL, tr("Open Volume..."),
                                              QString("D:\\Projekte\\GraPa\\A3"), tr("Volume Files (*.raw )"));

    if(fn.isEmpty())
        return;
    qDebug()<<"Opening File:"<<fn;
    addVolume(fn);
}

void Controler::addVolume(QString filePath){


    QFile file(filePath);

    if(!file.open(QIODevice::ReadOnly)) {
        QMessageBox::information(0, "error", file.errorString());
    }

    QByteArray line1 = file.readLine();
    QTextStream l1(line1);
    QStringList line1Text = l1.readLine().split(" ");
    int x = line1Text[0].toInt();
    int y = line1Text[1].toInt();
    int z = line1Text[2].toInt();
    qDebug()<<line1Text<< x << y << z;


    QByteArray line2 = file.readLine();
    QTextStream l2(line2);
    QStringList line1Text2 = l2.readLine().split(" ");
    double dx = line1Text2[0].toDouble();
    double dy = line1Text2[1].toDouble();
    double dz = line1Text2[2].toDouble();
    qDebug()<<line1Text2<< dx <<dy << dz;


    QByteArray rawdata = file.readAll();
    //qDebug()<<rawdata;

    char ***data = new char**[z];

    int* histogram = new int[256];

    for(int i = 0; i < 256; i++)
    {
        histogram[i] = 0;
    }

    int count = 0;
    //  std::cout<<std::hex;
    int printLine = 400;// z/2;

    for(int k = 0; k < z; k++)
    {
        data[k] = new char*[y];
        for(int j = 0; j < y; j++)
        {

            data[k][j] = new char[x];
            for(int i = 0; i < x; i++)
            {
                uchar value = rawdata.at(count++);
                data[k][j][i] = value;
                histogram[value]++;

                if(k == printLine ){
                    int temp = value*9/256;
                    std::cout<<temp;
                }
            }
            if(k == printLine){
                std::cout<<std::endl;
            }
        }
    }

    char *copydata = new char[rawdata.length()];

    for(int i = 0; i < rawdata.length(); i++){
        copydata[i] = rawdata.at(i);
    }

    //qDebug()<<file.readData(data,file.size()-file.pos());
    int type = GL_UNSIGNED_BYTE;
    if(rawdata.size()>x*y*z)
        type = GL_UNSIGNED_SHORT;

    for(int i = 0; i < 4; i++)
        mainwindow->getViews()[i]->loadData(x,y,z,copydata,type);

    SceneVolume *volume = new SceneVolume(x,y,z,dx,dy,dz);

    scene->addSceneObjectTaActive(volume);

    file.close();

    uchar *trans = new uchar[4*256];

    for(int i = 0; i < 256; i+=1){
        int index = i*4;
        trans[index] = i;
        trans[index+1] = i;
        trans[index+2] = i;
        trans[index+3] = i;
    }

   for(int i = 0; i < 4; i++){
     //  mainwindow->getViews()[i]->loadTransfer(trans);
   }

   this->mainwindow->transEditor->setHistogram(histogram);
   // this->mainwindow->transEditor->setTransferFunction(trans);



    qDebug()<<"File Read finish";


}
