//      Hannah, GUI for downloading specific printer firmware
//      Copyright (C) 2007 Steffen Joeris <white@debian.org>
//      Copyright (C) 2017 Pino Toscano <pino@debian.org>
//
//    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 2 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, write to the Free Software Foundation, Inc.,
//    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

#include "gui.h"

#include <QAction>
#include <QApplication>
#include <QButtonGroup>
#include <QCheckBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QPushButton>
#include <QVBoxLayout>

MainWindow::MainWindow(QWidget *parent)
    : QWidget(parent)
{
    const QMessageBox::StandardButton check = QMessageBox::question(this,
            tr("Hannah - Firmware downloader"),
            tr("Do you want to download and install potential non-free printer firmware?"),
            QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
    if (check == QMessageBox::No) {
        exit(0);
    }

    createMainWidget();

    connect(&callProgram, SIGNAL(finished(int)), this, SLOT(checkProgram(int)));
}

void MainWindow::createMainWidget()
{
    setWindowTitle(tr("Hannah - Foo2zjs firmware downloader"));
    QVBoxLayout *mainLayout = new QVBoxLayout;

    buttonGroup = new QButtonGroup(this);
    buttonGroup->setExclusive(false);

    QMenuBar *menubar = new QMenuBar(this);
    QMenu *menu = new QMenu(menubar);
    menubar->addMenu(menu);
    QAction *about = new QAction(tr("About Hannah"), menu);
    menu = menubar->addMenu(tr("Help"));
    menu->addAction(about);
    mainLayout->addWidget(menubar);

    QGroupBox *groupbox = new QGroupBox(this);
    groupbox->setTitle(tr("Firmwares to download"));
    QGridLayout *groupLay = new QGridLayout(groupbox);
#define ADD(text, firmware) \
  do { \
    QCheckBox *cb = new QCheckBox(text, groupbox); \
    firmwareMappings.insert(cb, firmware); \
    buttonGroup->addButton(cb); \
    const int count = groupLay->count(); \
    groupLay->addWidget(cb, count / 2, count % 2); \
  } while (0)
    ADD(tr("HP2600"), QStringLiteral("2600n"));
    ADD(tr("HP1600"), QStringLiteral("1600"));
    ADD(tr("HP1020"), QStringLiteral("1020"));
    ADD(tr("HP1018"), QStringLiteral("1018"));
    ADD(tr("HP1005"), QStringLiteral("1005"));
    ADD(tr("HP1000"), QStringLiteral("1000"));
    ADD(tr("Minolta 2530"), QStringLiteral("2530"));
    ADD(tr("Minolta 2490"), QStringLiteral("2490"));
    ADD(tr("Minolta 2480"), QStringLiteral("2480"));
    ADD(tr("Minolta 2430"), QStringLiteral("2430"));
    ADD(tr("Minolta 2300"), QStringLiteral("2300"));
    ADD(tr("Minolta 2200"), QStringLiteral("2200"));
    ADD(tr("Minolta PageWorks/Pro L"), QStringLiteral("cpwl"));
    ADD(tr("Samsung CLX-3160"), QStringLiteral("3160"));
    ADD(tr("Samsung CLP-600"), QStringLiteral("600"));
    ADD(tr("Samsung CLP-300"), QStringLiteral("300"));
    ADD(tr("Xerox Phaser 6115"), QStringLiteral("6115"));
    ADD(tr("Xerox Phaser 6110"), QStringLiteral("6110"));
#undef ADD

    QHBoxLayout *hlay = new QHBoxLayout();
    QPushButton *markAllButton = new QPushButton(tr("&Mark All"), groupbox);
    hlay->addWidget(markAllButton);
    QPushButton *unmarkAllButton = new QPushButton(tr("&Unmark All"), groupbox);
    hlay->addWidget(unmarkAllButton);
    groupLay->addLayout(hlay, groupLay->rowCount(), 0, 1, 2);

    mainLayout->addWidget(groupbox);

    statusLabel = new QLabel(this);
    mainLayout->addWidget(statusLabel);

    downloadButton = new QPushButton(tr("&Download marked firmwares"));
    mainLayout->addWidget(downloadButton);

    exitButton = new QPushButton(tr("&Exit"));
    mainLayout->addWidget(exitButton);

    setLayout(mainLayout);

    connect(about, SIGNAL(triggered()), this, SLOT(showInfo()));
    connect(markAllButton, SIGNAL(clicked()), this, SLOT(slotMarkAll()));
    connect(unmarkAllButton, SIGNAL(clicked()), this, SLOT(slotUnmarkAll()));
    connect(downloadButton, SIGNAL(clicked()), this, SLOT(callGetweb()));
    connect(exitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
}

void MainWindow::showInfo()
{
    QMessageBox::information(this,
        tr("Hannah-Foo2zjs Firmware Downloader"),
        tr("This program is developed by the Debian Foo2ZJS maintainers.\n"
           "\n"
           "It is offered as a convenient method to download the needed "
           "firmware for one of the printers supported by Foo2ZJS.\n"
           "\n"
           "Please feel free to report any bugs against the foo2zjs package "
           "to the Debian BTS (https://bugs.debian.org).\n"
           "\n"
           "The program's name is Hannah:\n" 
           "(grapHical interfAce for dowNloading your priNter's firmwAre at Home)."),
        QMessageBox::Ok);
}

void MainWindow::slotMarkAll()
{
    foreach (QAbstractButton *button, buttonGroup->buttons()) {
        button->setChecked(true);
    }
}

void MainWindow::slotUnmarkAll()
{
    foreach (QAbstractButton *button, buttonGroup->buttons()) {
        button->setChecked(false);
    }
}

void MainWindow::callGetweb()
{
    QStringList arguments;

    foreach (QAbstractButton *button, buttonGroup->buttons()) {
        if (button->isChecked()) {
            arguments << firmwareMappings.value(button);
        }
    }

    if (arguments.isEmpty()) {
        return;
    }

    string = arguments.join(QLatin1Char(' '));

    arguments.prepend(QStringLiteral("/usr/sbin/getweb"));

    callProgram.start(QStringLiteral("pkexec"), arguments);
    statusLabel->setText(tr("Downloading firmware..."));
    downloadButton->setEnabled(false);
}

void MainWindow::checkProgram(int exitCode)
{
    downloadButton->setEnabled(true);

    switch (exitCode) {
    case 0:
        QMessageBox::information(this,
            tr("Hannah - Firmware downloader"),
            tr("The firmware for the following printers was downloaded and installed successfully:\n"
               "%1\n").arg(string),
            QMessageBox::Ok);
        statusLabel->setText(tr("Download and installation finished."));
        break;
    default: {
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Critical);
        msgBox.setWindowTitle(tr("Hannah - Firmware downloader"));
        msgBox.setText(tr("Something went wrong during the download and installation process for the following printers:\n"
                          "%1").arg(string));
        msgBox.setDetailedText(tr("The reported error was:\n"
                                  "%1").arg(QString::fromLocal8Bit(callProgram.readAllStandardError())));
        msgBox.setStandardButtons(QMessageBox::Ok);
        msgBox.exec();
        statusLabel->setText(tr("An error occurred during download and installation process."));
        break;
    }
    }
}
