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


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

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

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


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

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

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

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


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

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

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


    setCentralWidget(verticalSplit);

    showQuad();
    //showSingle();
    //showDual();
    //

    //File Menu Actions
    fileMenu = new QMenu("&File");
    viewGoup = new QActionGroup(this);
    viewMenu = new QMenu("View",this);
    primitivesMenu = new QMenu("Primitives",this);

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


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


    //Interaction Actions
    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);

    //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);


    //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

    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()));


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

    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()));



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

    setMenuBar(menuBar);

    //Assemble Tool Bar
    toolBar->addAction(cameraMode);
    toolBar->addAction(editMode);

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

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

 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);
    scene->simpleScene();



    setStatusBar(statusBar);
    initDoc();

}


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

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




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