/***
 * Warthog Robotics
 * University of Sao Paulo (USP) at Sao Carlos
 * http://www.warthog.sc.usp.br/
 *
 * This file is part of WRJoy project.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ***/

// Includes class header
#include <WRJoy/JoystickManagerGUI/joystickmanagergui.hh>

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

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

// Selects WRJoy namespace
using namespace WRJoy;


WRJoy::JoystickManagerGUI::JoystickManagerGUI::JoystickManagerGUI(JoystickManager* joystickManager) {
    _joystickManager = joystickManager;
    configureToolBar();
    configureTabWidget();
    configureMainWindow();
    configureConnections();
}


void WRJoy::JoystickManagerGUI::JoystickManagerGUI::configureMainWindow() {
    this->setWindowTitle(QString::fromUtf8("WRJoy 1.0"));
    this->setWindowIcon(QIcon(QString::fromUtf8("/usr/share/warthog-robotics/logos/wr_logo.svg")));
    this->resize(QSize(800,500));
    this->addToolBar(Qt::TopToolBarArea, _toolBar);
}


void WRJoy::JoystickManagerGUI::JoystickManagerGUI::configureToolBar() {
    _toolBar = new QToolBar(QString::fromUtf8("ToolBar"), this);
    _toolBar->setMovable(false);
    _toolBar->setFloatable(false);
    _toolBar->setIconSize(QSize(48,48));
    _toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

    _addJoystickAction = new QAction(QIcon(QString::fromUtf8(":/add_joystick.png")), QString::fromUtf8("Add joystick"), _toolBar);
    _addJoystickAction->setCheckable(false);
    _toolBar->addAction(_addJoystickAction);

    _delJoystickAction = new QAction(QIcon(QString::fromUtf8(":/del_joystick.png")), QString::fromUtf8("Delete joystick"), _toolBar);
    _delJoystickAction->setCheckable(false);
    _delJoystickAction->setEnabled(false);
    _toolBar->addAction(_delJoystickAction);

    _stopAllJoysticksAction = new QAction(QIcon(QString::fromUtf8(":/stop_joystick.png")), QString::fromUtf8("Stop all joysticks"), _toolBar);
    _stopAllJoysticksAction->setCheckable(false);
    _toolBar->addAction(_stopAllJoysticksAction);

    _toolBar->addSeparator();

    _resetServerConnectionAction = new QAction(QIcon(QString::fromUtf8(":/reset_server.png")), QString::fromUtf8("Reset server connection"), _toolBar);
    _resetServerConnectionAction->setCheckable(false);
    _toolBar->addAction(_resetServerConnectionAction);

    _toolBar->addSeparator();

    _resetAction = new QAction(QIcon(QString::fromUtf8(":/reset.png")), QString::fromUtf8("Reset software"), _toolBar);
    _resetAction->setCheckable(false);
    _toolBar->addAction(_resetAction);
}


void WRJoy::JoystickManagerGUI::JoystickManagerGUI::configureTabWidget() {
    _tabWidget = new QTabWidget();
    _tabWidget->setTabPosition(QTabWidget::North);
    _tabWidget->setIconSize(QSize(32,32));
    _tabWidget->addTab(new QWidget(), QIcon(QString::fromUtf8(":/server.png")), QString::fromUtf8("Server"));
    _tabWidget->addTab(new QWidget(), QString());
    _tabWidget->tabBar()->setTabEnabled(1,false);
    this->setCentralWidget(_tabWidget);
}


void WRJoy::JoystickManagerGUI::JoystickManagerGUI::configureConnections() {
    QObject::connect(_resetServerConnectionAction, &QAction::triggered, this, &WRJoy::JoystickManagerGUI::JoystickManagerGUI::resetServerConnection);
    QObject::connect(_addJoystickAction, &QAction::triggered, this, &WRJoy::JoystickManagerGUI::JoystickManagerGUI::addJoystick);
    QObject::connect(_delJoystickAction, &QAction::triggered, this, &WRJoy::JoystickManagerGUI::JoystickManagerGUI::delJoystick);
    QObject::connect(_stopAllJoysticksAction, &QAction::triggered, this, &WRJoy::JoystickManagerGUI::JoystickManagerGUI::stopAllJoysticks);
    QObject::connect(_resetAction, &QAction::triggered, this, &WRJoy::JoystickManagerGUI::JoystickManagerGUI::reset);
    QObject::connect(_tabWidget, &QTabWidget::currentChanged, this, &WRJoy::JoystickManagerGUI::JoystickManagerGUI::delJoystickActionHandler);
}


void WRJoy::JoystickManagerGUI::JoystickManagerGUI::addJoystick() {
    quint8 joystickNumber;
    joystickNumber    = _joystickManager->joysticks().size();
    QString inputText = QString::fromUtf8("Joystick ").append(QString::number(joystickNumber));

    bool    ok;
    QString joystickName;
    joystickName = QInputDialog::getText(this, QString::fromUtf8("Add Joystick"),
                                         QString::fromUtf8("Joystick name:"),
                                         QLineEdit::Normal, inputText, &ok);

    if (ok) {
        _joystickManager->addJoystick(joystickName);
        this->addJoystickTab(_joystickManager->joysticks().last());
    }
}


void WRJoy::JoystickManagerGUI::JoystickManagerGUI::delJoystick() {
    QString joystickName = _tabWidget->tabText(_tabWidget->currentIndex());

    QMessageBox::StandardButton response;

    response = QMessageBox::warning(this, this->windowTitle().append(QString::fromUtf8(" - Delete joystick")),
                                    QString::fromUtf8("Are you sure you want to delete ").append(joystickName).append(QString::fromUtf8("?")),
                                    QMessageBox::StandardButtons( QMessageBox::Yes | QMessageBox::No ),
                                    QMessageBox::No);

    if (response == QMessageBox::Yes) {
        _joystickManager->delJoystick(joystickName);
        _tabWidget->setCurrentIndex(0);
    }
}


void WRJoy::JoystickManagerGUI::JoystickManagerGUI::addJoystickTab(Joystick* joystick) {
    int tabIndex = _tabWidget->addTab(joystick->widget(), QIcon(QString::fromUtf8(":/joystick.png")), joystick->name());
    _tabWidget->setCurrentIndex(tabIndex);
}


void WRJoy::JoystickManagerGUI::JoystickManagerGUI::stopAllJoysticks() {
    QMessageBox::StandardButton response;

    response = QMessageBox::warning(this, this->windowTitle().append(QString::fromUtf8(" - Stop all joysticks")),
                                    QString::fromUtf8("Are you sure you want to stop all joysticks?"),
                                    QMessageBox::StandardButtons( QMessageBox::Yes | QMessageBox::No ),
                                    QMessageBox::No);

    if (response == QMessageBox::Yes) {
        _joystickManager->stopAllJoysticks();
    }
}


void WRJoy::JoystickManagerGUI::JoystickManagerGUI::resetServerConnection() {
    QMessageBox::StandardButton response;

    response = QMessageBox::warning(this, this->windowTitle().append(QString::fromUtf8(" - Reset server")),
                                    QString::fromUtf8("Are you sure you want to reset the server connection?"),
                                    QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No),
                                    QMessageBox::No);

    if (response == QMessageBox::Yes) {
        _tabWidget->setCurrentIndex(0);
    }
}


void WRJoy::JoystickManagerGUI::JoystickManagerGUI::reset() {
    QMessageBox::StandardButton response;

    response = QMessageBox::warning(this, this->windowTitle().append(QString::fromUtf8(" - Reset software")),
                                    QString::fromUtf8("Are you sure you want to reset the software?"),
                                    QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No),
                                    QMessageBox::No);

    if (response == QMessageBox::Yes) {
        _joystickManager->reset();
        delete(_tabWidget);
        this->configureTabWidget();
    }
}


void WRJoy::JoystickManagerGUI::JoystickManagerGUI::delJoystickActionHandler(int currentIndex) {
    if (currentIndex > 1) {
        _delJoystickAction->setEnabled(true);
    }
    else {
        _delJoystickAction->setEnabled(false);
    }
}
