#include "mainwidget.h"

MainWidget::MainWidget()
{

}

QSize MainWidget::minimumSizeHint() const
{
    return QSize(50, 50);
}

QSize MainWidget::sizeHint() const
{
    return QSize(1280, 720);
}

void MainWidget::wheelEvent(QWheelEvent *event )
{

    if(event->delta()<0)
        camDistance -=10.0;
    else
        camDistance +=10.0;

    m_view.setToIdentity();
    m_view.lookAt(QVector3D(0.0,camDistance,camDistance),QVector3D(0.0,0.0,0.0),QVector3D(0.0,1.0,0.0));

}


void MainWidget::initializeGL(){
    bool glFunctionsOK = initializeOpenGLFunctions();
    //Q_ASSERT(glFunctionsOK);
    if(!glFunctionsOK){
        qDebug()<<"ContextFormat"<<this->context()->format();
        exit(4);
    }

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    // Shader
    animationShader = initShader(QLatin1String(":/animate.frag"),QLatin1String(":/animate.vert"));

    camDistance = 30.0;
    m_view = QMatrix4x4();
    m_view.lookAt(QVector3D(0.0,camDistance,camDistance),QVector3D(0.0,0.0,0.0),QVector3D(0.0,1.0,0.0));

    loadNewMesh();
}

void MainWidget::loadNewMesh(){
    QString fn = QFileDialog::getOpenFileName(NULL, tr("Open Mesh..."),
                                              QString("D:\\Projekte\\GraPa\\A5\\Models"),
                                              tr("*.md5mesh *.3ds *.md2 *.obj" ));

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

    mesh = new Mesh(this,fn);
}

QOpenGLShaderProgram* MainWidget::initShader(QString fragSource, QString vertSource){

    QOpenGLShader *vert = new QOpenGLShader(QOpenGLShader::Vertex);
    if(!vert->compileSourceFile(vertSource)){
        qCritical()<< "Fragment Shader"<<vertSource<<"failed"<< vert->log();
        exit(5);
    }

    QOpenGLShader *frag = new QOpenGLShader(QOpenGLShader::Fragment);
    if(!frag->compileSourceFile(fragSource)){
        qCritical()<< "Fragment Shader"<<fragSource<<"failed"<< frag->log();
        exit(5);
    }

    QOpenGLShaderProgram* shader = new QOpenGLShaderProgram();
    shader->addShader(vert);
    shader->addShader(frag);
    if(!shader->link()){
        qCritical()<< "Linking shader failed:"<<shader->log();
        exit(5);
    }


    return shader;

}


void MainWidget::paintGL(){
    glViewport(0,0,width(),height());

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    QMatrix4x4 rot;
    int time = QTime::currentTime().second()*1000+QTime::currentTime().msec();
    rot.rotate(time/100.0*36/5,QVector3D(0,1,0));

    animationShader->bind();
    animationShader->setUniformValue("colorTexture",0);
    animationShader->setUniformValue("LightPos",QVector3D(0,100,100));

    mesh->render(animationShader,m_view*rot, m_projection);

    animationShader->release();
    update();
}

void MainWidget::resizeGL(int width, int height){
    qDebug()<<"Resize"<<width<<height;

    m_projection = QMatrix4x4();
    m_projection.perspective(45.0f,1.0*width/height,0.01f,1000.0f);


}

