/* BEGIN software license
 *
 * msXpertSuite - mass spectrometry software suite
 * -----------------------------------------------
 * Copyright (C) 2009--2020 Filippo Rusconi
 *
 * http://www.msxpertsuite.org
 *
 * This file is part of the msXpertSuite project.
 *
 * The msXpertSuite project is the successor of the massXpert project. This
 * project now includes various independent modules:
 *
 * - massXpert, model polymer chemistries and simulate mass spectrometric data;
 * - mineXpert, a powerful TIC chromatogram/mass spectrum viewer/miner;
 *
 * 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/>.
 *
 * END software license
 */


/////////////////////// Qt includes
#include <QObject>
#include <QDebug>
#include <QDialog>
#include <QWidget>
#include <QDir>
#include <QFileDialog>
#include <QMessageBox>
#include <QDate>
#include <QSettings>
#include <QLineEdit>
#include <QApplication>
#include <QClipboard>


/////////////////////// libXpertMassCore includes


/////////////////////// libXpertMassGui includes
#include <MsXpS/libXpertMassGui/WindowGeometryManager.hpp>


/////////////////////// Local includes
#include "Application.hpp"
#include "SaveToGraphicsFileDlg.hpp"
#include "ui_SaveToGraphicsFileDlg.h"

namespace MsXpS
{
namespace MineXpert
{

SaveToGraphicsFileDlg::SaveToGraphicsFileDlg(
  QWidget *parent,
  BasePlotCompositeWidget *plot_widget_p,
  const QString &application_name,
  const QString &sample_name,
  const QColor &color)
  : QDialog(parent),
    mp_plotWidget(plot_widget_p),
    m_applicationName(application_name),
    m_sampleName(sample_name),
    m_color(color),
    m_ui(new ::Ui::SaveToGraphicsFileDlg)
{
  m_ui->setupUi(this);

  initialize();
}

SaveToGraphicsFileDlg::~SaveToGraphicsFileDlg()
{
  QString settings_file_path =
    static_cast<Application *>(QCoreApplication::instance())
      ->getUserConfigSettingsFilePath();

  QSettings settings(settings_file_path, QSettings::IniFormat);

  qDebug() << "Saving window geometry.";

  libXpertMassGui::WindowGeometryManager::save(
    dynamic_cast<const QWidget *>(this), "SaveToGraphicsFileDlg", settings);
}

void
SaveToGraphicsFileDlg::readSettings()
{
  QString settings_file_path =
    static_cast<Application *>(QCoreApplication::instance())
      ->getUserConfigSettingsFilePath();

  QSettings settings(settings_file_path, QSettings::IniFormat);

  qDebug() << "Restoring window geometry.";

  libXpertMassGui::WindowGeometryManager::restore(this, "SaveToGraphicsFileDlg", settings);

  settings.beginGroup("SaveToGraphicsFileDlg");

  // No, let the pdf format be the real default one.
  // QString format = settings.value("format").toString();
  // m_ui->formatComboBox->setCurrentText(format);

  QString creator = settings.value("creator").toString();
  m_ui->creatorLineEdit->setText(creator);

  QString title = settings.value("title").toString();
  m_ui->titleLineEdit->setText(title);

  int width = settings.value("width").toInt();
  m_ui->widthSpinBox->setValue(width);

  int height = settings.value("height").toInt();
  m_ui->heightSpinBox->setValue(height);

  int scale = settings.value("scale", 1).toDouble();
  m_ui->scaleSpinBox->setValue(scale);

  settings.endGroup();
}

void
SaveToGraphicsFileDlg::writeSettings()
{
  // The window geometry is saved in the destructor, while
  // these bits are saved when OK is selected to actually write
  // the file.
  QString settings_file_path =
    static_cast<Application *>(QCoreApplication::instance())
      ->getUserConfigSettingsFilePath();

  QSettings settings(settings_file_path, QSettings::IniFormat);

  settings.beginGroup("SaveToGraphicsFileDlg");

  settings.setValue("format", m_ui->formatComboBox->currentText());
  settings.setValue("creator", m_ui->creatorLineEdit->text());
  settings.setValue("title", m_ui->titleLineEdit->text());
  settings.setValue("width", m_ui->widthSpinBox->value());
  settings.setValue("height", m_ui->heightSpinBox->value());
  settings.setValue("scale", m_ui->scaleSpinBox->value());


  settings.endGroup();
}

void
SaveToGraphicsFileDlg::initialize()
{
  m_ui->fileNameLineEdit->setText(m_sampleName);

  QPalette palette;
  palette.setColor(QPalette::Text, m_color);
  m_ui->fileNameLineEdit->setPalette(palette);

  m_graphicsFormatMap.insert(GRAPHICS_FORMAT_PDF, "pdf");
  m_graphicsFormatMap.insert(GRAPHICS_FORMAT_SVG, "svg");
  m_graphicsFormatMap.insert(GRAPHICS_FORMAT_PNG, "png");
  m_graphicsFormatMap.insert(GRAPHICS_FORMAT_JPG, "jpg");
  m_graphicsFormatMap.insert(GRAPHICS_FORMAT_CLIPBOARD, "clipboard");

  readSettings();

  connect(
    m_ui->formatComboBox,
    static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
    this,
    static_cast<void (SaveToGraphicsFileDlg::*)(int)>(
      &SaveToGraphicsFileDlg::formatItemChanged));

  m_ui->formatComboBox->insertItem(
    GraphicsFormat::GRAPHICS_FORMAT_PDF,
    m_graphicsFormatMap.value(GRAPHICS_FORMAT_PDF));

  m_ui->formatComboBox->insertItem(
    GraphicsFormat::GRAPHICS_FORMAT_SVG,
    m_graphicsFormatMap.value(GRAPHICS_FORMAT_SVG));

  m_ui->formatComboBox->insertItem(
    GraphicsFormat::GRAPHICS_FORMAT_PNG,
    m_graphicsFormatMap.value(GRAPHICS_FORMAT_PNG));

  m_ui->formatComboBox->insertItem(
    GraphicsFormat::GRAPHICS_FORMAT_JPG,
    m_graphicsFormatMap.value(GRAPHICS_FORMAT_JPG));

  m_ui->formatComboBox->insertItem(
    GraphicsFormat::GRAPHICS_FORMAT_CLIPBOARD,
    m_graphicsFormatMap.value(GRAPHICS_FORMAT_CLIPBOARD));

  // Now make sure the "pdf" item is currently displayed.

  m_ui->formatComboBox->setCurrentIndex(GraphicsFormat::GRAPHICS_FORMAT_PDF);

  connect(m_ui->fileNamePushButton, &QPushButton::clicked, [&]() {
    m_fileName = QFileDialog::getSaveFileName(
      this, "Please select the destination file name.", m_sampleName);
    m_ui->fileNameLineEdit->setText(m_fileName);
  });

  connect(m_ui->okPushButton,
          &QPushButton::clicked,
          this,
          &SaveToGraphicsFileDlg::okPushButton);
  connect(m_ui->cancelPushButton,
          &QPushButton::clicked,
          this,
          &SaveToGraphicsFileDlg::cancelPushButton);
}

void
SaveToGraphicsFileDlg::okPushButton()
{
  if(mp_plotWidget == Q_NULLPTR)
    qFatal() << "Programming error.";

  // We only need file names if the destination is not the clipboard.

  int format = m_ui->formatComboBox->currentIndex();

  if(format != GraphicsFormat::GRAPHICS_FORMAT_CLIPBOARD)
    {
      if(m_fileName.isEmpty())
        m_fileName = m_ui->fileNameLineEdit->text();

      if(m_fileName.isEmpty())
        {
          QMessageBox::information(this,
                                   "Save plot to graphics file",
                                   "Please, provide a destination file name.",
                                   QMessageBox::Ok);

          return;
        }
    }

  // The data seem to be fine, save them for next iteration use.
  writeSettings();

  int width  = m_ui->widthSpinBox->value();
  int height = m_ui->heightSpinBox->value();
  int scale  = m_ui->scaleSpinBox->value();

  if(format != GraphicsFormat::GRAPHICS_FORMAT_PDF &&
     format != GraphicsFormat::GRAPHICS_FORMAT_SVG)
    {
      if(scale == 0)
        {
          QMessageBox::information(this,
                                   "Save plot to graphics file",
                                   "Please, provide a non-0 scale factor.",
                                   QMessageBox::Ok);

          return;
        }
    }

  QString creator;
  QString title;

  switch(format)
    {
      case GraphicsFormat::GRAPHICS_FORMAT_PDF:
        creator = m_ui->creatorLineEdit->text();
        title   = m_ui->titleLineEdit->text();
        mp_plotWidget->savePlotToPdfFile(
          m_fileName, width, height, QCP::epNoCosmetic, creator, title);
        break;

      case GraphicsFormat::GRAPHICS_FORMAT_SVG:
        mp_plotWidget->savePlotToSvgFile(m_fileName);
        break;

      case GraphicsFormat::GRAPHICS_FORMAT_PNG:
        mp_plotWidget->savePlotToPngFile(
          m_fileName, width, height, scale, /* quality */ 100);
        break;

      case GraphicsFormat::GRAPHICS_FORMAT_JPG:
        mp_plotWidget->savePlotToJpgFile(
          m_fileName, width, height, scale, /* quality */ 100);
        break;

      case GraphicsFormat::GRAPHICS_FORMAT_CLIPBOARD:
        mp_plotWidget->saveRasterPlotToClipboard();
        break;
    }

  setResult(QDialog::Accepted);
  done(QDialog::Accepted);
}

void
SaveToGraphicsFileDlg::cancelPushButton()
{
  setResult(QDialog::Rejected);
  done(QDialog::Rejected);
}

void
SaveToGraphicsFileDlg::formatItemChanged(int index)
{
  QString text = m_ui->formatComboBox->itemText(index);

  if(text == "pdf")
    {
      m_ui->pdfCreatorTitleGroupBox->setVisible(true);
      m_ui->scaleLabel->setVisible(false);
      m_ui->scaleSpinBox->setVisible(false);
    }
  else
    {
      m_ui->pdfCreatorTitleGroupBox->setVisible(false);

      m_ui->scaleLabel->setVisible(true);
      m_ui->scaleSpinBox->setVisible(true);
    }
}


} // namespace MineXpert

} // namespace MsXpS
