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


#pragma once

/////////////////////// StdLib includes


/////////////////////// Qt includes


/////////////////////// pappsomspp includes


/////////////////////// Local includes
#include "globals.hpp"


namespace msxps
{
namespace minexpert
{


enum class MassPeakShapeType
{
  GAUSSIAN   = 1 << 0,
  LORENTZIAN = 1 << 1,
};


//! Width of a Gaussian/Lorentzian curve.
/*!
 * Describe how many times the whole gaussian/lorentzian curve should span
 * around the centroid mz ratio. 4 means that the peak will span
 : [ mzRatio - (2 * FWHM) --> mzRatio + (2 * FWHM) ]
 */
extern int FWHM_PEAK_SPAN_FACTOR;


// The MassPeakShaperConfig class contains all required data to configure the
// computation that will form a gaussian or lorentzian shape corresponding to
// a given centroid DataPoint (x,y) with x=m/z and y=relative intensity.
class MassPeakShaperConfig
{
  public:
  MassPeakShaperConfig();
  MassPeakShaperConfig(int resolution,
                       double fwhm,
                       const QString &ionization_formula,
                       int charge,
                       int data_point_count,
                       double mz_step,
                       double norm_factor,
                       MassPeakShapeType shape_type);

  MassPeakShaperConfig(const MassPeakShaperConfig &other);
  virtual ~MassPeakShaperConfig();

  void operator=(const MassPeakShaperConfig &other);

  void setConfig(int resolution,
                 double fwhm,
                 const QString &ionization_formula,
                 int charge,
                 int data_point_count,
                 double mz_step,
                 double norm_factor,
                 MassPeakShapeType shape_type);

  void setConfig(const MassPeakShaperConfig &other);

  void setResolution(int resolution);
  int resolution(double mz);
  QString resolutionToString() const;

  // For the gaussion, that is the entirety of the fwhm.
  void setFwhm(double value);
  double fwhm(double mz);
  QString fwhmToString(double mz);

  // For the lorentzian, that is half of the fwhm.
  double halfFwhm(double mz);
  QString halfFwhmToString(double mz);

  void setIonizationFormula(const QString &ionization_formula);
  QString getIonizationFormula() const;

  void setCharge(int value);
  int getCharge() const;
  QString chargeToString() const;

  void setPointCount(int);
  int getPointCount() const;
  QString pointCountToString() const;

  void setNormFactor(double);
  double normFactor();
  QString normFactorToString();

  MassPeakShapeType getMassPeakShapeType();
  void setMassPeakShapeType(MassPeakShapeType);

  double c(double mz);
  QString cToString(double mz);

  double a(double mz);
  QString aToString(double mz);

  double gamma(double mz);
  QString gammaToString(double mz);

  void setMzStep(double step);
  double mzStep(double mz);
  QString mzStepToString(double mz);

  QString toString(double mz);

  private:
  int m_resolution = 0;
  double m_fwhm    = 0;
  QString m_ionizationFormula;
  int m_charge = 1;

  // Number of points to use to shape the peak
  int m_pointCount = 0;

  // The delta bewteen two consecutive data points
  double m_mzStep = 0;

  // Norm factor
  double m_normFactor;

  // Type (GAUSSIAN | LORENTZIAN) of the peak shape
  MassPeakShapeType m_massPeakShapeType = MassPeakShapeType::GAUSSIAN;
};

} // namespace minexpert

} // namespace msxps
