/* ============================================================
 *
 * This file is a part of digiKam project
 * https://www.digikam.org
 *
 * Date        : 2015-07-28
 * Description : Common widgets shared by Web Service tools
 *
 * Copyright (C) 2013      by Pankaj Kumar <me at panks dot me>
 * Copyright (C) 2015      by Shourya Singh Gupta <shouryasgupta at gmail dot com>
 * Copyright (C) 2016-2022 by Gilles Caulier <caulier dot gilles at gmail dot com>
 *
 * 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, 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.
 *
 * ============================================================ */

#include "wssettingswidget.h"

// Qt includes

#include <QLabel>
#include <QSpinBox>
#include <QCheckBox>
#include <QGroupBox>
#include <QRadioButton>
#include <QButtonGroup>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>
#include <QApplication>
#include <QComboBox>
#include <QScrollArea>

// KDE includes

#include <klocalizedstring.h>

namespace Digikam
{

class Q_DECL_HIDDEN WSSettingsWidget::Private
{
public:

    explicit Private(DInfoInterface* const interface, const QString& name)
        : imgList           (nullptr),
          uploadWidget      (nullptr),
          toolName          (name),
          headerLbl         (nullptr),
          userNameDisplayLbl(nullptr),
          changeUserBtn     (nullptr),
          dlDimensionCoB    (nullptr),
          settingsScrollArea(nullptr),
          albumsCoB         (nullptr),
          newAlbumBtn       (nullptr),
          reloadAlbumsBtn   (nullptr),
          originalChB       (nullptr),
          resizeChB         (nullptr),
          photoIdChB        (nullptr),
          dimensionSpB      (nullptr),
          imageQualitySpB   (nullptr),
          mainLayout        (nullptr),
          settingsBox       (nullptr),
          settingsBoxLayout (nullptr),
          albBox            (nullptr),
          albumsBoxLayout   (nullptr),
          optionsBox        (nullptr),
          optionsBoxLayout  (nullptr),
          uploadBox         (nullptr),
          uploadBoxLayout   (nullptr),
          sizeBox           (nullptr),
          sizeBoxLayout     (nullptr),
          accountBox        (nullptr),
          accountBoxLayout  (nullptr),
          iface             (interface),
          progressBar       (nullptr)
    {
    }

    DItemsList*                   imgList;
    QWidget*                       uploadWidget;
    QString                        toolName;

    QLabel*                        headerLbl;
    QLabel*                        userNameDisplayLbl;
    QPushButton*                   changeUserBtn;
    QComboBox*                     dlDimensionCoB;
    QScrollArea*                   settingsScrollArea;

    QComboBox*                     albumsCoB;
    QPushButton*                   newAlbumBtn;
    QPushButton*                   reloadAlbumsBtn;

    QCheckBox*                     originalChB;
    QCheckBox*                     resizeChB;
    QCheckBox*                     photoIdChB;
    QSpinBox*                      dimensionSpB;
    QSpinBox*                      imageQualitySpB;

    QHBoxLayout*                   mainLayout;

    QWidget*                       settingsBox;
    QVBoxLayout*                   settingsBoxLayout;

    QGroupBox*                     albBox;
    QGridLayout*                   albumsBoxLayout;

    QGroupBox*                     optionsBox;
    QGridLayout*                   optionsBoxLayout;

    QGroupBox*                     uploadBox;
    QVBoxLayout*                   uploadBoxLayout;

    QGroupBox*                     sizeBox;
    QVBoxLayout*                   sizeBoxLayout;

    QGroupBox*                     accountBox;
    QGridLayout*                   accountBoxLayout;

    DInfoInterface*                iface;
    DProgressWdg*                  progressBar;
};

WSSettingsWidget::WSSettingsWidget(QWidget* const parent,
                                   DInfoInterface* const iface,
                                   const QString& toolName)
    : QWidget(parent),
      d      (new Private(iface, toolName))
{
    setObjectName(d->toolName + QLatin1String(" Widget"));

    d->mainLayout         = new QHBoxLayout(this);
    d->imgList            = new DItemsList(this);
    d->settingsScrollArea = new QScrollArea(this);
    d->settingsBox        = new QWidget(d->settingsScrollArea);
    d->settingsBoxLayout  = new QVBoxLayout(d->settingsBox);
    d->headerLbl          = new QLabel(this);
    d->accountBox         = new QGroupBox(i18n("Account"), d->settingsBox);
    d->accountBoxLayout   = new QGridLayout(d->accountBox);
    d->userNameDisplayLbl = new QLabel(d->accountBox);
    d->changeUserBtn      = new QPushButton(d->accountBox);
    d->albBox             = new QGroupBox(i18n("Album"), d->settingsBox);
    d->albumsBoxLayout    = new QGridLayout(d->albBox);
    d->albumsCoB          = new QComboBox(d->albBox);
    d->newAlbumBtn        = new QPushButton(d->accountBox);
    d->reloadAlbumsBtn    = new QPushButton(d->accountBox);
    d->sizeBox            = new QGroupBox(i18n("Max Dimension"), d->settingsBox);
    d->sizeBoxLayout      = new QVBoxLayout(d->sizeBox);
    d->dlDimensionCoB     = new QComboBox(d->sizeBox);
    d->uploadBox          = new QGroupBox(i18n("Destination"), d->settingsBox);
    d->uploadWidget       = iface->uploadWidget(d->uploadBox);
    d->uploadBoxLayout    = new QVBoxLayout(d->uploadBox);
    d->optionsBox         = new QGroupBox(i18n("Options"), d->settingsBox);
    d->optionsBoxLayout   = new QGridLayout(d->optionsBox);
    d->originalChB        = new QCheckBox(d->optionsBox);
    d->resizeChB          = new QCheckBox(d->optionsBox);
    d->photoIdChB         = new QCheckBox(d->optionsBox);
    d->dimensionSpB       = new QSpinBox(d->optionsBox);
    d->imageQualitySpB    = new QSpinBox(d->optionsBox);
    d->progressBar        = new DProgressWdg(d->settingsBox);

    //----------------------------------------------------------

    const int spacing = QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);

    d->imgList->setObjectName(QLatin1String("WebService ImagesList"));
    d->imgList->setControlButtonsPlacement(DItemsList::ControlButtonsBelow);
    d->imgList->setAllowRAW(true);
    d->imgList->listView()->setWhatsThis(i18n("This is the list of images "
                                              "to upload to your %1 account.", d->toolName));
    d->imgList->setIface(d->iface);
    d->imgList->loadImagesFromCurrentSelection();

    d->settingsScrollArea->setMinimumSize(400, 500);
    d->settingsScrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
    d->settingsScrollArea->setWidget(d->settingsBox);
    d->settingsScrollArea->setWidgetResizable(true);
    d->settingsScrollArea->setFrameShadow(QFrame::Plain);

    d->headerLbl->setWhatsThis(i18n("This is a clickable link to open %1 in a browser.", d->toolName));
    d->headerLbl->setOpenExternalLinks(true);
    d->headerLbl->setFocusPolicy(Qt::NoFocus);

    //------------------------------------------------------------

    d->accountBox->setWhatsThis(i18n("This is the %1 account that is currently logged in.", d->toolName));

    QLabel* const userNameLbl = new QLabel(i18nc("account settings","Name:"), d->accountBox);
    d->changeUserBtn->setText(i18n("Change Account"));
    d->changeUserBtn->setIcon(QIcon::fromTheme(QLatin1String("system-switch-user")).pixmap(16));
    d->changeUserBtn->setToolTip(i18n("Change %1 account for transfer", d->toolName));

    d->accountBoxLayout->addWidget(userNameLbl,             0, 0, 1, 2);
    d->accountBoxLayout->addWidget(d->userNameDisplayLbl, 0, 2, 1, 2);
    d->accountBoxLayout->addWidget(d->changeUserBtn,      1, 0, 1, 4);
    d->accountBoxLayout->setContentsMargins(spacing, spacing, spacing, spacing);
    d->accountBoxLayout->setSpacing(spacing);

    //-------------------------------------------------------------

    d->albBox->setWhatsThis(i18n("This is the %1 folder to/from which selected "
                                 "photos will be uploaded/downloaded.", d->toolName));

    QLabel* const albLbl = new QLabel(i18n("Album:"), d->albBox);

    d->albumsCoB->setEditable(false);

    d->newAlbumBtn->setText(i18n("New Album"));
    d->newAlbumBtn->setIcon(QIcon::fromTheme(QLatin1String("list-add")).pixmap(16));
    d->newAlbumBtn->setToolTip(i18n("Create new %1 folder", d->toolName));

    d->reloadAlbumsBtn->setText(i18nc("album list","Reload"));
    d->reloadAlbumsBtn->setIcon(QIcon::fromTheme(QLatin1String("view-refresh")).pixmap(16));
    d->reloadAlbumsBtn->setToolTip(i18n("Reload album list"));

    d->albumsBoxLayout->addWidget(albLbl,             0, 0, 1, 1);
    d->albumsBoxLayout->addWidget(d->albumsCoB,       0, 1, 1, 4);
    d->albumsBoxLayout->addWidget(d->newAlbumBtn,     1, 3, 1, 1);
    d->albumsBoxLayout->addWidget(d->reloadAlbumsBtn, 1, 4, 1, 1);

    //----------------------------------------------------------

    d->sizeBox->setWhatsThis(i18n("This is the maximum dimension of the images. "
                                  "Images larger than this will be scaled down."));
    d->dlDimensionCoB->addItem(i18n("Original Size"), QLatin1String("d"));
    d->dlDimensionCoB->addItem(i18n("1600 px"), QLatin1String("1600"));
    d->dlDimensionCoB->addItem(i18n("1440 px"), QLatin1String("1440"));
    d->dlDimensionCoB->addItem(i18n("1280 px"), QLatin1String("1280"));
    d->dlDimensionCoB->addItem(i18n("1152 px"), QLatin1String("1152"));
    d->dlDimensionCoB->addItem(i18n("1024 px"), QLatin1String("1024"));
    d->dlDimensionCoB->setCurrentIndex(0);
    d->sizeBoxLayout->addWidget(d->dlDimensionCoB);

    // ------------------------------------------------------------------------

    d->uploadBox->setWhatsThis(i18n("This is the location where %1 "
                                    "images will be downloaded.", d->toolName));
    d->uploadBoxLayout->addWidget(d->uploadWidget);

    //-----------------------------------------------------------

    d->optionsBox->setWhatsThis(i18n("These are the options that would "
                                     "be applied to photos before upload."));

    d->originalChB->setText(i18n("Upload original image file"));
    d->originalChB->setChecked(false);
    d->originalChB->hide();

    d->resizeChB->setText(i18n("Resize photos before uploading"));
    d->resizeChB->setChecked(false);

    d->photoIdChB->setText(i18n("Write the photo ID to the source image"));
    d->photoIdChB->setWhatsThis(i18n("Write the photo ID as metadata in "
                                     "the source image after uploading."));
    d->photoIdChB->setChecked(false);
    d->photoIdChB->hide();

    d->dimensionSpB->setMinimum(0);
    d->dimensionSpB->setMaximum(5000);
    d->dimensionSpB->setSingleStep(10);
    d->dimensionSpB->setValue(1600);
    d->dimensionSpB->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    d->dimensionSpB->setEnabled(false);

    QLabel* const dimensionLbl = new QLabel(i18n("Maximum Dimension:"), d->optionsBox);

    d->imageQualitySpB->setMinimum(0);
    d->imageQualitySpB->setMaximum(100);
    d->imageQualitySpB->setSingleStep(1);
    d->imageQualitySpB->setValue(90);
    d->imageQualitySpB->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    QLabel* const imageQualityLbl = new QLabel(i18n("JPEG Quality:"), d->optionsBox);

    d->optionsBoxLayout->addWidget(d->originalChB,     0, 0, 1, 5);
    d->optionsBoxLayout->addWidget(d->resizeChB,       1, 0, 1, 5);
    d->optionsBoxLayout->addWidget(imageQualityLbl,    2, 1, 1, 1);
    d->optionsBoxLayout->addWidget(d->imageQualitySpB, 2, 2, 1, 1);
    d->optionsBoxLayout->addWidget(dimensionLbl,       3, 1, 1, 1);
    d->optionsBoxLayout->addWidget(d->dimensionSpB,    3, 2, 1, 1);
    d->optionsBoxLayout->addWidget(d->photoIdChB,      4, 0, 1, 5);
    d->optionsBoxLayout->setRowStretch(5, 10);
    d->optionsBoxLayout->setSpacing(spacing);
    d->optionsBoxLayout->setContentsMargins(spacing, spacing, spacing, spacing);

    d->progressBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
    d->progressBar->hide();

    //------------------------------------------------------

    d->settingsBoxLayout->addWidget(d->headerLbl);
    d->settingsBoxLayout->addWidget(d->accountBox);
    d->settingsBoxLayout->addWidget(d->albBox);
    d->settingsBoxLayout->addWidget(d->sizeBox);
    d->settingsBoxLayout->addWidget(d->uploadBox);
    d->settingsBoxLayout->addWidget(d->optionsBox);
    d->settingsBoxLayout->addWidget(d->progressBar);
    d->settingsBoxLayout->setSpacing(spacing);
    d->settingsBoxLayout->setContentsMargins(spacing, spacing, spacing, spacing);

    //--------------------------------------------------------

    d->mainLayout->addWidget(d->imgList);
    d->mainLayout->addWidget(d->settingsScrollArea);
    d->mainLayout->setContentsMargins(QMargins());
    d->mainLayout->setSpacing(spacing);

    //-------------------------------------------------------

    connect(d->originalChB, SIGNAL(toggled(bool)),
            this, SLOT(slotResizeChecked()));

    connect(d->resizeChB, SIGNAL(toggled(bool)),
            this, SLOT(slotResizeChecked()));
}

WSSettingsWidget::~WSSettingsWidget()
{
    delete d;
}

QString WSSettingsWidget::getDestinationPath() const
{
    QUrl url = d->iface->uploadUrl();
    return url.toLocalFile();
}

DItemsList* WSSettingsWidget::imagesList() const
{
    return d->imgList;
}

void WSSettingsWidget::slotResizeChecked()
{
    d->resizeChB->setEnabled(!d->originalChB->isChecked());
    d->imageQualitySpB->setEnabled(!d->originalChB->isChecked());
    d->dimensionSpB->setEnabled(d->resizeChB->isChecked() && !d->originalChB->isChecked());
}

DProgressWdg* WSSettingsWidget::progressBar() const
{
    return d->progressBar;
}

void WSSettingsWidget::addWidgetToSettingsBox(QWidget* const widget)
{
    d->settingsBoxLayout->addWidget(widget);

    // NOTE: This is important because progress bar always has to be at the end of settings box layout.
    // So we remove it and then add it back.

    d->settingsBoxLayout->removeWidget(d->progressBar);

    d->settingsBoxLayout->addWidget(d->progressBar);
}

void WSSettingsWidget::replaceImageList(QWidget* const imgList)
{
    d->imgList->hide();
    d->mainLayout->removeWidget(d->imgList);
    d->mainLayout->insertWidget(0, imgList);
}

QWidget* WSSettingsWidget::getSettingsBox() const
{
    return d->settingsBox;
}

QVBoxLayout* WSSettingsWidget::getSettingsBoxLayout() const
{
    return d->settingsBoxLayout;
}

QGroupBox* WSSettingsWidget::getAlbumBox() const
{
    return d->albBox;
}

QGridLayout* WSSettingsWidget::getAlbumBoxLayout() const
{
    return d->albumsBoxLayout;
}

QGroupBox* WSSettingsWidget::getOptionsBox() const
{
    return d->optionsBox;
}

QGridLayout* WSSettingsWidget::getOptionsBoxLayout() const
{
    return d->optionsBoxLayout;
}

QGroupBox* WSSettingsWidget::getUploadBox() const
{
    return d->uploadBox;
}

QVBoxLayout* WSSettingsWidget::getUploadBoxLayout() const
{
    return d->uploadBoxLayout;
}

QGroupBox* WSSettingsWidget::getSizeBox() const
{
    return d->sizeBox;
}

QVBoxLayout* WSSettingsWidget::getSizeBoxLayout() const
{
    return d->sizeBoxLayout;
}

QGroupBox* WSSettingsWidget::getAccountBox() const
{
    return d->accountBox;
}

QGridLayout* WSSettingsWidget::getAccountBoxLayout() const
{
    return d->accountBoxLayout;
}

QLabel* WSSettingsWidget::getHeaderLbl() const
{
    return d->headerLbl;
}

QLabel* WSSettingsWidget::getUserNameLabel() const
{
    return d->userNameDisplayLbl;
}

QPushButton* WSSettingsWidget::getChangeUserBtn() const
{
    return d->changeUserBtn;
}

QComboBox* WSSettingsWidget::getDimensionCoB() const
{
    return d->dlDimensionCoB;
}

QPushButton* WSSettingsWidget::getNewAlbmBtn() const
{
    return d->newAlbumBtn;
}

QPushButton* WSSettingsWidget::getReloadBtn() const
{
    return d->reloadAlbumsBtn;
}

QCheckBox* WSSettingsWidget::getOriginalCheckBox() const
{
    return d->originalChB;
}

QCheckBox* WSSettingsWidget::getResizeCheckBox() const
{
    return d->resizeChB;
}

QCheckBox* WSSettingsWidget::getPhotoIdCheckBox() const
{
    return d->photoIdChB;
}

QSpinBox* WSSettingsWidget::getDimensionSpB() const
{
    return d->dimensionSpB;
}

QSpinBox* WSSettingsWidget::getImgQualitySpB() const
{
    return d->imageQualitySpB;
}

QComboBox* WSSettingsWidget::getAlbumsCoB() const
{
    return d->albumsCoB;
}

} // namespace Digikam
