/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK 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 Lesser General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/
#include "AboutAction.h"
#include "ReportBugDialog.h"

#include <Application.h>
#include <Core.h>

using namespace camitk;

#include <QBoxLayout>
#include <QLabel>
#include <QTextBrowser>
#include <QTabWidget>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QRegularExpression>

#include <vtkVersion.h>

// --------------- constructor -------------------
AboutAction::AboutAction(ActionExtension* extension) : Action(extension) {
    // Setting name, description and input component
    setName("About...");
    setEmbedded(false);
    setDescription(tr("Show a little dialog about the application"));
    setComponentClassName("");
    setIcon(QPixmap(":/camiTKIcon"));

    // Setting classification family and tags
    setFamily("Help");
    addTag(tr("About"));
}

// --------------- destructor -------------------
AboutAction::~AboutAction() {
    // do not delete the widget has it might have been used in the ActionViewer (i.e. the ownership might have been taken by the stacked widget)
}

// --------------- getWidget --------------
QWidget* AboutAction::getWidget() {
    return nullptr;
}

// --------------- apply -------------------
Action::ApplyStatus AboutAction::apply() {
    QDialog* aboutDialog = new QDialog();
    aboutDialog->setWindowTitle(tr("About ") + Application::getName() + "...");

    //-- Top parts : logo on the left, application name on the right
    QLabel* logoLabel = new QLabel();
    QPixmap camitkIcon(":/camiTKIcon");

    logoLabel->setPixmap(camitkIcon.scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
    QLabel* titleLabel = new QLabel(Application::getName());
    QFont titleFont = titleLabel->font();
    titleFont.setPointSize(18);
    titleFont.setBold(true);
    titleLabel->setFont(titleFont);

    QString version = QString(Core::version()).replace(QRegularExpression(R"(\w+ ([0-9]+\.[0-9]+\.\w+).*)"), R"(\1)");
    QLabel* versionLabel = new QLabel(version);
    QFont versionFont = versionLabel->font();
    versionFont.setPointSize(11);
    versionLabel->setFont(versionFont);
    versionLabel->setAlignment(Qt::AlignCenter);
    versionLabel->setAttribute(Qt::WA_TranslucentBackground);

    QHBoxLayout* topLayout = new QHBoxLayout();
    topLayout->addWidget(logoLabel, 0, Qt::AlignLeft | Qt::AlignVCenter);
    topLayout->addSpacing(10);
    QVBoxLayout* appLayout = new QVBoxLayout();
    appLayout->addWidget(titleLabel, 0, Qt::AlignLeft | Qt::AlignVCenter);
    appLayout->addWidget(versionLabel, 0, Qt::AlignLeft | Qt::AlignVCenter);
    topLayout->addLayout(appLayout);
    topLayout->addStretch();

    //-- Tab Widget
    QMap<QString, QString> tabTexts;
    tabTexts.insert("About",
                    "<p>" + Application::getName() + " " + version + tr(" is built with ") + "</p>"
                    + "<ul>"
                    + "<li>" + QString(Core::version()) + " " + QString((Core::isDebugBuild()) ? "Debug" : "Release") + "</li>"
                    + "<li> VTK " + QString(vtkVersion::GetVTKVersion()) + "</li>"
                    + "<li> Qt " + QString(qVersion()) + "</li>"
                    + "</ul>");
    tabTexts.insert("Python",
                    "<p>" + QString(Core::getPythonStatus()).replace("\n", "<br/>") + "</p>");
    tabTexts.insert("Contact",
                    "<p>" + tr("Please visit <a href='https://camitk.imag.fr'>camitk.imag.fr</a> for more information.") + "</p>");
    tabTexts.insert("Copyright",
                    "<p>" + tr("CamiTK is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3 only, as published by the Free Software Foundation.") + "</p>"
                    + "<p>" + tr("CamiTK 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 Lesser General Public License version 3 for more details" + "</p>"
                    + "<p>You should have received a copy of the GNU Lesser General Public License version 3 along with CamiTK.  If not, see <a href='http://www.gnu.org/licenses/'>GNU licenses website</a>.</p>");

    QTabWidget* aboutTabs = new QTabWidget();
    auto tabTextIt = tabTexts.begin();
    while (tabTextIt != tabTexts.end()) {
        QTextBrowser* tabTextBrowser = new QTextBrowser();
        tabTextBrowser->setHtml(tabTextIt.value());
        tabTextBrowser->setOpenExternalLinks(true);
        tabTextBrowser->setFrameShape(QFrame::NoFrame);
        tabTextBrowser->setReadOnly(true);
        tabTextBrowser->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
        tabTextBrowser->setTextInteractionFlags(Qt::TextSelectableByMouse);
        tabTextBrowser->setTextInteractionFlags(Qt::TextBrowserInteraction);
        tabTextBrowser->setStyleSheet(R"(
            QTextBrowser {
                background: transparent;
                border: none;
                padding: 0;
            }
        )");
        aboutTabs->addTab(tabTextBrowser, tabTextIt.key());
        ++tabTextIt;
    }

    //-- Middle part: buttons
    QPushButton* reportBugButton = new QPushButton(aboutDialog);
    reportBugButton->setText("Report Bug");
    ReportBugDialog* bugDialog = new ReportBugDialog();
    bugDialog->setBugReport();
    connect(reportBugButton, &QPushButton::clicked, bugDialog, &ReportBugDialog::exec);

    QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
    QPushButton* closeButton = buttonBox->button(QDialogButtonBox::Close);
    connect(closeButton, &QPushButton::clicked, aboutDialog, &QDialog::reject);
    closeButton->setDefault(true);
    closeButton->setFocus();

    QHBoxLayout* buttonLayout = new QHBoxLayout();
    buttonLayout->addWidget(reportBugButton);
    buttonLayout->addStretch();
    buttonLayout->addWidget(closeButton);

    //-- Copyright (should be updated with general year replacement)
    QLabel* copyrightLabel = new QLabel(QString::fromUtf8("© Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France"));
    QFont footerFont = copyrightLabel->font();
    footerFont.setPointSize(8);
    footerFont.setItalic(true);
    copyrightLabel->setFont(footerFont);
    copyrightLabel->setStyleSheet("color: gray;");
    copyrightLabel->setAlignment(Qt::AlignCenter);

    //-- Dialog assembly
    QVBoxLayout* dialogLayout = new QVBoxLayout(aboutDialog);
    dialogLayout->addLayout(topLayout);
    dialogLayout->addSpacing(5);
    dialogLayout->addWidget(aboutTabs);
    dialogLayout->addSpacing(5);
    dialogLayout->addLayout(buttonLayout);
    dialogLayout->addSpacing(5);
    dialogLayout->addWidget(copyrightLabel);

    aboutDialog->setLayout(dialogLayout);
    aboutDialog->setWindowIcon(QPixmap(":/camiTKIcon"));
    aboutDialog->exec();

    return SUCCESS;
}
