/* BEGIN software license
 *
 * msXpertSuite - mass spectrometry software suite
 * -----------------------------------------------
 * Copyright(C) 2009,...,2018 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>


/////////////////////// Local includes
#include <minexpert/gui/SaveToGraphicsFileDlg.hpp>


namespace msXpSmineXpert
{

SaveToGraphicsFileDlg::SaveToGraphicsFileDlg(QWidget *parent,
                                             AbstractPlotWidget *plot,
                                             const QString &applicationName)
  : QDialog{parent}, mp_plot{plot}, m_applicationName{applicationName}
{
  m_ui.setupUi(this);

  initialize();
}


SaveToGraphicsFileDlg::~SaveToGraphicsFileDlg()
{
}


void
SaveToGraphicsFileDlg::readSettings()
{
  QSettings 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);

  // Also restore the geometry of the window.
  restoreGeometry(settings.value("geometry").toByteArray());

  settings.endGroup();
}


void
SaveToGraphicsFileDlg::writeSettings()
{
  QSettings settings;
  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.setValue("geometry", saveGeometry());

  settings.endGroup();
}


void
SaveToGraphicsFileDlg::initialize()
{
  m_graphicsFormatMap.insert(GRAPHICS_FORMAT_PDF, "pdf");
  m_graphicsFormatMap.insert(GRAPHICS_FORMAT_PNG, "png");
  m_graphicsFormatMap.insert(GRAPHICS_FORMAT_JPG, "jpg");

  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_PNG,
    m_graphicsFormatMap.value(GRAPHICS_FORMAT_PNG));

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

  // 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_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_plot == Q_NULLPTR)
    qFatal(
      "Fatal error at %s@%d -- %s(). "
      "Pointer cannot be nullptr."
      "Program aborted.",
      __FILE__,
      __LINE__,
      __FUNCTION__);

  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();

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

  if(format != GraphicsFormat::GRAPHICS_FORMAT_PDF && 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_plot->savePdf(
          m_fileName, width, height, QCP::epNoCosmetic, creator, title);
        break;

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

      case GraphicsFormat::GRAPHICS_FORMAT_JPG:
        mp_plot->saveJpg(m_fileName, width, height, scale, /* quality */ 100);
        break;
    }

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


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


void
SaveToGraphicsFileDlg::formatItemChanged(int index)
{
  qDebug() << __FILE__ << __LINE__ << __FUNCTION__ << "()"
           << "Activated!: " << 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 msXpSmineXpert
