#include "mainwin.h"
#include "./ui_mainwin.h"

#include <QDialogButtonBox>
#include <QFormLayout>
#include <qspinbox.h>

MainWin::MainWin(QWidget *parent)
    : QMainWindow(parent)
    , log(this, QDir::homePath()+"/log.log")
    , ui(new Ui::MainWin)
    , saveDialog(new Select_File_Dialog)
    , calib(new camera_calibration)
    , timer(new QElapsedTimer)
    , robot(new ri::Staubli)
    , continuousCapture(new continuous_capture_thread)
    , calibration_thread(new Main_Algorithm(this))
{
    timerFlag = false;
    ui->setupUi(this);
    this->setWindowTitle("TCP Calibration v0.8");
    ui->pic_ShowF->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: black;}");
    ui->pic_ShowS->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: black;}");
    getCameras();
    ui->comboBoxF->setCurrentText("NONE");
    ui->comboBoxS->setCurrentText("NONE");
    ui->cancel_button->setEnabled(false);
    ui->progress_Calculation->setValue(0);
    ui->progress_Measurement->setValue(0);

    for (uint8_t i=0;i<3;i++) {
        std::vector<float> vect;
        for (uint8_t j=0;j<6;j++) vect.push_back(0);
        this->parameters.tcpc.default_tcpc_positions.push_back(vect);
    }

    connect(calibration_thread,SIGNAL(ShowMarked(QImage,QImage)),this,SLOT(on_ShowMarked(QImage,QImage)));
    connect(calibration_thread,SIGNAL(NumberChanged(int)),this,SLOT(onNumberChanged(int)));
    connect(calibration_thread, SIGNAL(ShowStats(QString,QString)), this, SLOT(on_ShowStats(QString,QString)));
    connect(calibration_thread, SIGNAL(MeasurementProgressChanged(double)),this,SLOT(on_MeasurementProgressChanged(double)));
    connect(calibration_thread, SIGNAL(CalculationProgressChanged(double)),this,SLOT(on_CalculationProgressChanged(double)));
    connect(continuousCapture, SIGNAL(ShowImages(QImage,QImage)),this,SLOT(on_ShowImages(QImage,QImage)));
    qRegisterMetaType<camera::frame>();
}

MainWin::~MainWin()
{
    if(front_camera != nullptr) front_camera->close();
    if(side_camera != nullptr) side_camera->close();
    delete saveDialog;
    delete ui;
    delete calib;
    delete timer;
    delete robot;
    log<<"GUI closed";
}

void MainWin::on_ShowImages(QImage front,QImage side)
{
    int const hF=ui->pic_ShowF->height();
    int const wF=ui->pic_ShowF->width();
    int const hS=ui->pic_ShowS->height();
    int const wS=ui->pic_ShowS->width();

    QPixmap qPixmap_front(QPixmap::fromImage(front));
    QPixmap qPixmap_side(QPixmap::fromImage(side));
    ui->pic_ShowF->setPixmap(qPixmap_front.scaled(wF,hF,Qt::KeepAspectRatio, Qt::SmoothTransformation));
    ui->pic_ShowS->setPixmap(qPixmap_side.scaled(wS,hS,Qt::KeepAspectRatio, Qt::SmoothTransformation));
    ui->pic_ShowF->setAlignment(Qt::AlignCenter);
    ui->pic_ShowS->setAlignment(Qt::AlignCenter);
    ui->pic_ShowF->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: yellow;}");
    ui->pic_ShowS->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: yellow;}");
}

void MainWin::on_ShowMarked(QImage frontIMG, QImage sideIMG)
{
    int const hF=ui->pic_ShowF->height();
    int const wF=ui->pic_ShowF->width();
    int const hS=ui->pic_ShowS->height();
    int const wS=ui->pic_ShowS->width();

    QPixmap qPixmap_front(QPixmap::fromImage(frontIMG));
    QPixmap qPixmap_side(QPixmap::fromImage(sideIMG));
    ui->pic_ShowF->setPixmap(qPixmap_front.scaled(wF,hF,Qt::KeepAspectRatio, Qt::SmoothTransformation));
    ui->pic_ShowS->setPixmap(qPixmap_side.scaled(wS,hS,Qt::KeepAspectRatio, Qt::SmoothTransformation));
    ui->pic_ShowF->setAlignment(Qt::AlignCenter);
    ui->pic_ShowS->setAlignment(Qt::AlignCenter);
    ui->pic_ShowF->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: green;}");
    ui->pic_ShowS->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: green;}");
}

void MainWin::onNumberChanged(int Number)
{
    if(Number==4){
        QMessageBox box;
        box.setText(this->calibration_thread->getLog());
        box.exec();

        this->calibration_thread->getTCP(TCP);
        //SAVE?
        bool ok1,ok2;
        json_handler tst;
        QMessageBox::StandardButton saveDialog;
        saveDialog = QMessageBox::question(this, "", "Do you want to save TCP?",
                     QMessageBox::Yes|QMessageBox::No);
        if (saveDialog == QMessageBox::Yes) {
            auto TOOL = (ri::eRobot_TOOL)QInputDialog::getInt(this, tr("Select TOOL"),tr("TOOL:"), 0, 0, 8, 1, &ok1);
            if (ok1) tst.saveTCP(TCP, TOOL);
            this->bTCP=true;
        }
        QMessageBox::StandardButton setDialog;
        setDialog = QMessageBox::question(this, "", "Do you want to load TCP to the Robot?",
                    QMessageBox::Yes|QMessageBox::No);
         if (setDialog == QMessageBox::Yes) {
            this->TCP_TOOL = (ri::eRobot_TOOL)QInputDialog::getInt(this, tr("Select TOOL"),tr("TOOL:"), 0, 0, 8, 1, &ok2);
            if (ok2) this->robot->setTOOL(this->TCP_TOOL);
            this->robot->setTCP(this->TCP,this->TCP_TOOL);
            this->bTCP=true;
         }
         ui->comboBoxF->setEnabled(true);
         ui->comboBoxS->setEnabled(true);
         ui->exit_button->setEnabled(true);
         ui->saveF_button->setEnabled(true);
         ui->saveS_button->setEnabled(true);
         ui->shotF_button->setEnabled(true);
         ui->shotS_button->setEnabled(true);
         ui->start_button->setEnabled(true);
         ui->menuCamera->setEnabled(true);
         ui->menuSetting->setEnabled(true);
         ui->menuHelp->setEnabled(true);
         ui->camConfigF_button->setEnabled(true);
         ui->camConfigS_button->setEnabled(true);
         ui->cancel_button->setEnabled(false);
         ui->pic_ShowF->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: black;}");
         ui->pic_ShowS->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: black;}");
         log<<"Calibration finished";
    }
}

void MainWin::on_actionmvImpact_Setting_triggered()
{
    log<<("Openned `wxPropView`");
    std::system("wxPropView");
}

void MainWin::getCameras()
{
    QStringList comboBoxEntries;
    mvIMPACT::acquire::DeviceManager devMgr_;
    for( unsigned int i = 0; i < devMgr_.deviceCount(); i++ )
    {
        mvIMPACT::acquire::Device* pDev = devMgr_.getDevice( i );
        QString entry;
        QTextStream( &entry ) << "[" << i << "] - " << QString::fromStdString( pDev->serial.readS() ) << " - " << QString::fromStdString( pDev->product.readS() );
        comboBoxEntries.append( entry );
    }
    QString entry;
    QTextStream( &entry ) << "NONE";
    comboBoxEntries.append( entry );
    QString currentTextF = ui->comboBoxF->currentText();
    QString currentTextS = ui->comboBoxS->currentText();
    ui->comboBoxF->clear();
    ui->comboBoxS->clear();
    ui->comboBoxF->addItems( comboBoxEntries );
    ui->comboBoxS->addItems( comboBoxEntries );
    ui->comboBoxF->setCurrentText(currentTextF);
    ui->comboBoxS->setCurrentText(currentTextS);
    log<<("called `getCameras()` with founded: " + QString::number(devMgr_.deviceCount()) + " cameras");
}

void MainWin::on_exit_button_clicked()
{
    close();
}

void MainWin::on_comboBoxF_activated(int index)
{
    if(index==ui->comboBoxS->currentIndex()){
        ui->comboBoxS->setCurrentText("NONE");
        if(side_camera != nullptr) side_camera->close();
    }
    if(ui->comboBoxF->currentText()=="NONE"){
        if(front_camera != nullptr) front_camera->close();
        log<<"Front camera selected as: NONE";
    }else{
        if(front_camera != nullptr) front_camera->close();
        front_camera = std::make_unique<interfaceBALLUFF::Camera>(index);
        log<<("Front camera selected as: " + QString::fromUtf8(front_camera->get_Name().c_str()));
        front_camera->set_idPf(mvIMPACT::acquire::TImageDestinationPixelFormat::idpfRGB888Packed );// idpfMono8
        log<<("Front camera pixel format: " + QString::fromUtf8(front_camera->get_idPf().c_str()));
    }
}

void MainWin::on_comboBoxS_activated(int index)
{
    if(index==ui->comboBoxF->currentIndex()){
        ui->comboBoxF->setCurrentText("NONE");
        if(front_camera != nullptr) front_camera->close();
    }
    if(ui->comboBoxS->currentText()=="NONE"){
        if(side_camera != nullptr) side_camera->close();
        log<<"Side camera selected as: NONE";
    }else{
    if(side_camera != nullptr) side_camera->close();
        side_camera = std::make_unique<interfaceBALLUFF::Camera>(index);
        log<<("Side camera selected as: " + QString::fromUtf8(side_camera->get_Name().c_str()));
        side_camera->set_idPf(mvIMPACT::acquire::TImageDestinationPixelFormat::idpfRGB888Packed );// idpfMono8//idpfMono16
        log<<("Side camera pixel format: " + QString::fromUtf8(side_camera->get_idPf().c_str()));
    }
}

void MainWin::on_shotF_button_clicked()
{
    if(front_camera != nullptr){
        int format = this->front_camera->get_Format_px();
        if(format == -1){
            QMessageBox text;
            text.setWindowTitle("ERROR");
            text.setText("Setted unsupported pixel format");
            text.exec();
            log<<("Not possible to capture Front frame - unsupported px format setted");
            return;
        }
        camera::frame frame = front_camera->readImage(format, -1, true);
        show_Front_Frame(frame, "red");
        front_frame = frame;
        log<<"Front camera test frame shooted";
    }
}

void MainWin::on_shotS_button_clicked()
{
    if(side_camera != nullptr){
        int format = this->side_camera->get_Format_px();
        if(format == -1){
            QMessageBox text;
            text.setWindowTitle("ERROR");
            text.setText("Setted unsupported pixel format");
            text.exec();
            log<<("Not possible to capture Front frame - unsupported px format setted");
            return;
        }
        camera::frame frame = side_camera->readImage(format, -1, true);//CV_16UC1
        show_Side_Frame(frame, "red");
        side_frame = frame;
        log<<"Side camera test frame shooted";
    }
}

void MainWin::on_start_button_clicked()
{
    if(this->robot == nullptr || this->front_camera == nullptr || this->side_camera == nullptr){
        QMessageBox text;
        text.setWindowTitle("WARNING");
        text.setText("Not possible to start calibration. Please check everything!");
        log<<"Starting calibration Aborted. Not possible to start calibration.";
        return;
    }
    ui->pic_ShowF->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: green;}");
    ui->pic_ShowS->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: green;}");
    log<<"Calibration started";

    ui->comboBoxF->setEnabled(false);
    ui->comboBoxS->setEnabled(false);
    ui->saveF_button->setEnabled(false);
    ui->saveS_button->setEnabled(false);
    ui->shotF_button->setEnabled(false);
    ui->shotS_button->setEnabled(false);
    ui->start_button->setEnabled(false);
    ui->menuCamera->setEnabled(false);
    ui->menuSetting->setEnabled(false);
    ui->menuHelp->setEnabled(true);
    ui->camConfigF_button->setEnabled(false);
    ui->camConfigS_button->setEnabled(false);
    ui->cancel_button->setEnabled(true);
    ui->exit_button->setEnabled(false);
    robot->goHome();
    this->stats_CNT = 0;
    this->ui->tableWidget->clearContents();
    //Show START
    this->calibration_thread->setFront_camera(*this->front_camera);
    this->calibration_thread->setSide_camera(*this->side_camera);
    this->calibration_thread->setRobot(*this->robot);
    this->calibration_thread->setSettings(this->parameters);
    this->calibration_thread->start();
}

void MainWin::on_cancel_button_clicked()
{
    calibration_thread->stopFlag = true;
    ui->comboBoxF->setEnabled(true);
    ui->comboBoxS->setEnabled(true);
    ui->exit_button->setEnabled(true);
    ui->saveF_button->setEnabled(true);
    ui->saveS_button->setEnabled(true);
    ui->shotF_button->setEnabled(true);
    ui->shotS_button->setEnabled(true);
    ui->start_button->setEnabled(true);
    ui->menuCamera->setEnabled(true);
    ui->menuSetting->setEnabled(true);
    ui->menuHelp->setEnabled(true);
    ui->camConfigF_button->setEnabled(true);
    ui->camConfigS_button->setEnabled(true);
    ui->cancel_button->setEnabled(false);
    ui->pic_ShowF->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: black;}");
    ui->pic_ShowS->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: black;}");
    log<<"Calibration canceled";
}

void MainWin::on_saveF_button_clicked()
{
    if(front_frame.image.ptr()==nullptr){
        QMessageBox text;
        text.setText("Frame is not captured");
        text.exec();
        log<<"Tried to save Front camera test frame without frame";
    }else{
        saveDialog->setFrame(&front_frame);
        saveDialog->setModal(true);
        saveDialog->exec();
        log<<"Front camera test frame saved";
    }
}

void MainWin::on_saveS_button_clicked()
{
    if(side_frame.image.ptr()==nullptr){
        QMessageBox text;
        text.setText("Frame is not captured");
        text.exec();
        log<<"Tried to save Side camera test frame without frame";
    }else{
        saveDialog->setFrame(&side_frame);
        saveDialog->setModal(true);
        saveDialog->exec();
        log<<"Side camera test frame saved";
    }
}

void MainWin::on_camConfigF_button_clicked()
{
    QMessageBox text;
    if(front_camera == nullptr){
        text.setWindowTitle("WARNING");
        text.setText("Camera not assigned");
        text.exec();
        log<<"Tried to load Front camera setting without assigned camera";
        return;
    }
    QString filter = "All File (*.*) ;; XML File (*.xml)";
    QString filename = QFileDialog::getOpenFileName(this, "Select a XML file", QDir::homePath(),filter);
    bool result = front_camera->loadConfig(filename.toStdString());
    if(!result){
        text.setWindowTitle("WARNING");
        text.setText("Setting not able to load");
        text.exec();
        log<<"Loading Front camera setting aborted";
    }else{
        log<<"Front camera setting loaded from *.XML file";
    }
}

void MainWin::on_camConfigS_button_clicked()
{
    QMessageBox text;
    if(side_camera == nullptr){
        text.setWindowTitle("WARNING");
        text.setText("Camera not assigned");
        text.exec();
        log<<"Tried to load Side camera setting without assigned camera";
        return;
    }
    QString filter = "All File (*.*) ;; XML File (*.xml)";
    QString filename = QFileDialog::getOpenFileName(this, "Select a XML file", QDir::homePath(),filter);
    bool result = side_camera->loadConfig(filename.toStdString());
    if(!result){
        text.setWindowTitle("WARNING");
        text.setText("Setting not able to load");
        text.exec();
        log<<"Loading Side camera setting aborted";
    }else{
        log<<"Side camera setting loaded from *.XML file";
    }
}

void MainWin::on_actionRefresh_triggered()
{
    getCameras();
}

void MainWin::on_actionSave_All_frames_triggered()
{
    on_saveF_button_clicked();
    on_saveS_button_clicked();
}

void MainWin::on_actionShoot_All_triggered()
{
    on_shotF_button_clicked();
    on_shotS_button_clicked();
}


void MainWin::on_actionOnly_Front_view_triggered()
{
    QMessageBox text;
    QString filter = "All File (*.*) ;; PNG File (*.png)";
    QString filename = QFileDialog::getOpenFileName(this, "Select Front frame (*.PNG)", QDir::homePath(),filter);
    front_frame.image = cv::imread(filename.toStdString());
    if(front_frame.image.empty()){
        text.setWindowTitle("Error");
        text.setText("Is not possible to set Custom Front frame");
        text.exec();
        log<<"Loading custom Front frame aborted";
    }else{
        show_Front_Frame(front_frame, "orange");
        log<<"Custom Front frame loaded";
    }
}

void MainWin::on_actionOnly_Side_view_triggered()
{
    QMessageBox text;
    QString filter = "All File (*.*) ;; PNG File (*.png)";
    QString filename = QFileDialog::getOpenFileName(this, "Select Side frame (*.PNG)", QDir::homePath(),filter);
    side_frame.image = cv::imread(filename.toStdString());
    if(side_frame.image.empty()){
        text.setWindowTitle("Error");
        text.setText("Is not possible to set Custom Side frame");
        text.exec();
        log<<"Loading custom Side frame aborted";
    }else{
        show_Side_Frame(side_frame, "orange");
        log<<"Custom Side frame loaded";
    }
}

void MainWin::on_actionBoth_views_triggered()
{
    on_actionOnly_Front_view_triggered();
    on_actionOnly_Side_view_triggered();
}

void MainWin::show_Front_Frame(camera::frame frame, QString color)
{
    //QImage image((uchar*) frame.image.data, frame.image.cols, frame.image.rows, frame.image.step, QImage::Format_Grayscale16);
    QImage image;
    int const h=ui->pic_ShowF->height();
    int const w=ui->pic_ShowF->width();
    QString tmp_path = "/tmp/frameF.png";
    cv::imwrite(tmp_path.toStdString(),frame.image);
    image.load(tmp_path);
    QPixmap qPixmap(QPixmap::fromImage(image));
    ui->pic_ShowF->setPixmap(qPixmap.scaled(w,h,Qt::KeepAspectRatio, Qt::SmoothTransformation));
    ui->pic_ShowF->setAlignment(Qt::AlignCenter);
    if(color!=""){
        ui->pic_ShowF->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: "+color+";}");
    }
}

void MainWin::show_Side_Frame(camera::frame frame, QString color)
{
    //QImage image((uchar*) frame.image.data, frame.image.cols, frame.image.rows, frame.image.step, QImage::Format_Grayscale16);
    QImage image;
    int const h=ui->pic_ShowS->height();
    int const w=ui->pic_ShowS->width();
    QString tmp_path = "/tmp/frameS.png";
    cv::imwrite(tmp_path.toStdString(),frame.image);
    image.load(tmp_path);
    QPixmap qPixmap(QPixmap::fromImage(image));
    ui->pic_ShowS->setPixmap(qPixmap.scaled(w,h,Qt::KeepAspectRatio, Qt::SmoothTransformation));
    ui->pic_ShowS->setAlignment(Qt::AlignCenter);
    if(color!=""){
        ui->pic_ShowS->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: "+color+";}");
    }
}

void MainWin::on_actionFront_View_triggered()
{
    log<<"Openned CV setting parameters menu";
    setParameters_Utility = new cv_Params(nullptr,&log);
    setParameters_Utility->setParameters(this->parameters.cv);
    setParameters_Utility->setItem(features::eItem::pre_processing);
    setParameters_Utility->setModal(true);
    setParameters_Utility->exec();
    setParameters_Utility->unsetItem();
    setParameters_Utility->getParameters(this->parameters.cv);
    delete setParameters_Utility;
    log<<"Closed CV setting parameters menu";
}

void MainWin::on_actionLoad_Parameters_triggered()
{
    QMessageBox text;
    tcpc::sCAM_Parameters front_, side_;

    if(front_camera != nullptr) front_camera->close();
    if(side_camera != nullptr) side_camera->close();

    try {
        json_handler json;
        json.loadJSON(this->parameters, front_, side_);

        if(front_.serial != "NONE" && front_.idPf != "NONE" && front_.exposure > 20){
            this->front_camera = std::make_unique<interfaceBALLUFF::Camera>(front_.serial, front_.xmlPath);
            this->front_camera->set_idPf(front_.idPf);
            //front_camera->set_idPf(mvIMPACT::acquire::TImageDestinationPixelFormat::idpfRGB888Packed );
            this->front_camera->set_Exposure_us(front_.exposure);
            ui->comboBoxF->setCurrentIndex(this->front_camera->get_ID());
        }else{
            text.setWindowTitle("Warning");
            text.setText("bad Front Camera configuration, Not possible to connect to the Camera");
            text.exec();
            log<<("Not possible to connect to the Front Camera");
        }

        if(side_.serial != "NONE" && side_.idPf != "NONE" && side_.exposure > 20){
            this->side_camera = std::make_unique<interfaceBALLUFF::Camera>(side_.serial, side_.xmlPath);
            this->side_camera->set_idPf(side_.idPf);
            //side_camera->set_idPf(mvIMPACT::acquire::TImageDestinationPixelFormat::idpfRGB888Packed );
            this->side_camera->set_Exposure_us(side_.exposure);
            ui->comboBoxS->setCurrentIndex(this->side_camera->get_ID());
        }else{
            text.setWindowTitle("Warning");
            text.setText("bad Side Camera configuration, Not possible to connect to the Camera");
            text.exec();
            log<<("Not possible to connect to the Side Camera");
        }

        if(this->parameters.Robot.ipv4_Address != "" && this->parameters.Robot.type == "Staubli"){
            try {
                this->robot = new ri::Staubli(this->parameters.Robot);
                this->robot->setHome(this->parameters.Robot.default_position);
            } catch (...) {
                text.setWindowTitle("Warning");
                text.setText("Check TCP connection on Robot side, Not possible to establish connection");
                text.exec();
                log<<("bad TCP connection, Not possible to establish connection");
            }
        }

    } catch (...) {
        text.setWindowTitle("Error");
        text.setText("Selected *.JSON file not supported");
        text.exec();
        log<<("*.JSON file not supported");
        return;
    }
    text.setText("*.JSON file succesfully loaded");
    text.exec();
    log<<("*.JSON file was succesfully loaded");
}

void MainWin::on_actionSave_Parameters_triggered()
{
    tcpc::sCAM_Parameters front_, side_;

    if(this->front_camera != nullptr){
        front_.serial = this->front_camera->get_Name();
        front_.idPf = this->front_camera->get_idPf();
        front_.exposure = this->front_camera->get_Exposure_us();
    }
    if(this->side_camera != nullptr){
        side_.serial = this->side_camera->get_Name();
        side_.idPf = this->side_camera->get_idPf();
        side_.exposure = this->side_camera->get_Exposure_us();
    }

    try {
        json_handler json;
        json.saveJSON(this->parameters, front_, side_);
        log<<("*.JSON file was successfully saved");
        QMessageBox text;
        text.setText("JSON File was successfully saved");
        text.exec();
    } catch (...) {
        log<<("*.JSON file saving aborted");
        QMessageBox text;
        text.setText("JSON File saving aborted");
        text.exec();
    }
}

void MainWin::on_actionCalibrate_triggered()
{
    log<<("Cameras calibration started..");
    calib->setModal(true);
    calib->exec();
    this->parameters.stereo_camera = calib->getData();
    log<<("Cameras calibration finished..");
}

void MainWin::on_actionSet_Calibration_Point_triggered()
{
    if(this->front_frame.image.empty() || this->side_frame.image.empty()){
        log<<("Setting calibration point aborted..");
        QMessageBox text;
        text.setWindowTitle("Error");
        text.setText("Not possible to set Calibration point without frames");
        text.exec();
        return;
    }
    try {
        setCalibrate_Point();
    } catch (...) {
        QMessageBox text;
        text.setWindowTitle("Error");
        text.setText("Not possible to detect ArUco Marker ID# 21");
        text.exec();
        return;
    }

    QMessageBox text;
    text.setWindowTitle("Done");
    text.setText("Calibration Point Setted.");
    text.exec();
}

void MainWin::setCalibrate_Point(){
    cv::Mat frontMat;
    cv::Mat sideMat;
    if(this->front_frame.image.channels()==1){
        this->front_frame.image.convertTo(frontMat,CV_8UC1, 1/255.0);
        this->side_frame.image.convertTo(sideMat,CV_8UC1, 1/255.0);
    }else if(this->front_frame.image.channels()==3){
        if(this->front_frame.image.type()==18){
            this->front_frame.image.convertTo(frontMat,CV_8UC3, 1/255.0);
            this->side_frame.image.convertTo(sideMat,CV_8UC3, 1/255.0);
        }else{
            this->front_frame.image.copyTo(frontMat);
            this->side_frame.image.copyTo(sideMat);
        }
        cv::cvtColor(frontMat,frontMat,cv::COLOR_BGR2GRAY);
        cv::cvtColor(sideMat,sideMat,cv::COLOR_BGR2GRAY);
    }else{
        QMessageBox text;
        text.setWindowTitle("ERROR");
        text.setText("Unsupported Image format");
        text.exec();
        return;
    }

    std::vector<int> markerIdsF, markerIdsS;
    std::vector<std::vector<cv::Point2f>> markerCornersF, markerCornersS, rejectedCandidatesF, rejectedCandidatesS;
    cv::Ptr<cv::aruco::DetectorParameters> parameters = cv::aruco::DetectorParameters::create();
    cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
    cv::aruco::detectMarkers(frontMat, dictionary, markerCornersF, markerIdsF, parameters, rejectedCandidatesF);
    cv::aruco::detectMarkers(sideMat, dictionary, markerCornersS, markerIdsS, parameters, rejectedCandidatesS);

    if(markerCornersF.size()==0 || markerCornersS.size()==0) throw std::runtime_error("Not possible to detect ArUco Marker ID# 21");
    std::vector<cv::Vec3d> rvecsF, rvecsS, tvecsF, tvecsS;
    cv::aruco::estimatePoseSingleMarkers(markerCornersF, 25, this->parameters.stereo_camera.Front_cam.K_matrix, this->parameters.stereo_camera.Front_cam.Dist_coeffs, rvecsF, tvecsF);
    cv::aruco::estimatePoseSingleMarkers(markerCornersS, 25, this->parameters.stereo_camera.Side_cam.K_matrix, this->parameters.stereo_camera.Side_cam.Dist_coeffs, rvecsS, tvecsS);

    int rowF = 0, colF = 0;
    int rowS = 0, colS = 0;
    for(int i = 0; i<4; i++){
      rowF += markerCornersF.at(0).at(i).x;
      colF += markerCornersF.at(0).at(i).y;
      rowS += markerCornersS.at(0).at(i).x;
      colS += markerCornersS.at(0).at(i).y;
    }

    rowF /= 4;
    colF /= 4;
    rowS /= 4;
    colS /= 4;

    cv::Point midleF(rowF,colF);
    cv::Point midleS(rowS,colS);

    auto rvecF = rvecsF.at(0);
    auto tvecF = tvecsF.at(0);
    auto rvecS = rvecsS.at(0);
    auto tvecS = tvecsS.at(0);

    cv::aruco::drawAxis(this->front_frame.image, this->parameters.stereo_camera.Front_cam.K_matrix, this->parameters.stereo_camera.Front_cam.Dist_coeffs, rvecF, tvecF, 30);
    cv::drawMarker(this->front_frame.image, midleF,  cv::Scalar(0, 0, 255), cv::MARKER_CROSS, 40, 10);
    cv::aruco::drawAxis(this->side_frame.image, this->parameters.stereo_camera.Side_cam.K_matrix, this->parameters.stereo_camera.Side_cam.Dist_coeffs, rvecS, tvecS, 30);
    cv::drawMarker(this->side_frame.image, midleS,  cv::Scalar(0, 0, 255), cv::MARKER_CROSS, 40, 10);
    std::cout<<midleF<<midleS<<std::endl;
    //frontMat.copyTo(this->frameF.image);
    //sideMat.copyTo(this->frameS.image);
    show_Front_Frame(this->front_frame);
    show_Side_Frame(this->side_frame);

    this->parameters.tcpc.calibration_Point.front = midleF;
    this->parameters.tcpc.calibration_Point.side = midleS;
}

bool MainWin::isCalibrated(){
    //Front
    if(this->parameters.stereo_camera.Front_cam.K_matrix.at<_Float64>(2,2) == 1 &&
       this->parameters.stereo_camera.Side_cam.K_matrix.at<_Float64>(2,2) == 1 &&
       this->parameters.stereo_camera.Q_matrix.at<_Float64>(0) == 1){
        this->parameters.stereo_camera.Front_cam.Calibrated = true;
        this->parameters.stereo_camera.Side_cam.Calibrated = true;
        return true;
    }else{
        this->parameters.stereo_camera.Front_cam.Calibrated = false;
        this->parameters.stereo_camera.Side_cam.Calibrated = false;
        return false;
    }
}

void MainWin::on_actionGripper_colors_triggered()
{
    log<<"Openned Gripper color detection parameters menu";
    setParameters_Utility = new cv_Params(nullptr,&log);
    setParameters_Utility->setParameters(this->parameters.HSV_filter);
    setParameters_Utility->setItem(features::eItem::hsv_colors);
    setParameters_Utility->setModal(true);
    setParameters_Utility->exec();
    setParameters_Utility->unsetItem();
    setParameters_Utility->getParameters(this->parameters.HSV_filter);
    delete setParameters_Utility;
    log<<"Closed Gripper color detection parameters menu";
}

void MainWin::on_actionStart_triggered()
{ 
    if(this->side_camera != nullptr && this->front_camera != nullptr){
        continuousCapture->setFront(*this->front_camera);
        continuousCapture->setSide(*this->side_camera);
    }else{
        QMessageBox text;
        text.setWindowTitle("ERROR");
        text.setText("Cameras NOT setted");
        text.exec();
        return;
    }
    ui->comboBoxF->setEnabled(false);
    ui->comboBoxS->setEnabled(false);
    ui->saveF_button->setEnabled(false);
    ui->saveS_button->setEnabled(false);
    ui->shotF_button->setEnabled(false);
    ui->shotS_button->setEnabled(false);
    ui->start_button->setEnabled(false);
    ui->camConfigF_button->setEnabled(false);
    ui->camConfigS_button->setEnabled(false);
    ui->cancel_button->setEnabled(false);
    ui->menuSetting->setEnabled(false);
    ui->menuHelp->setEnabled(true);
    calibration_thread->stopFlag = false;
    continuousCapture->start();
}

void MainWin::on_actionSet_Connection_triggered()
{
    RobotComunnication_gui rcg(this->robot);
    rcg.setModal(true);
    rcg.exec();
    this->parameters.Robot = robot->getParameters();
}

void MainWin::on_actionSet_This_position_as_Default_triggered()
{
    this->parameters.Robot.default_position = this->robot->getPosition();
    this->robot->setHome(this->robot->getPosition());
}

void MainWin::on_actionStop_triggered()
{
    continuousCapture->stopFlag = true;
    ui->pic_ShowF->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: purple;}");
    ui->pic_ShowS->setStyleSheet("QLabel{border-style: solid; border-width: 5px; border-color: purple;}");
    ui->comboBoxF->setEnabled(true);
    ui->comboBoxS->setEnabled(true);
    ui->saveF_button->setEnabled(true);
    ui->saveS_button->setEnabled(true);
    ui->shotF_button->setEnabled(true);
    ui->shotS_button->setEnabled(true);
    ui->start_button->setEnabled(true);
    ui->camConfigF_button->setEnabled(true);
    ui->camConfigS_button->setEnabled(true);
    ui->cancel_button->setEnabled(false);
    ui->menuSetting->setEnabled(true);
    ui->menuHelp->setEnabled(true);
}

void MainWin::on_ShowStats(QString point, QString diff)
{
    QTableWidgetItem* numberItm = new QTableWidgetItem();
    numberItm->setFlags(numberItm->flags() ^ Qt::ItemIsEditable);
    QTableWidgetItem* pointItm = new QTableWidgetItem();
    pointItm->setFlags(pointItm->flags() ^ Qt::ItemIsEditable);
    QTableWidgetItem* diffItm = new QTableWidgetItem();
    diffItm->setFlags(diffItm->flags() ^ Qt::ItemIsEditable);
    QTableWidgetItem* timeItm = new QTableWidgetItem();
    timeItm->setFlags(timeItm->flags() ^ Qt::ItemIsEditable);

    ui->tableWidget->setRowCount(this->stats_CNT+1);

    numberItm->setText(QString::number(this->stats_CNT+1));
    pointItm->setText(point);
    diffItm->setText(diff);
    timeItm->setText(QTime::currentTime().toString("hh:mm:ss.z"));

    ui->tableWidget->setItem(this->stats_CNT/*row*/,0,numberItm);
    ui->tableWidget->setItem(this->stats_CNT/*row*/,1,pointItm);
    ui->tableWidget->setItem(this->stats_CNT/*row*/,2,diffItm);
    ui->tableWidget->setItem(this->stats_CNT/*row*/,3,timeItm);

    ui->tableWidget->resizeColumnToContents(0);
    ui->tableWidget->resizeColumnToContents(1);
    ui->tableWidget->resizeColumnToContents(2);
    ui->tableWidget->resizeColumnToContents(3);

    ui->tableWidget->verticalHeader()->setVisible(false);
    ui->tableWidget->sortItems(3,Qt::DescendingOrder);
    this->stats_CNT++;
}

void MainWin::on_actionReadme_triggered()
{
    std::thread(std::system,"evince ../source/instruct/instruct.pdf").detach();
}

void MainWin::on_actionGo_Home_triggered()
{
    if(!this->robot->isEstablished()){
        QMessageBox text;
        text.setWindowTitle("ERROR");
        text.setText("Robot NOT setted");
        text.exec();
        return;
    }else{
        if(!this->robot->atHome()) this->robot->goHome();
        QMessageBox text;
        text.setText("Robot IN HOME position");
        text.exec();
    }
}

void MainWin::on_actionCalibrate_2_triggered()
{
    if(!this->robot->isEstablished()){
        QMessageBox text;
        text.setWindowTitle("ERROR");
        text.setText("Robot NOT setted");
        text.exec();
        return;
    }else if(this->front_camera==nullptr || this->side_camera==nullptr){
        QMessageBox text;
        text.setWindowTitle("ERROR");
        text.setText("Cameras NOT setted");
        text.exec();
    }else if(!this->robot->atHome()) this->robot->goHome();

    Camera_Robot_Calibration(*this->robot,*this->front_camera,*this->side_camera,this->parameters,this->parameters.stereo_camera,log);

    QMessageBox text;
    text.setWindowTitle("Result");
    text.setText("Robot coordinates X: 1px -> "+QString::number(this->parameters.camera_robot.coordinates_offset.x)+" mm\n"+
                 "Robot coordinates Y: 1px -> "+QString::number(this->parameters.camera_robot.coordinates_offset.y)+" mm\n"+
                 "Robot coordinates Z: 1px -> "+QString::number(this->parameters.camera_robot.coordinates_offset.z)+" mm\n");
    text.exec();

    robot->goHome();
}

void MainWin::on_actionSet_default_positions_triggered()
{
    if(!this->robot->isEstablished()){
        QMessageBox text;
        text.setWindowTitle("WARNING");
        text.setText("Robot connection NOT established");
    }
    if(this->front_camera==nullptr || this->side_camera==nullptr){
        QMessageBox text;
        text.setWindowTitle("WARNING");
        text.setText("Cameras NOT setted");
        text.exec();
    }

    QMessageBox select;
    select.setWindowTitle("Camera - Robot calibration");
    select.setText("Go by the robot to the new position and press 'Set position'.");
    QAbstractButton *but = select.addButton(tr("Set position"), QMessageBox::ActionRole);
    select.exec();
    if(select.clickedButton() == but) this->parameters.camera_robot.position = this->robot->getPosition();
}

void MainWin::on_action1st_position_triggered()
{
    if(!this->robot->isEstablished()){
        QMessageBox text;
        text.setWindowTitle("WARNING");
        text.setText("Robot connection NOT established");
        text.exec();
    }

    QMessageBox select;
    QAbstractButton *bset;
    QAbstractButton *bgo;
    select.setWindowTitle("TCPC 1st default position");
    select.setText("Select what you want to do with this position.");
    QAbstractButton *bval = select.addButton(tr("Validate"), QMessageBox::ActionRole);

    if(this->robot->isEstablished()){
        bset = select.addButton(tr("Set"), QMessageBox::ActionRole);
        bgo = select.addButton(tr("to Position"), QMessageBox::ActionRole);
    }
    select.exec();

    if (select.clickedButton() == bval){
        if(this->front_camera == nullptr || this->side_camera == nullptr){
            QMessageBox text;
            text.setWindowTitle("WARNING");
            text.setText("Cameras NOT setted");
            text.exec();
        }
        try {
            this->on_shotF_button_clicked();
            this->on_shotS_button_clicked();

            std::vector<cv::Point> frontContours = tcpc::getSignificantContours(front_frame.image, parameters.HSV_filter.front, parameters.cv.Canny_threshold,
                                                                                                       parameters.cv.Dilate_thickness);
            std::vector<cv::Point> sideContours = tcpc::getSignificantContours(side_frame.image, parameters.HSV_filter.side, parameters.cv.Canny_threshold,
                                                                                                parameters.cv.Dilate_thickness);

            for(auto at: frontContours){
                cv::drawMarker(front_frame.image, at,  cv::Scalar(0, 0, 255), cv::MARKER_CROSS, 40, 10);
            }
            for(auto at: sideContours){
                cv::drawMarker(side_frame.image, at,  cv::Scalar(0, 0, 255), cv::MARKER_CROSS, 40, 10);
            }
            show_Front_Frame(front_frame, "orange");
            show_Side_Frame(side_frame, "orange");
        } catch (...) {
            QMessageBox text;
            text.setWindowTitle("ERROR");
            text.setText("NOT possible to detect Contours");
            text.exec();
        }
    }
    if (select.clickedButton() == bset){
        QMessageBox box;
        box.setText("Go by the robot to the new position and press 'Set position'.");
        QAbstractButton *but =
              box.addButton(tr("Set position"), QMessageBox::ActionRole);
        box.exec();
        if(box.clickedButton() == but) this->parameters.tcpc.default_tcpc_positions.at(0) = this->robot->getPositionJ();
    }
    if (select.clickedButton() == bgo){
        this->robot->setPositionJ(this->parameters.tcpc.default_tcpc_positions.at(0));
        QMessageBox box;
        box.setText("Robot reached setted position");
        box.exec();
    }
}

void MainWin::on_action2nd_position_triggered()
{
    if(!this->robot->isEstablished()){
        QMessageBox text;
        text.setWindowTitle("WARNING");
        text.setText("Robot connection NOT established");
        text.exec();
    }

    QMessageBox select;
    QAbstractButton *bset;
    QAbstractButton *bgo;
    select.setWindowTitle("TCPC 2nd default position");
    select.setText("Select what you want to do with this position.");
    QAbstractButton *bval = select.addButton(tr("Validate"), QMessageBox::ActionRole);

    if(this->robot->isEstablished()){
        bset = select.addButton(tr("Set"), QMessageBox::ActionRole);
        bgo = select.addButton(tr("to Position"), QMessageBox::ActionRole);
    }
    select.exec();

    if (select.clickedButton() == bval){
        if(this->front_camera == nullptr || this->side_camera == nullptr){
            QMessageBox text;
            text.setWindowTitle("WARNING");
            text.setText("Cameras NOT setted");
            text.exec();
        }
        try {
            this->on_shotF_button_clicked();
            this->on_shotS_button_clicked();

            std::vector<cv::Point> frontContours = tcpc::getSignificantContours(front_frame.image, parameters.HSV_filter.front, parameters.cv.Canny_threshold,
                                                                                                       parameters.cv.Dilate_thickness);
            std::vector<cv::Point> sideContours = tcpc::getSignificantContours(side_frame.image, parameters.HSV_filter.side, parameters.cv.Canny_threshold,
                                                                                                parameters.cv.Dilate_thickness);

            for(auto at: frontContours){
                cv::drawMarker(front_frame.image, at,  cv::Scalar(0, 0, 255), cv::MARKER_CROSS, 40, 10);
            }
            for(auto at: sideContours){
                cv::drawMarker(side_frame.image, at,  cv::Scalar(0, 0, 255), cv::MARKER_CROSS, 40, 10);
            }
            show_Front_Frame(front_frame, "orange");
            show_Side_Frame(side_frame, "orange");
        } catch (...) {
            QMessageBox text;
            text.setWindowTitle("ERROR");
            text.setText("NOT possible to detect Contours");
            text.exec();
        }
    }
    if (select.clickedButton() == bset){
        QMessageBox box;
        box.setText("Go by the robot to the new position and press 'Set position'.");
        QAbstractButton *but =
              box.addButton(tr("Set position"), QMessageBox::ActionRole);
        box.exec();
        if(box.clickedButton() == but) this->parameters.tcpc.default_tcpc_positions.at(1) = this->robot->getPositionJ();
    }
    if (select.clickedButton() == bgo){
        this->robot->setPositionJ(this->parameters.tcpc.default_tcpc_positions.at(1));
        QMessageBox box;
        box.setText("Robot reached setted position");
        box.exec();
    }
}

void MainWin::on_action3rd_position_triggered()
{
    if(!this->robot->isEstablished()){
        QMessageBox text;
        text.setWindowTitle("WARNING");
        text.setText("Robot connection NOT established");
        text.exec();
    }

    QMessageBox select;
    QAbstractButton *bset;
    QAbstractButton *bgo;
    select.setWindowTitle("TCPC 3rd default position");
    select.setText("Select what you want to do with this position.");
    QAbstractButton *bval = select.addButton(tr("Validate"), QMessageBox::ActionRole);
    if(this->robot->isEstablished()){
        bset = select.addButton(tr("Set"), QMessageBox::ActionRole);
        bgo = select.addButton(tr("to Position"), QMessageBox::ActionRole);
    }
    select.exec();

    if (select.clickedButton() == bval){
        if(this->front_camera == nullptr || this->side_camera == nullptr){
            QMessageBox text;
            text.setWindowTitle("WARNING");
            text.setText("Cameras NOT setted");
            text.exec();
        }
        try {
            this->on_shotF_button_clicked();
            this->on_shotS_button_clicked();

            std::vector<cv::Point> frontContours = tcpc::getSignificantContours(front_frame.image, parameters.HSV_filter.front, parameters.cv.Canny_threshold,
                                                                                                       parameters.cv.Dilate_thickness);
            std::vector<cv::Point> sideContours = tcpc::getSignificantContours(side_frame.image, parameters.HSV_filter.side, parameters.cv.Canny_threshold,
                                                                                                parameters.cv.Dilate_thickness);

            for(auto at: frontContours){
                cv::drawMarker(front_frame.image, at,  cv::Scalar(0, 0, 255), cv::MARKER_CROSS, 40, 10);
            }
            for(auto at: sideContours){
                cv::drawMarker(side_frame.image, at,  cv::Scalar(0, 0, 255), cv::MARKER_CROSS, 40, 10);
            }
            show_Front_Frame(front_frame, "orange");
            show_Side_Frame(side_frame, "orange");
        } catch (...) {
            QMessageBox text;
            text.setWindowTitle("ERROR");
            text.setText("NOT possible to detect Contours");
            text.exec();
        }
    }
    if (select.clickedButton() == bset){
        QMessageBox box;
        box.setText("Go by the robot to the new position and press 'Set position'.");
        QAbstractButton *but =
              box.addButton(tr("Set position"), QMessageBox::ActionRole);
        box.exec();
        if(box.clickedButton() == but) this->parameters.tcpc.default_tcpc_positions.at(2) = this->robot->getPositionJ();
    }
    if (select.clickedButton() == bgo){
        this->robot->setPositionJ(this->parameters.tcpc.default_tcpc_positions.at(2));
        QMessageBox box;
        box.setText("Robot reached setted position");
        box.exec();
    }
}

void MainWin::on_actionLoad_triggered()
{
    json_handler ss;
    ri::Point poi;
    ri::eRobot_TOOL tool;
    ss.loadTCP(poi , tool);
    if(poi.x==0){
        QMessageBox txt;
        txt.setWindowTitle("WARNING");
        txt.setText("NOT possible to load TCP from *.json");
        txt.exec();
        return;
    }
    this->TCP = poi;
    this->TCP_TOOL = tool;
    this->bTCP = true;
    this->robot->setTOOL(tool);
    this->robot->setTCP(this->TCP,this->TCP_TOOL);
    QMessageBox res;
    res.setText("TCP Loaded");
    res.exec();
}

void MainWin::on_actionSave_triggered()
{
    if(!bTCP){
        QMessageBox text;
        text.setWindowTitle("WARNING");
        text.setText("NO TCP to save");
        text.exec();
        return;
    }
    bool ok;
    json_handler tst;
    QMessageBox::StandardButton reply;
    reply = QMessageBox::question(this, "", "Do you want to change TOOL?",
                                QMessageBox::Yes|QMessageBox::No);
    if (reply == QMessageBox::Yes) {
        TCP_TOOL = (ri::eRobot_TOOL)QInputDialog::getInt(this, tr("Set TOOL"),tr("TOOL:"), 0, 0, 8, 1, &ok);
        if (ok) tst.saveTCP(TCP, TCP_TOOL);
    }
}

void MainWin::on_actionValidate_triggered()
{
    //Validate calibration
}

void MainWin::on_MeasurementProgressChanged(double no)
{
    ui->progress_Measurement->setValue(no);
}

void MainWin::on_CalculationProgressChanged(double no)
{
    ui->progress_Calculation->setValue(no);
}

void MainWin::on_actionTest_Detection_triggered()
{
    if(this->front_camera==nullptr || this->side_camera==nullptr){
        QMessageBox text;
        text.setWindowTitle("ERROR");
        text.setText("Cameras NOT setted");
        text.exec();
    }
    std::vector<cv::Point> frontContours = tcpc::getSignificantContours(front_frame.image, parameters.HSV_filter.front, parameters.cv.Canny_threshold,
                                                                                           parameters.cv.Dilate_thickness);
    std::vector<cv::Point> sideeContours = tcpc::getSignificantContours(side_frame.image, parameters.HSV_filter.side, parameters.cv.Canny_threshold,
                                                                                          parameters.cv.Dilate_thickness);

    for(auto at: frontContours){
        cv::drawMarker(front_frame.image, at,  cv::Scalar(0, 0, 255), cv::MARKER_CROSS, 40, 10);
    }
    for(auto at: sideeContours){
        cv::drawMarker(side_frame.image, at,  cv::Scalar(0, 0, 255), cv::MARKER_CROSS, 40, 10);
    }
    show_Front_Frame(front_frame, "orange");
    show_Side_Frame(side_frame, "orange");
}

void MainWin::on_actionSet_Default_triggered()
{
    QDialog dialog(this);
    QFormLayout form(&dialog);
    form.addRow(new QLabel("Enter default coordinates:"));
    dialog.setWindowTitle("Set default TCP");
    // Value1
    QString value1 = QString("x: ");
    QDoubleSpinBox *spinbox1 = new QDoubleSpinBox(&dialog);
    spinbox1->setRange(-500,500);
    spinbox1->setValue(this->parameters.tcpc.default_gripper.x);
    form.addRow(value1, spinbox1);
    // Value2
    QString value2 = QString("y: ");
    QDoubleSpinBox *spinbox2 = new QDoubleSpinBox(&dialog);
    spinbox2->setRange(-500,500);
    spinbox2->setValue(this->parameters.tcpc.default_gripper.y);
    form.addRow(value2, spinbox2);
    // Value3
    QString value3 = QString("z: ");
    QDoubleSpinBox *spinbox3 = new QDoubleSpinBox(&dialog);
    spinbox3->setRange(-500,500);
    spinbox3->setValue(this->parameters.tcpc.default_gripper.z);
    form.addRow(value3, spinbox3);
    // Add Cancel and OK button
    QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
        Qt::Horizontal, &dialog);
    form.addRow(&buttonBox);
    QObject::connect(&buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
    QObject::connect(&buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));

    // Process when OK button is clicked
    if (dialog.exec() == QDialog::Accepted) {
        this->parameters.tcpc.default_gripper.x = spinbox1->value();
        this->parameters.tcpc.default_gripper.y = spinbox2->value();
        this->parameters.tcpc.default_gripper.z = spinbox3->value();
    }
}

void MainWin::on_actionAbout_triggered()
{
    QMessageBox text;
    text.setWindowTitle("About");
    std::stringstream ss;
    ss<<" This Aplication is for Automatical TCP calibration"<<"\n";
    ss<<"\t   version 0.8"<<"\n";
    ss<<"\t released 5/20\n";
    ss<<"Created by David Sala as part of Master thesis";
    text.setText(ss.str().c_str());
    text.exec();
}
