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


#pragma once


/////////////////////// Local includes
#include <globals/globals.hpp>


namespace msXpSlibmass
{


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

// How many times the whole gaussian/lorentzian curve should span
// around the centroid mz. 4 means that the peak will span
// [ mz - (2 * FWHM) --> mz + (2 * FWHM) ]

extern int FWHM_PEAK_SPAN_FACTOR;


// The PeakShaperConfig 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 PeakShaperConfig
{
  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
  PeakShapeType m_peakShapeType;

  public:
  PeakShaperConfig();
  PeakShaperConfig(int resolution,
                   double fwhm,
                   const QString &ionization_formula,
                   int charge,
                   int data_point_count,
                   double mz_step,
                   double norm_factor,
                   PeakShapeType shape_type);
  PeakShaperConfig(const PeakShaperConfig &other);
  virtual ~PeakShaperConfig();

  void operator=(const PeakShaperConfig &other);

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

  void setConfig(const PeakShaperConfig &other);

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

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

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

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

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

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

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

  PeakShapeType peakShapeType();
  void setPeakShapeType(PeakShapeType);

  double c(double mz);
  QString cAsText(double mz);

  double a(double mz);
  QString aAsText(double mz);

  double gamma(double mz);
  QString gammaAsText(double mz);

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

  QString asText(double mz);
};

} // namespace msXpSlibmass
