/*** WRJoy - JoystickGUI implementation
  ** Warthog Robotics
  ** University of Sao Paulo at Sao Carlos
  ** http://www.warthog.sc.usp.br
  ** This file is part of the Warthog Robotics project
  ***/


// Includes class header
#include <WRJoy/joystickgui.hh>

// Includes Qt library
#include <QtCore/QtCore>
#include <QtWidgets/QtWidgets>

// Includes WRJoy
#include <WRJoy/wrjoy.hh>

// Selects WRJoy namespace
using namespace WRJoy;


WRJoy::JoystickGUI::JoystickGUI(Joystick* joystick) {
    // Sets the controlled joystick
    _joystick = joystick;

    // Configures widget elements
    configureToolBar();
    configureTabWidget();
    configureMainWindow();

    // Configures elements connections
    configureConnections();
}


void WRJoy::JoystickGUI::configureMainWindow() {
    // Inserts the tool bar
    this->addToolBar(Qt::TopToolBarArea, _toolBar);

    // Inserts the tab widget
    this->setCentralWidget(_tabWidget);
}


void WRJoy::JoystickGUI::configureToolBar() {
    // Creates and configures the tool bar
    _toolBar = new QToolBar(QString::fromUtf8("ToolBar"), this);
    _toolBar->setMovable(false);
    _toolBar->setFloatable(false);
    _toolBar->setIconSize(QSize(32,32));
    _toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

    // Adds joystick run-time actions
    this->configureRunTimeActions(_toolBar);

    _toolBar->addSeparator();

    // Adds reset action
    this->configureAdvancedActions(_toolBar);
}


void WRJoy::JoystickGUI::configureRunTimeActions(QToolBar* toolBar) {
    // Adds the start joystick button
    _startJoystickAction = new QAction(QIcon(QString::fromUtf8(":/start.png")), QString::fromUtf8("Start joystick"), _toolBar);
    _startJoystickAction->setCheckable(false);
    _startJoystickAction->setEnabled(false);
    toolBar->addAction(_startJoystickAction);

    // Adds the stop joystick button
    _stopJoystickAction = new QAction(QIcon(QString::fromUtf8(":/stop.png")), QString::fromUtf8("Stop joystick"), _toolBar);
    _stopJoystickAction->setCheckable(false);
    _stopJoystickAction->setEnabled(false);
    toolBar->addAction(_stopJoystickAction);
}


void WRJoy::JoystickGUI::configureAdvancedActions(QToolBar* toolBar) {
    // Adds the reset joystick button
    _resetAction = new QAction(QIcon(QString::fromUtf8(":/reset.png")), QString::fromUtf8("Reset joystick"), _toolBar);
    _resetAction->setCheckable(false);
    toolBar->addAction(_resetAction);
}


void WRJoy::JoystickGUI::configureTabWidget() {
    // Creates and configures the XBox 360 controller monitor widget
    QWidget* monitor = new QWidget();
    QFormLayout* layout = new QFormLayout();

    layout->addRow(QString::fromUtf8("Name:"), new QLabel());
    layout->addRow(QString::fromUtf8("Axis 0:"), new QLabel());
    layout->addRow(QString::fromUtf8("Axis 1:"), new QLabel());
    layout->addRow(QString::fromUtf8("Axis 2:"), new QLabel());
    layout->addRow(QString::fromUtf8("Axis 3:"), new QLabel());
    layout->addRow(QString::fromUtf8("Axis 4:"), new QLabel());
    layout->addRow(QString::fromUtf8("Axis 5:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 0:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 1:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 2:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 3:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 4:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 5:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 6:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 7:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 8:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 9:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 10:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 11:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 12:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 13:"), new QLabel());
    layout->addRow(QString::fromUtf8("Button 14:"), new QLabel());
    monitor->setLayout(layout);
    monitor->setFont(QFont(QFont().defaultFamily(), 7));

    // Creates and configures the tab widget
    _tabWidget = new QTabWidget(this);
    _tabWidget->setTabPosition(QTabWidget::North);
    _tabWidget->setIconSize(QSize(24,24));

    // Adds SDL tab
    _tabWidget->addTab(new QWidget(), QIcon(QString::fromUtf8(":/joystick.png")), QString::fromUtf8("SDL"));
    _tabWidget->addTab(new QWidget(), QString());
    _tabWidget->tabBar()->setTabEnabled(1,false);

    // Adds monitor tab
    _tabWidget->addTab(monitor, QIcon(QString::fromUtf8(":/joystick.png")), QString::fromUtf8("Monitor"));
    _tabWidget->addTab(new QWidget(), QString());
    _tabWidget->tabBar()->setTabEnabled(1,false);

    // Adds players tab
    _tabWidget->addTab(new QWidget(), QIcon(QString::fromUtf8(":/joystick.png")), QString::fromUtf8("Controlled players"));
    _tabWidget->addTab(new QWidget(), QString());
    _tabWidget->tabBar()->setTabEnabled(1,false);

    // Adds advanced configuration tab
    _tabWidget->addTab(new QWidget(), QIcon(QString::fromUtf8(":/joystick.png")), QString::fromUtf8("Advanced configuration"));
}


void WRJoy::JoystickGUI::configureConnections() {
    QObject::connect(_startJoystickAction, &QAction::triggered, this, &WRJoy::JoystickGUI::startJoystick);
    QObject::connect(_stopJoystickAction, &QAction::triggered, this, &WRJoy::JoystickGUI::stopJoystick);
    QObject::connect(_resetAction, &QAction::triggered, this, &WRJoy::JoystickGUI::resetJoystick);
    QObject::connect(_joystick, &Joystick::started, this, &WRJoy::JoystickGUI::joystickStarted);
    QObject::connect(_joystick, &Joystick::finished, this, &WRJoy::JoystickGUI::joystickStoped);
    QObject::connect(_joystick, &Joystick::reseted, this, &WRJoy::JoystickGUI::joystickReseted);
}


void WRJoy::JoystickGUI::startJoystick() {
    // Starts the joystick
    _joystick->open(0); // GAMBIARRA!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    _joystick->start();
}


void WRJoy::JoystickGUI::stopJoystick() {
    // Shows a confirmation dialog
    QString dialogTitle   = _joystick->name().append(QString::fromUtf8(" - Stop joystick"));
    QString dialogMessage = QString::fromUtf8("Are you sure you want to stop ").append(_joystick->name()).append(QString::fromUtf8("?"));

    QMessageBox::StandardButton response;
    response = QMessageBox::warning(this, dialogTitle, dialogMessage,
                                    QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No),
                                    QMessageBox::No);

    // Stops the joystick
    if (response == QMessageBox::Yes) {
        _joystick->stop();
    }
}


void WRJoy::JoystickGUI::resetJoystick() {
    // Shows a confirmation dialog
    QString dialogTitle   = _joystick->name().append(QString::fromUtf8(" - Reset joystick"));
    QString dialogMessage = QString::fromUtf8("Are you sure you want to reset ").append(_joystick->name()).append(QString::fromUtf8("?"));

    QMessageBox::StandardButton response;
    response = QMessageBox::warning(this, dialogTitle, dialogMessage,
                                    QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No),
                                    QMessageBox::No);

    // Resets the joystick
    if (response == QMessageBox::Yes) {
        qWarning() << QString::fromUtf8("TODO: Reset joystick!!");
    }
}


void WRJoy::JoystickGUI::joystickStarted() {
    // Toogles run-time actions
    _startJoystickAction->setEnabled(false);
    _stopJoystickAction->setEnabled(true);
}

void WRJoy::JoystickGUI::joystickStoped() {
    // Toogles run-time actions
    _startJoystickAction->setEnabled(true);
    _stopJoystickAction->setEnabled(false);
}

void WRJoy::JoystickGUI::joystickReseted() {
    qWarning() << QString::fromUtf8("TODO: Joystick reseted!!");
}
