/* 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
 */


#ifndef SPECTRUM_CALCULATION_DLG_HPP
#define SPECTRUM_CALCULATION_DLG_HPP


/////////////////////// Qt includes
#include <QDialog>
#include <QTextDocument>


/////////////////////// Local includes
#include <ui_SpectrumCalculationDlg.h>
#include <massxpert/nongui/PolChemDef.hpp>
#include <libmass/Atom.hpp>
#include <libmass/AtomCount.hpp>
#include <libmass/Formula.hpp>
#include <libmass/PeakShape.hpp>
#include <massxpert/nongui/globals.hpp>
#include <massxpert/nongui/OligomerList.hpp>


namespace msXpSmassXpert
{

enum ValidationError
{
  VALIDATION_ERRORS_NONE       = 0x0000,
  VALIDATION_FORMULA_ERRORS    = 1 << 0,
  VALIDATION_RESOLUTION_ERRORS = 1 << 1,
  VALIDATION_FWHM_ERRORS       = 1 << 2,
};

enum SpectrumCalculationMode
{
  SPECTRUM_CALCULATION_MODE_NONE     = 0x0000,
  SPECTRUM_CALCULATION_MODE_CLUSTER  = 1 << 0,
  SPECTRUM_CALCULATION_MODE_SPECTRUM = 1 << 1,
};


class SpectrumCalculationDlg : public QDialog
{
  Q_OBJECT

  private:
  Ui::SpectrumCalculationDlg m_ui;

  SpectrumCalculationMode m_mode;

  const QList<msXpSlibmass::Atom *> &m_atomList;

  OligomerList *mp_oligomerList;

  int m_validationErrors;

  QString m_filePath;
  msXpSlibmass::Formula m_formula;

  QString m_configSettingsFilePath;

  double m_minimumProbability;
  int m_maximumPeaks;

  double m_resolution;

  msXpSlibmass::PeakShapeConfig m_config;

  int m_charge;

  bool m_withMonoMass;
  bool m_withCluster;

  const PolChemDef &m_polChemDef;

  QString m_resultsString;

  // The point list that will hold the sum of all the
  // gaussians/lorentzian curves obtained for the single peak shapes
  // of the spectrum.

  QList<QPointF *> m_patternPointList;

  double m_mono;
  double m_avg;

  bool m_aborted;

  void closeEvent(QCloseEvent *event);

  void setupDialog();

  bool fetchFormulaMass(double * = 0, double * = 0);
  bool fetchMzRatio(double * = 0, double * = 0);

  bool fetchValidateInputData();
  bool fetchValidateInputDataIsotopicClusterMode();
  bool fetchValidateInputDataSpectrumMode();

  void setInErrorStatus(const QString &);

  bool updateMzRatio();
  bool updateIncrement();

  void debugPutStdErrBitset(QString /*file*/,
                            int /*line*/,
                            int             = 0 /*value*/,
                            const QString & = QString() /*descString*/);

  void executeCluster();
  void executeSpectrum();
  void executeSpectrumWithCluster(QList<QList<QPointF *> *> *,
                                  QHash<QList<QPointF *> *, double> *);
  void executeSpectrumWithoutCluster(QList<QList<QPointF *> *> *,
                                     QHash<QList<QPointF *> *, double> *);

  private slots:
  void massTypeRadioButtonToggled(bool);
  void isotopicClusterCheckBoxToggled(bool);

  void formulaEdited(const QString &);
  void chargeChanged(int);
  void pointsChanged(int);
  void resolutionChanged(int);
  void fwhmEdited(const QString &);

  void execute();
  void abort();
  void outputFile();

  public:
  SpectrumCalculationDlg(QWidget *parent,
                         const QString &configSettingsFilePath,
                         const QList<msXpSlibmass::Atom *> &,
                         SpectrumCalculationMode);

  ~SpectrumCalculationDlg();

  void setOligomerList(OligomerList *);

  signals:
  void spectrumCalculationAborted();

  public slots:
  void spectrumCalculationProgressValueChanged(int);
  void spectrumCalculationMessageChanged(QString);
};

} // namespace msXpSmassXpert


#endif // SPECTRUM_CALCULATION_DLG_HPP
