#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include "SyncObject.h"
#include "SyncThread.h"

#include "CameraPreview.h"
#include "CameraThread.h"
#include "CameraObject.h"

#include "Camera_Basler_GigE.h"

#include "ProcessorThread.h"
#include "ProcessorObject.h"


#include "Processor_CameraCalibration.h"
#include "CameraCalibrationWindow.h"

#include "Processor_PlaneCalibration.h"
#include "PlaneCalibrationWindow.h"

#include "Processor_ObjectExtraction.h"
#include "ObjectExtractionWindow.h"

#include <QMdiSubWindow>
#include <QDebug>
#include <QDockWidget>
#include <QFileDialog>
enum gestures_ids {leftRightId,downUpId,rectangleCWId,leftDownId, leftUpId, upDownId,};
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    qRegisterMetaType<QList<CameraObject*>>();
    qRegisterMetaType<QList<ProcessorObject*>>();
    qRegisterMetaType<QVector<sObject>>();
    qRegisterMetaType<cv::Mat>();
    
    ui->setupUi(this);

    connect ( this, SIGNAL( writeInfo(QString) ), this, SLOT( displayInfo(QString) ));

    //adds complex  gestures filter

    QVector<cGestureDirectoryEntry> gesturesDirectory = {cGestureDirectoryEntry((int)gestures_ids::leftRightId,"horizontal move left right",{sAtomGesture::H_LINE_LEFT,sAtomGesture::H_LINE_RIGHT},cGestureDirectoryEntry::EQUAL_START_END, Qt::NoButton, 'a', Qt::ControlModifier, 5000),\
                                                         cGestureDirectoryEntry((int)gestures_ids::downUpId,"vertical down up",{sAtomGesture::V_LINE_DOWN,sAtomGesture::V_LINE_UP},cGestureDirectoryEntry::EQUAL_START_END, Qt::LeftButton, 0, Qt::NoModifier, 3000),\
                                                         cGestureDirectoryEntry((int)gestures_ids::upDownId,"vertical  up down",{sAtomGesture::V_LINE_UP,sAtomGesture::V_LINE_DOWN},cGestureDirectoryEntry::EQUAL_START_END, Qt::NoButton, 0, Qt::NoModifier, 3000),\
                                                         cGestureDirectoryEntry((int)gestures_ids::leftDownId,"rotate right ",{sAtomGesture::H_LINE_LEFT,sAtomGesture::V_LINE_DOWN},cGestureDirectoryEntry::EQUAL_SIZE, Qt::NoButton, 0, Qt::NoModifier, 3000),\
                                                         // cGestureDirectoryEntry((int)gestures_ids::leftUpId,"rotate left ",{sAtomGesture::H_LINE_LEFT,sAtomGesture::V_LINE_UP},cGestureDirectoryEntry::EQUAL_SIZE, Qt::NoButton, 0, Qt::NoModifier, 3000),
                                                         cGestureDirectoryEntry((int)gestures_ids::rectangleCWId,"rectangle clockwise",{sAtomGesture::H_LINE_RIGHT,sAtomGesture::V_LINE_DOWN,sAtomGesture::H_LINE_LEFT, sAtomGesture::V_LINE_UP},cGestureDirectoryEntry::EQUAL_START_END, Qt::NoButton, 'z',Qt::ControlModifier)};

    //    QVector<cGestureDirectoryEntry> gesturesDirectory = {cGestureDirectoryEntry((int)gestures_ids::leftRightId,"horizontal move left right",{sAtomGesture::H_LINE_LEFT,sAtomGesture::H_LINE_RIGHT},cGestureDirectoryEntry::EQUAL_START_END, Qt::NoButton, 'a', Qt::ControlModifier, 5000),\
    //                                                         cGestureDirectoryEntry((int)gestures_ids::downUpId,"vertical down up",{sAtomGesture::V_LINE_DOWN,sAtomGesture::V_LINE_UP},cGestureDirectoryEntry::EQUAL_START_END, Qt::LeftButton, 0, Qt::NoButton, 5000),\
    //                                                         cGestureDirectoryEntry((int)gestures_ids::rectangleCWId,"rectangle clockwise",{sAtomGesture::H_LINE_RIGHT,sAtomGesture::V_LINE_DOWN,sAtomGesture::H_LINE_LEFT, sAtomGesture::V_LINE_UP},cGestureDirectoryEntry::EQUAL_START_END, Qt::NoButton, 'z',Qt::ControlModifier)};

    gestureEventsFilter = new cEyeTrackerFilter(gesturesDirectory,this,0);
    connect(gestureEventsFilter,SIGNAL(complexGesture(int,QRect,QPoint,QString)),this,SLOT(complexGesturesMatcher(int,QRect,QPoint,QString)));

    qApp->installEventFilter(gestureEventsFilter);

}

bool MainWindow::init(const QString &configFilename, const QString& logFilename, int is_gestures_used) {
    /* ROBOT */
    
    UR3Workspace_ = new UR3Workspace();
    connect(UR3Workspace_, SIGNAL(connectedToRobot(bool)), this, SLOT(robot_connected(bool)));
    connect(UR3Workspace_, SIGNAL(disconnectedFromRobot()), this, SLOT(robot_disconnected()));
    UR3CalibWidget_ = new UR3CalibWidget(UR3Workspace_);
    
    /* IMAGE PROCESSING */
    
    SyncObject *so = new SyncObject;
    syncThread = new SyncThread(so);
    
    connect(this, SIGNAL(syncThreadStart(int)), so, SLOT(startAcquisition(int)), Qt::QueuedConnection );
    connect(this, SIGNAL(syncThreadStop()), so, SLOT(stopAcquisition()), Qt::QueuedConnection);
    connect(this, SIGNAL(connectCameraToSyncThread(CameraThread *)), so, SLOT( connectCamera(CameraThread *) ), Qt::QueuedConnection);
    connect(this, SIGNAL(disconnectCameraFromSyncThread(CameraThread *)), so, SLOT( disconnectCamera(CameraThread *) ), Qt::QueuedConnection );
    connect(this, SIGNAL(connectProcessorToSyncThread(ProcessorThread *)), so, SLOT( connectProcessor(ProcessorThread *) ), Qt::QueuedConnection);
    connect(this, SIGNAL(disconnectProcessorFromSyncThread(ProcessorThread *)), so, SLOT( disconnectProcessor(ProcessorThread *) ), Qt::QueuedConnection );
    
    objectManipulationWindow = new ObjectManipulationWindow();
    ui->layout_user_interface->addWidget(objectManipulationWindow);
    objectManipulationProperties = new ObjectManipulationProperties(objectManipulationWindow, objectManipulationWindow);
    
    connect(ui->action_config_reset_buttons, SIGNAL(triggered()), objectManipulationWindow, SLOT(reset_buttons()));
    
    connect(UR3Workspace_, SIGNAL(commandStarted()), objectManipulationWindow, SLOT(commandStarted()));
    connect(UR3Workspace_, SIGNAL(commandExecuted()), objectManipulationWindow, SLOT(commandExecuted()));
    connect(UR3Workspace_, SIGNAL(robotEmergencyStopped()), objectManipulationWindow, SLOT(robotEmergencyStopped()));
    
    configFilename_ = configFilename;
    
    bool retval;
    
    retval = refreshDeviceList();
    
    if(retval) {
        connectDevice();
    }
    
    /* LOAD CONFIG */
    
    openFile(configFilename);
    if(is_gestures_used >=0)
    {
        gestureEventsFilter->Setuse_complex_gestures(is_gestures_used);
    }
    objectManipulationWindow->show_gestures_legend(gestureEventsFilter->use_complex_gestures());
    /* START */
    // wait for robot connection
    {
        QTimer timer;
        timer.setSingleShot(true);
        QEventLoop loop;
        connect(UR3Workspace_,  SIGNAL(connectedToRobot(bool)), &loop, SLOT(quit()) );
        connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
        UR3Workspace_->connectToRobot();
        timer.start(100);
        loop.exec();
    }
    
    if (retval) {
        QTimer timer;
        timer.setSingleShot(true);
        QEventLoop loop;
        connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
        timer.start(3000);
        loop.exec();
        on_action_view_user_interface_triggered();
    }
    
    if (retval) {
        acquisitionStart();
    }

    if(logFilename!="")
    {
        QString filename = logFilename+QString("!%1").arg(QDateTime::currentDateTime().toString("dd-MM-yyThh-mm-ss"));
        file.setFileName(filename+".csv");
        Processor_ObjectExtraction* p= dynamic_cast< Processor_ObjectExtraction*>(ObjectExtraction_proc);
        if(p!=NULL)
        {
            p->screenshot(filename);
        }
        file.open(QIODevice::WriteOnly);

        stream.setDevice(&file);
        connect(gestureEventsFilter,SIGNAL(logEvent(cEyeTrackerFilter::logSource,int,int,int,QString)),this,SLOT(logEvent(cEyeTrackerFilter::logSource,int,int,int,QString)));
        connect(objectManipulationWindow, SIGNAL(logEvent(ObjectManipulationWindow::interfaceLogEvents,int,int,QPointF,QPointF,float)),this,SLOT(logEvent(ObjectManipulationWindow::interfaceLogEvents,int,int,QPointF,QPointF,float)));
        logTimer.start();
    }
    return retval;
}

bool MainWindow::openFile(QString fileName) {
    
    if (fileName.isEmpty()) {
        fileName = QFileDialog::getOpenFileName(this,
                                                tr("Open config file"), "", tr("XML files (*.xml)"));
    }
    QFileInfo check_file(fileName);
    if (check_file.exists() && check_file.isFile()) {
        QList<CameraThread *> cl = syncThread->syncObject->getCameraList();
        for(auto el:cl) {
            el->cameraObject->findInXML(fileName);
        }
        
        QList<ProcessorThread *> pt = syncThread->syncObject->getProcessorList();
        for(auto el:pt) {
            el->processorObject->findInXML(fileName);
        }
        
        UR3Workspace_->findInXML(fileName);
        gestureEventsFilter->findInXML(fileName);
        objectManipulationProperties->findInXML(fileName);
        
        configFilename_ = fileName;
        
        return true;
    } else {
        displayInfo("ERROR: could not open config file\"" + fileName + "\"");
        return false;
    }
}

bool MainWindow::saveFile(QString fileName) {
    if (fileName.isEmpty()) {
        fileName = QFileDialog::getSaveFileName(this,
                                                tr("Save config file"), "", tr("XML files (*.xml)"));
    }
    if (fileName.isEmpty()) {
        return 0;
    }
    
    QFile file;
    file.setFileName(fileName);

    if (file.open(QIODevice::WriteOnly)) {
        QXmlStreamWriter stream(&file);

        stream.writeStartDocument();
        stream.writeStartElement("_05Robot");
        stream.setAutoFormatting(true);
        
        stream.writeStartElement("Cameras");
        QList<CameraThread *> cl = syncThread->syncObject->getCameraList();
        for(auto el:cl)
        {
            el->cameraObject->writeXml(stream);
        }
        stream.writeEndElement();
        
        stream.writeStartElement("Processors");
        QList<ProcessorThread *> pt = syncThread->syncObject->getProcessorList();
        for(auto el:pt)
        {
            el->processorObject->writeXml(stream);
        }
        stream.writeEndElement();
        
        stream.writeStartElement("Robot");
        UR3Workspace_->writeXml(stream);
        stream.writeEndElement();
        
        stream.writeStartElement("EyeTracker");
        gestureEventsFilter->writeXml(stream);
        stream.writeEndElement();
        
        stream.writeStartElement("ObjectManipulationProperties");
        objectManipulationProperties->writeXml(stream);
        stream.writeEndElement();
        
        stream.writeEndElement();
        stream.writeEndDocument();
        file.close();
        return true;
    } else {
        return false;
    }
}

void MainWindow::connectDevice() {
    QList<QListWidgetItem*> selected = ui->cameraList->selectedItems();
    if(selected.size() != 1)
    {
        QMessageBox msgBox;
        msgBox.setText("Select device!");
        msgBox.exec();
        return;
    }
    connectDevice(selected[0]);
    updateWindowLists();
}

bool MainWindow::refreshDeviceList() {
    bool retval = false;
    ui->cameraList->clear();
    QListWidgetItem* item;

    Camera_Basler_GigE::refreshDevices();

    for(size_t i=0; i<Camera_Basler_GigE::devices.size(); ++i) {
        item = new QListWidgetItem();
        item->setText(QString::fromStdString((string)Camera_Basler_GigE::devices[i].GetFullName()));
        item->setData(QListWidgetItem::UserType+1, deviceBasler_GigE);
        item->setData(QListWidgetItem::UserType+2, QString::fromStdString((string)Camera_Basler_GigE::devices[i].GetSerialNumber()));
        ui->cameraList->addItem(item);

    }
    
    displayInfo("Detected " + QString::number(Camera_Basler_GigE::devices.size()) + " camera(s):");
    for (auto& dev : Camera_Basler_GigE::devices) {
        displayInfo(QString::fromStdString((string)dev.GetFullName()));
    }
    
    if (Camera_Basler_GigE::devices.size() > 0) {
        retval = true;
        ui->cameraList->item(0)->setSelected(1);
    }
    return retval;
}

void MainWindow::connectDevice(QListWidgetItem *selectedDev)
{
    for(int i=0; i<connectedDevices.size(); ++i)
    {
        if(selectedDev->data(QListWidgetItem::UserType+1).toInt() != deviceImageFromFile && selectedDev->data(QListWidgetItem::UserType+1).toInt() != deviceDataFromFile)
            if(selectedDev->data(QListWidgetItem::UserType+1).toInt() == connectedDevices[i]->ct->cameraObject->cameraType && selectedDev->data(QListWidgetItem::UserType+2).toInt() == connectedDevices[i]->ct->cameraObject->cameraID)
            {
                QMessageBox msgBox;
                msgBox.setText("Device already connected!");
                msgBox.exec();
                return;
            }

    }

    Camera *cam;
    int err = 1;
    QString windowName;


    if(selectedDev->data(QListWidgetItem::UserType+1).toInt() == deviceBasler_GigE)
    {
        cam = new Camera_Basler_GigE;
        connect ( cam, SIGNAL( writeInfo(QString) ), this, SLOT( displayInfo(QString) ), Qt::QueuedConnection );
        int n=-1;
        for(size_t i=0; i<Camera_Basler_GigE::devices.size(); ++i)
            if(selectedDev->data(QListWidgetItem::UserType+2).toString() == QString::fromStdString((string)Camera_Basler_GigE::devices[i].GetSerialNumber()))
                n=i;
        if(n>=0)
        {
            err = cam->connect(n);
            windowName = QString::fromStdString((string)Camera_Basler_GigE::devices[n].GetFullName());
        }
    }

    if(err) {
        writeInfo("Connection failed!");
    } else {
        writeInfo("Device connected!");

        CameraObject *co = new CameraObject(cam, selectedDev->data(QListWidgetItem::UserType+1).toInt(), selectedDev->data(QListWidgetItem::UserType+2).toInt(), syncThread->syncObject->syncSem);
        CameraThread *ct = new CameraThread(co);

        connect ( co, SIGNAL( writeInfo(QString) ), this, SLOT( displayInfo(QString) ), Qt::QueuedConnection );

        CameraPreview *cameraWindow1 = new CameraPreview(ct,parentWidget());
        ui->tabWidget_debug->addTab(cameraWindow1, windowName);
        
        emit connectCameraToSyncThread(ct);

        connect ( co, SIGNAL( frameOut(cv::Mat*,int,int) ), cameraWindow1, SLOT( frameIn(cv::Mat*,int,int) ), Qt::QueuedConnection );

        connect ( cameraWindow1, SIGNAL( closing(CameraPreview*) ), this, SLOT( disconnectDevice(CameraPreview*) ), Qt::QueuedConnection );
        
        connectedDevices.push_back(cameraWindow1);
        
        /* PlaneCalibration */
        PlaneCalibration_proc = new Processor_PlaneCalibration();
        connect (PlaneCalibration_proc, SIGNAL( writeInfo(QString) ), this, SLOT( displayInfo(QString) ), Qt::QueuedConnection );
        
        PlaneCalibration_po = new ProcessorObject(PlaneCalibration_proc, processorPlaneCalibration, 0, syncThread->syncObject->syncSem);
        PlaneCalibration_pt = new ProcessorThread(PlaneCalibration_po);
        
        connect ( PlaneCalibration_po, SIGNAL( writeInfo(QString) ), this, SLOT( displayInfo(QString) ), Qt::QueuedConnection );
        
        ProcessorWindow *PlaneCalibration_processorWindow1 = new PlaneCalibrationWindow(PlaneCalibration_pt,parentWidget());
        
        emit connectProcessorToSyncThread(PlaneCalibration_pt);
        
        connect ( PlaneCalibration_po, SIGNAL( frameOut(int, cv::Mat*) ), PlaneCalibration_processorWindow1, SLOT( frameIn(int, cv::Mat*) ), Qt::QueuedConnection );
        connect (PlaneCalibration_processorWindow1, SIGNAL( closing(ProcessorWindow*) ), this, SLOT( removeProcessor(ProcessorWindow*) ), Qt::QueuedConnection );
        connect (PlaneCalibration_processorWindow1, SIGNAL( signalSpecial(QString) ), PlaneCalibration_po, SLOT( pProcessSpecial(QString) ), Qt::QueuedConnection );
        
        QList<CameraObject*> PlaneCalibration_input_camera_objects = {co};
        QList<ProcessorObject*> PlaneCalibration_input_processor_objects;
        PlaneCalibration_po->connectInputs(PlaneCalibration_input_camera_objects, PlaneCalibration_input_processor_objects);
        
        connectedProcessors.push_back(PlaneCalibration_processorWindow1);
        ui->tabWidget_debug->addTab(PlaneCalibration_processorWindow1, tr("Plane calibration"));

        updateWindowLists();
        
        /* ObjectExtraction */
        ObjectExtraction_proc = new Processor_ObjectExtraction();
        connect (ObjectExtraction_proc, SIGNAL( writeInfo(QString) ), this, SLOT( displayInfo(QString) ), Qt::QueuedConnection );
        
        ObjectExtraction_po = new ProcessorObject(ObjectExtraction_proc, processorObjectExtraction, 0, syncThread->syncObject->syncSem);
        ObjectExtraction_pt = new ProcessorThread(ObjectExtraction_po);
        
        connect ( ObjectExtraction_po, SIGNAL( writeInfo(QString) ), this, SLOT( displayInfo(QString) ), Qt::QueuedConnection );
        
        ProcessorWindow *ObjectExtraction_processorWindow1 = new ObjectExtractionWindow(ObjectExtraction_pt,parentWidget());
        
        emit connectProcessorToSyncThread(ObjectExtraction_pt);
        
        connect ( ObjectExtraction_po, SIGNAL( frameOut(int, cv::Mat*) ), ObjectExtraction_processorWindow1, SLOT( frameIn(int, cv::Mat*) ), Qt::QueuedConnection );
        connect ( ObjectExtraction_proc, SIGNAL(object_data(cv::Mat,QVector<sObject>)), objectManipulationWindow, SLOT(new_object_data(cv::Mat,QVector<sObject>)), Qt::QueuedConnection );
        
        connect (ObjectExtraction_processorWindow1, SIGNAL( closing(ProcessorWindow*) ), this, SLOT( removeProcessor(ProcessorWindow*) ), Qt::QueuedConnection );
        connect (ObjectExtraction_processorWindow1, SIGNAL( signalSpecial(QString) ), ObjectExtraction_po, SLOT( pProcessSpecial(QString) ), Qt::QueuedConnection );
        
        QList<CameraObject*> ObjectExtraction_input_camera_objects;
        QList<ProcessorObject*> ObjectExtraction_input_processor_objects{PlaneCalibration_po};
        ObjectExtraction_po->connectInputs(ObjectExtraction_input_camera_objects, ObjectExtraction_input_processor_objects);
        
        connectedProcessors.push_back(ObjectExtraction_processorWindow1);
        ui->tabWidget_debug->addTab(ObjectExtraction_processorWindow1, tr("Objects"));

        connect(objectManipulationWindow, SIGNAL(pickObject(QVector3D,float,float,int)), UR3Workspace_, SLOT(pickObject(QVector3D,float,float,int)));
        
        updateWindowLists();
    }
}

void MainWindow::displayInfo(const QString &s)
{
    ui->infoDisplay->moveCursor(QTextCursor::MoveOperation::End);
    QString s2 = s;
    ui->infoDisplay->insertHtml(s + QString("<br />"));
}

void MainWindow::acquisitionStart() {
    if(!(this->syncThread->syncObject->isRunning)) {
        emit syncThreadStart(50);
    }
}
void MainWindow::acquisitionStop() {
    if(this->syncThread->syncObject->isRunning) {
        emit syncThreadStop();
    }
}


MainWindow::~MainWindow() {
    acquisitionStop();
    delete ui;
    gestureEventsFilter->deleteLater();
}

void MainWindow::updateWindowLists() {
    for(int i=0; i<connectedProcessors.size(); ++i) {
        connectedProcessors[i]->updateLists(connectedDevices,connectedProcessors);
    }
}

void MainWindow::disconnectDevice(CameraPreview *pWindow)
{
    disconnect ( pWindow->ct->cameraObject->cam, SIGNAL( writeInfo(QString) ), this, SLOT( displayInfo(QString) ) );
    disconnect ( pWindow->ct->cameraObject, SIGNAL( writeInfo(QString) ), this, SLOT( displayInfo(QString) ) );
    disconnect ( pWindow, SIGNAL( closing(CameraPreview*) ), this, SLOT( disconnectDevice(CameraPreview*) ));
    emit disconnectCameraFromSyncThread(pWindow->ct);
    for(int i=0; i<connectedDevices.size(); ++i)
    {
        if(pWindow == connectedDevices[i])
        {
            connectedDevices.erase(connectedDevices.begin()+i);
            writeInfo("Device disconnected!");
            updateWindowLists();
            return;
        }
    }
}

void MainWindow::removeProcessor(ProcessorWindow *pWindow)
{
    disconnect ( pWindow->pt->processorObject->proc, SIGNAL( writeInfo(QString) ), this, SLOT( displayInfo(QString) ) );
    disconnect ( pWindow->pt->processorObject, SIGNAL( writeInfo(QString) ), this, SLOT( displayInfo(QString) ) );

    disconnect ( pWindow, SIGNAL( closing(ProcessorWindow*) ), this, SLOT( removeProcessor(ProcessorWindow*) ));
    emit disconnectProcessorFromSyncThread(pWindow->pt);
    for(int i=0; i<connectedProcessors.size(); ++i)
    {
        if(pWindow == connectedProcessors[i])
        {
            connectedProcessors.erase(connectedProcessors.begin()+i);
            writeInfo("Processor removed!");
            updateWindowLists();
            return;
        }
    }
}

void MainWindow::robot_connected(bool connected) {
    if (connected) {
        ui->action_robot_connect_disconnect->setText("Disconnect");
        displayInfo("Connection to robot succeeded");
    } else {
        displayInfo("ERROR: Connection to robot failed");
    }
    robot_connected_ = connected;
}

void MainWindow::robot_disconnected() {
    displayInfo("Robot disconnected");
    ui->action_robot_connect_disconnect->setText("Connect");
    robot_connected_ = false;
}

void MainWindow::on_action_config_open_default_triggered() {
    openFile("config.xml");
}
void MainWindow::on_action_config_open_triggered() {
    openFile();
}
void MainWindow::on_action_config_save_triggered() {
    saveFile(configFilename_);
}
void MainWindow::on_action_config_save_as_triggered() {
    saveFile();
}
void MainWindow::on_action_view_user_interface_triggered() {
    ui->stackedWidget->setCurrentIndex(1);
}
void MainWindow::on_action_view_message_log_triggered() {
    ui->stackedWidget->setCurrentIndex(0);
}
void MainWindow::on_action_view_debug_triggered() {
    ui->stackedWidget->setCurrentIndex(2);
}
void MainWindow::on_action_robot_connect_disconnect_triggered() {
    if (robot_connected_) {
        UR3Workspace_->disconnectFromRobot();
    } else {
        UR3Workspace_->connectToRobot();
    }
}
void MainWindow::on_action_robot_calibration_triggered() {
    UR3CalibWidget_->show();
}
void MainWindow::on_action_robot_home_triggered() {
    UR3Workspace_->moveToWorkspaceHome();
}
void MainWindow::on_action_camera_calibration_triggered(){
    if (PlaneCalibration_po != NULL) {
        QMetaObject::invokeMethod(PlaneCalibration_po, "pProcessSpecial", Qt::QueuedConnection, Q_ARG(QString, "calibrate"));
    }
}
void MainWindow::on_action_camera_get_background_triggered() {
    if (ObjectExtraction_po != NULL) {
        QMetaObject::invokeMethod(ObjectExtraction_po, "pProcessSpecial", Qt::QueuedConnection, Q_ARG(QString, "get_background"));
    }
}
void MainWindow::on_action_camera_start_triggered() {
    acquisitionStart();
}
void MainWindow::on_action_camera_stop_triggered() {
    acquisitionStop();
}

void MainWindow::complexGesturesMatcher(int id, QRect boundingBox, QPoint center, QString description)
{
    ObjectManipulationWindow::previev_types_t previev_id = objectManipulationWindow->getPreviewId();
    if(previev_id == ObjectManipulationWindow::preview_id)
    {
        switch(id)
        {
        case gestures_ids::leftRightId:
        {

        }
        case gestures_ids::leftDownId:
        {

        }
        case gestures_ids::downUpId:
        {
            QPoint center_l = objectManipulationWindow->getPreviewWidget()->mapFromGlobal(center);
            //objectManipulationWindow->preview_clicked(center_l.x(),center_l.y());
            break;
        }
        case gestures_ids::rectangleCWId:
        {

        }
        }
    }
    else if(previev_id == ObjectManipulationWindow::object_manipultion_id)
    {
        switch(id)
        {

        case gestures_ids::leftRightId:
        {
            //     objectManipulationWindow->lookAt(center);
            objectManipulationWindow->on_toolButton_zoom_out_clicked();
            break;
        }
        case gestures_ids::leftDownId:
        {
            objectManipulationWindow->on_toolButton_rotate_left_clicked();\
            break;
        }
        case gestures_ids::leftUpId:
        {
            objectManipulationWindow->on_toolButton_rotate_right_clicked();
            break;
        }
        case gestures_ids::upDownId:
        {

            break;
        }
        case gestures_ids::rectangleCWId:
        {
            //objectManipulationWindow->on_toolButton_zoom_in_clicked();
            int x1,x2,y1,y2;
            boundingBox.getCoords(&x1,&y1,&x2,&y2);
            QPoint p1 = objectManipulationWindow->getManipulationWidget()->mapFromGlobal(QPoint(x1,y1));
            QPoint p2 = objectManipulationWindow->getManipulationWidget()->mapFromGlobal(QPoint(x2,y2));

            objectManipulationWindow->zoom_rect_widget(QRect(p1,p2));
            break;
        }
        }
    }
    else
    {

    }

}
void MainWindow::logEvent(cEyeTrackerFilter::logSource source,int ID,int x, int y, QString info)
{

    stream<<logTimer.elapsed()<<";E"<<";"<<source<<";"<<ID<<";"<<x<<";"<<y<<";"<<";"<<";"<<";"<<";"<<info<<"\r\n";

}
void MainWindow::logEvent(ObjectManipulationWindow::interfaceLogEvents eventID, int selected_object, int param, QPointF point, QPointF size, float angle)
{
    QMetaEnum metaEnum = QMetaEnum::fromType<ObjectManipulationWindow::interfaceLogEvents>();
    //qDebug() << metaEnum.valueToKey(ModelApple::Big);
    stream<<logTimer.elapsed()<<";I"<<";"<<eventID<<";"<<selected_object<<";"<<param<<";"<<point.x()<<";"<<point.y()<<";"<<size.x()<<";"<<size.y()<<";"<<angle<<";"<<"Interface event:"<<metaEnum.valueToKey(eventID)<<"\r\n";
}

