/**
    05Robot - Computer Vision Module

    @author P.Kaczmarek,J.Tomczynski,T.Mankowski
    @version 1.0 2017
*/
/**
 * \defgroup UR Universal Robot Module
 * \brief Contains routines for pick and place actions and enabling communication with Universal Robot UR3, UR5 or UR10
 *
 * Contains routines enabling communication with Universal Robot UR3, UR5 or UR10. Module enables direct communication with UR robot by using
 * \ref UR3Intermediator class, however a more easy-to-use wrapper \ref UR3Workspace was prepared to handle basic tasks of object sorting.
 *
 * Additionally module contains \ref UR3CalibWidget widget prepared as an user interface for robot workspace calibration.
 *
 * Module example usage is presented below:
 *
 * \code
 *  UR3Workspace* UR3Workspace_ = new UR3Workspace();
 *  connect(UR3Workspace_, SIGNAL(commandStarted()), this, SLOT(changeToRunninng()));
 *  connect(UR3Workspace_, SIGNAL(commandExecuted()), this, SLOT(changeToIdle()));
 *  connect(ui->connect_r, SIGNAL(clicked(bool)), UR3Workspace_, SLOT(connectToRobot()));
 *  connect(ui->pushButton_2, SIGNAL(clicked(bool)), UR3Workspace_, SLOT(moveToWorkspaceHome()));
 *  connect(ui->pushButton_3, SIGNAL(clicked(bool)), UR3Workspace_, SLOT(moveOverBoard()));
 *  connect(this, SIGNAL(pickObject(QVector3D,float,int)), UR3Workspace_, SLOT(pickObject(QVector3D,float,int)));
 *
 *  UR3CalibWidget* UR3CalibWidget_ = new UR3CalibWidget(UR3Workspace_);
 *  connect(this->ui->pushButton, SIGNAL(clicked()), UR3CalibWidget_, SLOT(show()));
 * \endcode
 */
#ifndef UR3CALIBWIDGET_H
#define UR3CALIBWIDGET_H

#include <QWidget>
#include <QLineEdit>
#include <QLabel>
#include "UR3Workspace.h"


namespace Ui {
class UR3CalibWidget;
}

/** \addtogroup UR
 *  @{
 */
/**
 * @brief robot calibration user interface wizard for UR3Workspace class
 */
class UR3CalibWidget : public QWidget
{
    Q_OBJECT

public:
    /**
     * @brief default constructor
     * @param UR3W pointer to UR3Workspace for which calibration occurs
     * @param parent parent
     */
    explicit UR3CalibWidget(UR3Workspace* UR3W, QWidget *parent = 0);
    ~UR3CalibWidget();



private:
    enum CalibrationEnum{
        HOME,
        BOARD,
        CALIB_POINTS,
        OVER_BINS,
        BIN_ARRAY_START,
        BIN_ARRAY_END,
        BINS,
        FINISH
    };

    Ui::UR3CalibWidget *ui;

    UR3Workspace* UR3Workspace_;

    QVector<QLabel*> labelsPointers_;
    QVector<QLineEdit*> savedLinesPointers_;
    QVector<QLineEdit*> currentLinesPointers_;

    void startCalibration();

    void setJointStrings();
    void setCartesianStrings();

    void setEditsValues(QVector<double> data, char type);
    QVector<double> getEditValues(char type);

    QMap<int, BinDescriptor> binDescriptors_;
    QVector<double> homePosition_;
    QVector<double> boardPosition_;
    QVector<double> overBinPosition_;
    QMap<int, QVector<double> > calibrationPoints_;

    bool enableBinArrayMode_;
    QVector<double> arrayStartPosition_;
    QVector<double> arrayEndPosition_;

    CalibrationEnum calibrationState_ = HOME;
    QMap<int, BinDescriptor>::iterator binIterator_;
    QMap<int, QVector<double> >::iterator calibPointsIterator_;

    char currentDataType_ = 'j';

    void closeEvent(QCloseEvent *event);

signals:
    /**
     * @brief emitted on calibration finish
     * @param settingsChanged true if calibration finished successfully, false if procedure canceled
     */
    void calibrationFinished(bool settingsChanged);

private slots:
    void on_btn_next_clicked();
    void on_btn_cancel_clicked();
    void on_btn_transfer_clicked();
    void newPoseFromRobot(QVector<double> data, char type);

public slots:
    /**
     * @brief overloaded QWidget function, starts the calibration state machine and shows the calibration UI
     */
    void show();
};
/** @}*/
#endif // UR3CALIBWIDGET_H
