#include "mainwindow.h"
#include <treedelegate.h>


void MainWindow::initViews()
{
    QGLFormat glFormat;
    glFormat.setVersion( 4, 4 );
    glFormat.setProfile( QGLFormat::CoreProfile ); // Requires >=Qt-4.8.0

    Camera *perspectiveCam = new Camera(true);
    perspectiveView = new GLView(scene,perspectiveCam,controler,glFormat);

    Camera *frontCam = new Camera(false);
    frontCam->setHome(new QQuaternion(), new QVector3D(0.0,0.0,-4.0));
    frontView = new GLView(scene,frontCam,controler,glFormat);


    Camera *leftCam = new Camera(false);
    leftCam->setHome(new QQuaternion(QQuaternion::fromAxisAndAngle(0.0,1.0,0.0,90.0).toVector4D()),
                     new QVector3D(0.0,0.0,-4.0));
    leftView = new GLView(scene,leftCam,controler,glFormat);

    Camera *topCam = new Camera(false);
    topCam->setHome(new QQuaternion(QQuaternion::fromAxisAndAngle(1.0,0.0,0.0,90.0).toVector4D()),
                    new QVector3D(0.0,0.0,-4.0));
    topView = new GLView(scene,topCam,controler,glFormat);

    views = new GLView*[4];
    views[0] = perspectiveView;
    views[1] = frontView;
    views[2] = leftView;
    views[3] = topView;


}

void MainWindow::initSplits()
{
    viewGoup = new QActionGroup(this);
    viewMenu = new QMenu("View",this);

    topSplit = new QSplitter(Qt::Horizontal,this);
    bottomSplit = new QSplitter(Qt::Horizontal,this);
    verticalSplit = new QSplitter(Qt::Vertical,this);

    topSplit->addWidget(perspectiveView);
    topSplit->addWidget(frontView);

    bottomSplit->addWidget(leftView);
    bottomSplit->addWidget(topView);

    verticalSplit->addWidget(topSplit);
    verticalSplit->addWidget(bottomSplit);

    setCentralWidget(verticalSplit);

    showQuad();
    //

    //View Actions
    singleView = new QAction("Single View",this);
    singleView->setShortcut(QKeySequence("1"));
    singleView->setCheckable(true);

    singleView->setIcon(QIcon(":/img/view-single.png"));
    connect(singleView, SIGNAL(triggered()), this, SLOT(showSingle()));
    viewGoup->addAction(singleView);

    dualView = new QAction("Dual View",this);
    dualView->setShortcut(QKeySequence("2"));
    dualView->setCheckable(true);
    dualView->setIcon(QIcon(":/img/view-dual.png"));
    connect(dualView, SIGNAL(triggered()), this, SLOT(showDual()));
    viewGoup->addAction(dualView);

    quadView = new QAction("Quad View",this);
    quadView->setShortcut(QKeySequence("4"));
    quadView->setCheckable(true);
    quadView->setChecked(true);
    quadView->setIcon(QIcon(":/img/viewports.png"));

    connect(quadView, SIGNAL(triggered()), this, SLOT(showQuad()));
    viewGoup->addAction(quadView);

    viewMenu->addAction(singleView);
    viewMenu->addAction(dualView);
    viewMenu->addAction(quadView);
}

void MainWindow::initToolbar()
{
    toolBar->addAction(cameraMode);
    toolBar->addAction(editMode);

    toolBar->addSeparator();
    toolBar->addAction(camHome);
    toolBar->addAction(landscapeAdd);
    toolBar->addSeparator();

    toolBar->addWidget(showGridButton);
    toolBar->addWidget(gridSizeInput);
    toolBar->addWidget(gridStepInput);
    toolBar->addWidget(MIPButton);

    toolBar->addSeparator();


    QToolButton* toolButton = new QToolButton();
    toolButton->setIcon(QIcon(":/img/viewports.png"));
    toolButton->setMenu(viewMenu);
    toolButton->setPopupMode(QToolButton::InstantPopup);
    QWidgetAction* toolButtonAction = new QWidgetAction(this);
    toolButtonAction->setDefaultWidget(toolButton);
    toolBar->addAction(toolButtonAction);


    QToolButton* primitives = new QToolButton();
    primitives->setIcon(QIcon(":/img/box.png"));
    primitives->setMenu(primitivesMenu);
    primitives->setPopupMode(QToolButton::InstantPopup);
    QWidgetAction* primitiveActione = new QWidgetAction(this);
    primitiveActione->setDefaultWidget(primitives);
    toolBar->addAction(primitiveActione);

    toolBar->addWidget(slider);

    addToolBar( toolBar);

}

void MainWindow::initGrid()
{
    showGridButton = new QToolButton(toolBar);

    showGridButton->setCheckable(true);

    gridSizeInput = new QSpinBox(toolBar);
    gridSizeInput->setRange(0,100);
    gridSizeInput->setValue(5);

    gridSizeInput->setToolTip("Grid Size");

    gridStepInput = new QSpinBox(toolBar);
    gridStepInput->setRange(1,10);

    gridStepInput->setToolTip("Grid Step Size");

    connect(gridSizeInput,SIGNAL(valueChanged(int)),perspectiveView,SLOT(setGridSize(int)));
    connect(gridStepInput,SIGNAL(valueChanged(int)),perspectiveView,SLOT(setGridStepSize(int)));
    connect(showGridButton,SIGNAL(clicked(bool)),perspectiveView,SLOT(showGrid(bool)));

    connect(gridSizeInput,SIGNAL(valueChanged(int)),topView,SLOT(setGridSize(int)));
    connect(gridStepInput,SIGNAL(valueChanged(int)),topView,SLOT(setGridStepSize(int)));
    connect(showGridButton,SIGNAL(clicked(bool)),topView,SLOT(showGrid(bool)));

    connect(gridSizeInput,SIGNAL(valueChanged(int)),leftView,SLOT(setGridSize(int)));
    connect(gridStepInput,SIGNAL(valueChanged(int)),leftView,SLOT(setGridStepSize(int)));
    connect(showGridButton,SIGNAL(clicked(bool)),leftView,SLOT(showGrid(bool)));

    connect(gridSizeInput,SIGNAL(valueChanged(int)),frontView,SLOT(setGridSize(int)));
    connect(gridStepInput,SIGNAL(valueChanged(int)),frontView,SLOT(setGridStepSize(int)));
    connect(showGridButton,SIGNAL(clicked(bool)),frontView,SLOT(showGrid(bool)));

    connect(gridSizeInput,SIGNAL(valueChanged(int)),this,SLOT(updateGL()));
    connect(gridStepInput,SIGNAL(valueChanged(int)),this,SLOT(updateGL()));
    connect(showGridButton,SIGNAL(clicked(bool)),this,SLOT(updateGL()));
}

void MainWindow::initPrimitivesMenu()
{
    primitivesMenu = new QMenu("Primitives",this);

    spheresAdd = new QAction("Sphere",this);
    spheresAdd->setIcon(QIcon(":/img/sphere.png"));
    connect(spheresAdd, SIGNAL(triggered()), scene, SLOT(addSphere()));

    boxesAdd = new QAction("Box",this);
    boxesAdd->setIcon(QIcon(":/img/box.png"));
    connect(boxesAdd, SIGNAL(triggered()), scene, SLOT(addCube()));

    cylindersAdd = new QAction("Cylinder",this);
    cylindersAdd->setIcon(QIcon(":/img/cylinder.png"));
    connect(cylindersAdd, SIGNAL(triggered()), scene, SLOT(addCylinder()));

    coneAdd = new QAction("Cone",this);
    coneAdd->setIcon(QIcon(":/img/cone.png"));
    connect(coneAdd, SIGNAL(triggered()), scene, SLOT(addCone()));

    torusAdd = new QAction("Torus",this);
    torusAdd->setIcon(QIcon(":/img/torus.png"));
    connect(torusAdd, SIGNAL(triggered()), scene, SLOT(addTorus()));

    groupAdd = new QAction("Group",this);
    groupAdd->setIcon(QIcon(":/img/wireframe.png"));
    connect(groupAdd, SIGNAL(triggered()), scene, SLOT(addNode()));

    activeDelete = new QAction("Delete",this);
    activeDelete->setIcon(QIcon(":/img/delete.png"));
    connect(activeDelete, SIGNAL(triggered()), scene, SLOT(deletActive()));

    volumeAdd = new QAction("Volume",this);
    //activeDelete->setIcon(QIcon(":/img/delete.png"));
    connect(volumeAdd, SIGNAL(triggered()), controler, SLOT(addVolume()));

    landscapeAdd = new QAction("Landscape",this);
    landscapeAdd->setIcon(QIcon(":/img/land.png"));
    connect(landscapeAdd, SIGNAL(triggered()), controler, SLOT(addLandscape()));


    primitivesMenu->addAction(spheresAdd);
    primitivesMenu->addAction(boxesAdd);
    primitivesMenu->addAction(cylindersAdd);
    primitivesMenu->addAction(coneAdd);
    primitivesMenu->addAction(torusAdd);
    primitivesMenu->addAction(groupAdd);
    primitivesMenu->addAction(activeDelete);
    primitivesMenu->addAction(volumeAdd);
    primitivesMenu->addAction(landscapeAdd);
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setWindowTitle("Hello Cube");

    menuBar = new QMenuBar();
    toolBar = new QToolBar("Shading",this);
    statusBar = new QStatusBar(this);

    //Views
    scene = new Scene();
    scene->setTesselation(1);
    connect(scene,SIGNAL(activChanged()),this,SLOT(updateStatusBar()));
    connect(scene,SIGNAL(activChanged()),this,SLOT(updateGL()));


    controler = new Controler(this,scene);

    initViews();

    camHome = new QAction(QIcon(":/img/cam_home.png"),"Cam Home", toolBar);//vor set Active View
    setActiveView(perspectiveView);

    initSplits();


    //File Menu Actions
    fileMenu = new QMenu("&File");



    exitAction = new QAction("E&xit",fileMenu);
    exitAction->setShortcut(QKeySequence::Quit);
    connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));


    MIPButton = new QToolButton(toolBar);
    MIPButton->setCheckable(true);
    connect(MIPButton, SIGNAL(clicked(bool)), perspectiveView, SLOT(setMIP(bool)));
    connect(MIPButton, SIGNAL(clicked(bool)), frontView, SLOT(setMIP(bool)));
    connect(MIPButton, SIGNAL(clicked(bool)), leftView, SLOT(setMIP(bool)));
    connect(MIPButton, SIGNAL(clicked(bool)), topView, SLOT(setMIP(bool)));



    //Interaction Actions
    interactionGroup = new QActionGroup(this);
    interactionMenu = new QMenu("Interaction",this);

    cameraMode = new QAction("Camera",this);
    cameraMode->setCheckable(true);
    cameraMode->setIcon(QIcon(":/img/camera.png"));
    cameraMode->setChecked(true);
    connect(cameraMode, SIGNAL(triggered()), controler, SLOT(setCamMode()));
    interactionGroup->addAction(cameraMode);

    editMode = new QAction("Edit",this);
    editMode->setCheckable(true);
    editMode->setIcon(QIcon(":/img/select.png"));
    connect(editMode, SIGNAL(triggered()), controler, SLOT(setEditMode()));
    interactionGroup->addAction(editMode);


    //Other Actions
    aboutAction = new QAction("About",menuBar);
    connect(aboutAction,SIGNAL(triggered()),this,SLOT(showAboutBox()));

    slider = new QSlider(Qt::Horizontal,toolBar);
    slider->setMinimum( 0 );
    slider->setMaximum( 4 );
    connect(slider,SIGNAL(valueChanged(int)),scene,SLOT(setTesselation(int)));
    slider->setValue( 1 );

    // Add Primitives

    initPrimitivesMenu();

    initGrid();





    // Assemble Menus
    fileMenu->addAction(exitAction);
    menuBar->addMenu(fileMenu);
    menuBar->addMenu(primitivesMenu);
    menuBar->addAction(aboutAction);

    setMenuBar(menuBar);

    //Assemble Tool Bar
    initToolbar();

    timer= new QTimer(this);

    connect(timer, SIGNAL(timeout()),this,SLOT(initScene()));
    timer->start(1000);

    setStatusBar(statusBar);
    initDoc();


}

void MainWindow::initScene(){
    //scene->simpleScene();
    // controler->addVolume("D:/Projekte/GraPa/A3/MRI-head.raw");

    timer->stop();
}


void MainWindow::initDoc()
{
    QDockWidget *dock = new QDockWidget("Scene", this);
    dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);

    sceneView = new QTreeView(this);
    sceneView->setSelectionBehavior(QAbstractItemView::SelectRows);
    sceneView->expandAll();
    sceneView->setModel(scene);
    TreeDelegate *delegate = new TreeDelegate();
    sceneView->setItemDelegate(delegate);
    connect(sceneView,SIGNAL(clicked(QModelIndex)),scene, SLOT(objectSelected(QModelIndex)));
    connect(delegate,SIGNAL(nameChanged()),this, SLOT(updateStatusBar()));

    dock->setWidget(sceneView);

    //Transfer Function Doc
    QDockWidget *transferDock = new QDockWidget("Transfer Function Editor",this);
    transferDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);

    transEditor = new TransferFunctionEditor(this);

    connect(transEditor,SIGNAL(dataChanged(uchar*)),perspectiveView,SLOT(loadTransfer(uchar*)));
    connect(transEditor,SIGNAL(dataChanged(uchar*)),frontView,SLOT(loadTransfer(uchar*)));
    connect(transEditor,SIGNAL(dataChanged(uchar*)),leftView,SLOT(loadTransfer(uchar*)));
    connect(transEditor,SIGNAL(dataChanged(uchar*)),topView,SLOT(loadTransfer(uchar*)));
    connect(transEditor,SIGNAL(dataChanged(uchar*)),this,SLOT(updateGL()));



    QPushButton *save = new QPushButton("Save");
    connect(save,SIGNAL(released()),transEditor,SLOT(save()));
    QPushButton *load = new QPushButton("Load");
    connect(load,SIGNAL(released()),transEditor,SLOT(load()));
    QPushButton *reset = new QPushButton("Reset");
    connect(reset,SIGNAL(released()),transEditor,SLOT(reset()));
    QPushButton *Smooth = new QPushButton("smooth");
    connect(Smooth,SIGNAL(released()),transEditor,SLOT(smooth()));

    QCheckBox *red = new QCheckBox("red");
    red->setChecked(true);
    connect(red,SIGNAL(clicked(bool)),transEditor,SLOT(paintRed(bool)));

    QCheckBox *green = new QCheckBox("green");
    green->setChecked(true);
    connect(green,SIGNAL(clicked(bool)),transEditor,SLOT(paintGreen(bool)));

    QCheckBox *blue = new QCheckBox("blue");
    blue->setChecked(true);
    connect(blue,SIGNAL(clicked(bool)),transEditor,SLOT(paintBlue(bool)));

    QCheckBox *alpha = new QCheckBox("alpha");
    alpha->setChecked(true);
    connect(alpha,SIGNAL(clicked(bool)),transEditor,SLOT(paintAlpha(bool)));


    QWidget *all = new QWidget;
    QWidget *buttons = new QWidget;
    QWidget *left = new QWidget;
    QWidget *right = new QWidget;

    QVBoxLayout *checkLayout = new QVBoxLayout;
    checkLayout->addWidget(red);
    checkLayout->addWidget(green);
    checkLayout->addWidget(blue);
    checkLayout->addWidget(alpha);
    right->setLayout(checkLayout);

    QGridLayout *butLayout = new QGridLayout;
    butLayout->addWidget(save,0,0);
    butLayout->addWidget(load,0,1);
    butLayout->addWidget(reset,1,0);
    butLayout->addWidget(Smooth,1,1);
    left->setLayout(butLayout);

    QHBoxLayout *buttonsLayout = new QHBoxLayout;
    buttonsLayout->addWidget(left);
    buttonsLayout->addWidget(right);
    buttons->setLayout(buttonsLayout);

    QVBoxLayout *allLayout = new QVBoxLayout;
    allLayout->addWidget(transEditor);
    allLayout->addWidget(buttons);
    all->setLayout(allLayout);

    transferDock->setWidget(all);

    transferDock->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum);
    addDockWidget(Qt::RightDockWidgetArea, transferDock);
    addDockWidget(Qt::RightDockWidgetArea, dock);
}

void MainWindow::updateStatusBar()
{
    QString text = scene->getActive()->getName();
    statusBar->showMessage(text);
}

void MainWindow::showSingle(){
    perspectiveView->show();
    frontView->hide();
    leftView->hide();
    topView->hide();
}
void MainWindow::showDual(){

    perspectiveView->show();
    frontView->show();
    leftView->hide();
    topView->hide();
}

void MainWindow::showQuad(){

    perspectiveView->show();
    frontView->show();
    leftView->show();
    topView->show();

}

void MainWindow::updateGL()
{
    perspectiveView->updateGL();
    frontView->updateGL();
    leftView->updateGL();
    topView->updateGL();
}

GLView** MainWindow::getViews(){
    return views;

}




void MainWindow::setActiveView(GLView * active)
{
    perspectiveView->setAcive((perspectiveView == active));

    frontView->setAcive((frontView == active));
    leftView->setAcive((leftView == active));
    topView->setAcive((topView == active));
    disconnect(camHome, SIGNAL(triggered(bool)),perspectiveView,SLOT(home()));
    disconnect(camHome, SIGNAL(triggered(bool)),frontView,SLOT(home()));
    disconnect(camHome, SIGNAL(triggered(bool)),leftView,SLOT(home()));
    disconnect(camHome, SIGNAL(triggered(bool)),topView,SLOT(home()));

    connect(camHome, SIGNAL(triggered(bool)),active,SLOT(home()));
}



MainWindow::~MainWindow()
{

}

void MainWindow::showAboutBox()
{
    QMessageBox msgBox;
    msgBox.setWindowTitle("About Hello Cube!");
    msgBox.setText("Written by Kai Westerkamp");
    msgBox.exec();
}
