/* BEGIN software license
 *
 * msXpertSuite - mass spectrometry software suite
 * -----------------------------------------------
 * Copyright 2009--2026 by 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 <QMessageBox>
#include <QSettings>


/////////////////////// Local includes
#include "MsXpS/libXpertMassCore/globals.hpp"
#include "MsXpS/libXpertMassGui/DecimalPlacesOptionsDlg.hpp"

#include "ui_DecimalPlacesOptionsDlg.h"

namespace MsXpS
{
namespace libXpertMassGui
{

/*!
\class MsXpS::libXpertMassGui::DecimalPlacesOptionsDlg
\inmodule libXpertMassGui
\ingroup XpertMassGuiUtilities
\inheaderfile DecimalPlacesOptionsDlg.hpp

\brief The DecimalPlacesOptionsDlg class provides a means to configure
the number of decimals that numbers should have when printed as text.
*/

/*!
\variable MsXpS::libXpertMassGui::DecimalPlacesOptionsDlg::m_atomDecPlaces

\brief The number of digits after the decimal separator symbol ('.') when
printing out the mass of atoms or isotopes (default = 10).
*/

/*!
\variable MsXpS::libXpertMassGui::DecimalPlacesOptionsDlg::m_oligomerDecPlaces

\brief The number of digits after the decimal separator symbol ('.') when
printing out the mass of oligomers (default = 6).
*/

/*!
\variable MsXpS::libXpertMassGui::DecimalPlacesOptionsDlg::m_polymerDecPlaces

\brief The number of digits after the decimal separator symbol ('.') when
printing out the mass of polymers (default = 3).
*/

/*!
\variable MsXpS::libXpertMassGui::DecimalPlacesOptionsDlg::m_pkaPhPiDecPlaces

\brief The number of digits after the decimal separator symbol ('.') when
printing out pH, pKa, pI values (default = 3).
*/

/*!
\brief Constructs a DecimalPlacesOptionsDlg instance with \a
config_settings_file_path and setting \a parent.

If \a config_settings_file_path points to a valid file, the settings are read
from there and set to the the dialog widgets.
*/
DecimalPlacesOptionsDlg::DecimalPlacesOptionsDlg(
  [[maybe_unused]] const QString &config_settings_file_path, QWidget *parent)
  : QDialog(parent), mp_ui(new Ui::DecimalPlacesOptionsDlg)
{
  mp_ui->setupUi(this);

  QSettings settings(m_configSettingsFilePath, QSettings::IniFormat);

  settings.beginGroup("decimal_places_options_dlg");

  restoreGeometry(settings.value("geometry").toByteArray());

  settings.endGroup();

  // Make now the connections that we will rely upon when
  // reading places settings and set them to the widgets
  // which will be reported to the member data.
  connect(mp_ui->atomDecimalPlacesSpinBox,
          &QSpinBox::valueChanged,
          this,
          [&](int value) {
            m_atomDecPlaces = value;
          });

  connect(mp_ui->oligomerDecimalPlacesSpinBox,
          &QSpinBox::valueChanged,
          this,
          [&](int value) {
            m_oligomerDecPlaces = value;
          });

  connect(mp_ui->polymerDecimalPlacesSpinBox,
          &QSpinBox::valueChanged,
          this,
          [&](int value) {
            m_polymerDecPlaces = value;
          });

  connect(mp_ui->pKaPhPiDecimalPlacesSpinBox,
          &QSpinBox::valueChanged,
          this,
          [&](int value) {
            m_pkaPhPiDecPlaces = value;
          });

  connect(mp_ui->validatePushButton,
          &QPushButton::clicked,
          this,
          &DecimalPlacesOptionsDlg::validate);

  settings.beginGroup("decimal_places_options");

  updateDecimalPlaces(
    settings.value("ATOM_DEC_PLACES", libXpertMassCore::ATOM_DEC_PLACES)
      .toInt(),
    settings.value("OLIGOMER_DEC_PLACES", libXpertMassCore::OLIGOMER_DEC_PLACES)
      .toInt(),
    settings.value("POLYMER_DEC_PLACES", libXpertMassCore::POLYMER_DEC_PLACES)
      .toInt(),
    settings
      .value("PKA_PH_PI_DEC_PLACES", libXpertMassCore::PKA_PH_PI_DEC_PLACES)
      .toInt());

  settings.endGroup();
}

/*!
\brief Constructs a DecimalPlacesOptionsDlg instance.

The values for the various chemical entities are set from global values.
*/
DecimalPlacesOptionsDlg::DecimalPlacesOptionsDlg()
  : DecimalPlacesOptionsDlg("", nullptr)
{
  // This constructor uses the construction delegate form (C++-11)
  // by calling the other constructor in the member initializer list.
}

DecimalPlacesOptionsDlg::~DecimalPlacesOptionsDlg()
{
}

/*!
\brief Updates the decimal places values for \a atom, \a oligo, \a poly and \a
ph_pka.
*/
void
DecimalPlacesOptionsDlg::updateDecimalPlaces(int atom,
                                             int oligo,
                                             int poly,
                                             int pka_ph)
{
  // Will automagically update the member data.
  mp_ui->atomDecimalPlacesSpinBox->setValue(atom);
  mp_ui->oligomerDecimalPlacesSpinBox->setValue(oligo);
  mp_ui->polymerDecimalPlacesSpinBox->setValue(poly);
  mp_ui->pKaPhPiDecimalPlacesSpinBox->setValue(pka_ph);
}

void
DecimalPlacesOptionsDlg::closeEvent(QCloseEvent *event)
{
  Q_UNUSED(event);

  QSettings settings(m_configSettingsFilePath, QSettings::IniFormat);

  settings.beginGroup("decimal_places_options_dlg");

  settings.setValue("geometry", saveGeometry());

  settings.setValue("ATOM_DEC_PLACES", m_atomDecPlaces);
  settings.setValue("OLIGOMER_DEC_PLACES", m_oligomerDecPlaces);
  settings.setValue("POLYMER_DEC_PLACES", m_polymerDecPlaces);
  settings.setValue("PKA_PH_PI_DEC_PLACES", m_pkaPhPiDecPlaces);

  settings.endGroup();
}

/*!
\brief Validates all the decimal values set in the dialog window control.

The values read from the graphical interface are set to the library global
data:

\list

\li libXpertMassCore::ATOM_DEC_PLACES
\li libXpertMassCore::OLIGOMER_DEC_PLACES
\li libXpertMassCore::POLYMER_DEC_PLACES
\li libXpertMassCore::PKA_PH_PI_DEC_PLACES

\endlist
*/
void
DecimalPlacesOptionsDlg::validate()
{

  libXpertMassCore::ATOM_DEC_PLACES = mp_ui->atomDecimalPlacesSpinBox->value();
  libXpertMassCore::OLIGOMER_DEC_PLACES =
    mp_ui->oligomerDecimalPlacesSpinBox->value();
  libXpertMassCore::POLYMER_DEC_PLACES =
    mp_ui->polymerDecimalPlacesSpinBox->value();
  libXpertMassCore::PKA_PH_PI_DEC_PLACES =
    mp_ui->pKaPhPiDecimalPlacesSpinBox->value();

  QSettings settings(m_configSettingsFilePath, QSettings::IniFormat);

  settings.beginGroup("decimal_places_options");

  settings.setValue("ATOM_DEC_PLACES", libXpertMassCore::ATOM_DEC_PLACES);
  settings.setValue("OLIGOMER_DEC_PLACES",
                    libXpertMassCore::OLIGOMER_DEC_PLACES);
  settings.setValue("POLYMER_DEC_PLACES", libXpertMassCore::POLYMER_DEC_PLACES);
  settings.setValue("PKA_PH_PI_DEC_PLACES",
                    libXpertMassCore::PKA_PH_PI_DEC_PLACES);

  settings.endGroup();

  // At this point ask that masses be redisplayed, for the sequence
  // editor window.

  emit decimalPlacesOptionsChangedSignal();
}

void
DecimalPlacesOptionsDlg::registerJsConstructor(QJSEngine *engine)
{
  if(!engine)
    {
      qDebug()
        << "Cannot register DecimalPlacesOptionsDlg class: engine is null";
      return;
    }

  // Register the meta object as a constructor

  QJSValue jsMetaObject =
    engine->newQMetaObject(&DecimalPlacesOptionsDlg::staticMetaObject);
  engine->globalObject().setProperty("DecimalPlacesOptionsDlg", jsMetaObject);
}


} // namespace libXpertMassGui

} // namespace MsXpS
