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


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


/////////////////////// Qt includes
#include <QDir>
#include <QString>
#include <QStandardPaths>
#include <QFile>
#include <QTextStream>


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


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


int errorListMetaTypeId = qRegisterMetaType<MsXpS::libXpertMassCore::ErrorList>(
  "MsXpS::libXpertMassCore::ErrorList");

int errorListPtrMetaTypeId =
  qRegisterMetaType<MsXpS::libXpertMassCore::ErrorList *>(
    "MsXpS::libXpertMassCore::ErrorList *");

namespace MsXpS
{
namespace libXpertMassCore
{


/*!
\enum MsXpS::libXpertMassCore::Enums::LocationType
\ingroup Globals

This enum type specified the kind of location:

\value INDEX
      The location is specified as an index, that is, the numbering starts with
0

\value POSITION
      The location is specified as a position, that is, the numbering starts
with 1
*/

/*!
\variable MsXpS::libXpertMassCore::locationTypeMap
\ingroup Globals

\brief Map relating each \l{LocationType} member to a corresponding textual
representation.
*/
std::map<Enums::LocationType, QString> locationTypeMap{
  {Enums::LocationType::INDEX, "INDEX"},
  {Enums::LocationType::POSITION, "POSITION"}};


/*!
\enum MsXpS::libXpertMassCore::Enums::MassType
\ingroup Globals

This enum type specifies the type of mass:

\value MONO
     The mass is monoisotopic

\value AVG
     The mass is average

\value BOTH
     (MONO | AVG)
*/

/*!
\variable MsXpS::libXpertMassCore::massTypeMap
\ingroup Globals

\brief Map relating each \l{MassType} member to a corresponding textual
representation.
*/
std::map<Enums::MassType, QString> massTypeMap{{Enums::MassType::MONO, "MONO"},
                                               {Enums::MassType::AVG, "AVG"},
                                               {Enums::MassType::BOTH, "BOTH"}};

/*!
\enum MsXpS::libXpertMassCore::Enums::MassToleranceType
\ingroup Globals

  This enum type specifies the kind of mass tolerance to use for a mass
calculation or a mass comparison.

  \value NONE
         The tolerance is not specified

  \value PPM
         The tolerance is based on parts per million

  \value MZ
         The tolerance is based on an absolute m/z value

  \value AMU
         The tolerance is based on an absolute mass value

  \value RES
         The tolerance is based on resolution

  \omitvalue LAST
*/

/*!
\variable MsXpS::libXpertMassCore::massToleranceTypeMap
\ingroup Globals

\brief Map relating each \l{MassToleranceType} member to a corresponding textual
representation.
*/
std::map<Enums::MassToleranceType, QString> massToleranceTypeMap{
  {Enums::MassToleranceType::NONE, "NONE"},
  {Enums::MassToleranceType::PPM, "PPM"},
  {Enums::MassToleranceType::MZ, "MZ"},
  {Enums::MassToleranceType::AMU, "AMU"},
  {Enums::MassToleranceType::RES, "RES"}};


/*!
\enum MsXpS::libXpertMassCore::Enums::PolymerEnd
\ingroup Globals

This enum specifies the polymer end.

\value NONE
       Not defined

\value LEFT
       The left end

\value RIGHT
       The right end

\value BOTH
       (LEFT | RIGHT)
*/

/*!
\variable MsXpS::libXpertMassCore::polymerEndMap
\ingroup Globals

\brief Map relating each \l{PolymerEnd} member to a corresponding textual
representation.
*/
std::map<Enums::PolymerEnd, QString> polymerEndMap{
  {Enums::PolymerEnd::NONE, "NONE"},
  {Enums::PolymerEnd::LEFT, "LEFT"},
  {Enums::PolymerEnd::RIGHT, "RIGHT"},
  {Enums::PolymerEnd::BOTH, "BOTH"}};


/*!
\enum MsXpS::libXpertMassCore::Enums::IonizationOutcome
\ingroup Globals

\brief This enum specifies the outcome of an ionization or deionization process.


\value FAILED
      The operation failed.

\value UNCHANGED
      The ionization status did not change. For example calling deionize() on a
non-ionized entity returns UNCHANGED.

\value IONIZED
      The ionization was successful.

\value DEIONIZED
      The deionization was successful.
*/


/*!
\variable MsXpS::libXpertMassCore::ionizationOutcomeMap
\ingroup Globals

\brief Map relating each \l{IonizationOutcome} member to a corresponding textual
representation.
*/
std::map<Enums::IonizationOutcome, QString> ionizationOutcomeMap{
  {Enums::IonizationOutcome::FAILED, "FAILED"},
  {Enums::IonizationOutcome::UNCHANGED, "UNCHANGED"},
  {Enums::IonizationOutcome::IONIZED, "IONIZED"},
  {Enums::IonizationOutcome::DEIONIZED, "DEIONIZED"}};


/*!
\enum MsXpS::libXpertMassCore::Enums::SelectionType
\ingroup Globals

This enum specifies the selection type in a polymer sequence.

\value RESIDUAL_CHAINS
       The selection comprises only residues

\value OLIGOMERS
       The selection comprises oligomers, that is, residual chains capped with
the left and right caps.
*/

/*!
\variable MsXpS::libXpertMassCore::selectionTypeMap
\ingroup Globals

\brief Map relating each \l{SelectionType} member to a corresponding textual
representation.
*/
std::map<Enums::SelectionType, QString> selectionTypeMap{
  {Enums::SelectionType::RESIDUAL_CHAINS, "RESIDUAL_CHAINS"},
  {Enums::SelectionType::OLIGOMERS, "OLIGOMERS"}};

/*!
\enum MsXpS::libXpertMassCore::Enums::CapType
\ingroup Globals

This enum specifies the type of cap (the chemical entities that are set to
the polymer ends so as to finish its polymerization state from a chain of
residues to an actual polymer molecule.

\value NONE
       The cap is not defined

\value LEFT
       The left cap

\value RIGHT
       The right cap

\value BOTH
       (LEFT | RIGHT)
*/

/*!
\variable MsXpS::libXpertMassCore::capTypeMap
\ingroup Globals

\brief Map relating each \l{CapType} member to a corresponding textual
representation.
*/
std::map<Enums::CapType, QString> capTypeMap{{Enums::CapType::NONE, "NONE"},
                                             {Enums::CapType::LEFT, "LEFT"},
                                             {Enums::CapType::RIGHT, "RIGHT"},
                                             {Enums::CapType::BOTH, "BOTH"}};

/*!
\enum MsXpS::libXpertMassCore::Enums::ChemicalEntity
\ingroup Globals

This enum specifies the monomer chemical entities to account for in a
calculation.

This enum is typically used when mass calculations need to account or not for
the various chemical entities that are attached to a given monomer.

\value NONE
       The chemical entity is not defined.

\value MONOMER
       The monomer

\value MODIF
       The modification

\value CROSS_LINKER
       The cross-linker

\value MODIF_AND_CROSS_LINKER
       The modification and the cross-linker

\value CROSS_LINK
       The cross-link

\value LEFT_END_MODIF
       The polymer left end modification

\value FORCE_LEFT_END_MODIF
       Force accounting of the polymer left end modification even if selection
does not encompass the left end monomer

\value RIGHT_END_MODIF
       The polymer right end modification

\value FORCE_RIGHT_END_MODIF
       Force accounting of the polymer right end modification even if selection
does not encompass the right end monomer

\value BOTH_END_MODIFS
       Both the polymer left and right ends modifications

\value FORCE_BOTH_END_MODIFS
       Force accounting of both the polymer left and right ends modifications
even if selection does not encompass any of the polymer ends monomers
*/

/*!
\variable MsXpS::libXpertMassCore::chemicalEntityMap
\ingroup Globals

\brief Map relating each \l{ChemicalEntity} member to a corresponding textual
representation.
*/
std::map<Enums::ChemicalEntity, QString> chemicalEntityMap{
  {Enums::ChemicalEntity::NONE, "NONE"},
  {Enums::ChemicalEntity::MONOMER, "MONOMER"},
  {Enums::ChemicalEntity::MODIF, "MODIF"},
  {Enums::ChemicalEntity::CROSS_LINKER, "CROSS_LINKER"},
  {Enums::ChemicalEntity::MODIF_AND_CROSS_LINKER, "MODIF AND CROSS_LINKER"},
  {Enums::ChemicalEntity::CROSS_LINK, "CROSS_LINK"},
  {Enums::ChemicalEntity::LEFT_END_MODIF, "LEFT_END_MODIF"},
  {Enums::ChemicalEntity::RIGHT_END_MODIF, "RIGHT_END_MODIF"},
  {Enums::ChemicalEntity::FORCE_LEFT_END_MODIF, "FORCE_LEFT_END_MODIF"},
  {Enums::ChemicalEntity::RIGHT_END_MODIF, "RIGHT_END_MODIF"},
  {Enums::ChemicalEntity::FORCE_RIGHT_END_MODIF, "FORCE_RIGHT_END_MODIF"},
  {Enums::ChemicalEntity::BOTH_END_MODIFS, "BOTH_END_MODIFS"},
  {Enums::ChemicalEntity::FORCE_BOTH_END_MODIFS, "FORCE_BOTH_END_MODIFS"}};


/*!
    \enum MsXpS::libXpertMassCore::Enums::CrossLinkEncompassed

    This enum type specifies the manner in which a sequence region in a \l
Polymer or in an \l Oligomer contains fully, or partially not does not contain
all the monomers involved in a CrossLink:

    \value NOT
           The region does not contain any \l Monomer involved in a CrossLink.

    \value PARTIALLY
           The region contains one or more \l{Monomer}s involved in a
CrossLink but not all.

    \value FULLY
           All the \l{Monomer}s involved in the CrossLink are contained in
the \l Polymer or \l Oligomer region.
*/


/*!
\variable MsXpS::libXpertMassCore::crossLinkEncompassedMap
\ingroup Globals

\brief Map relating each \l{CrossLinkEncompassed} member to a corresponding
textual representation.
*/
std::map<Enums::CrossLinkEncompassed, QString> crossLinkEncompassedMap{
  {Enums::CrossLinkEncompassed::NOT, "NOT"},
  {Enums::CrossLinkEncompassed::PARTIALLY, "PARTIALLY"},
  {Enums::CrossLinkEncompassed::FULLY, "FULLY"}};


/*!
\enum MsXpS::libXpertMassCore::Enums::HashAccountData
\ingroup Globals

This enum specifies the chemical entites to account for when calculating a hash.

\value NOTHING
       Nothing

\value SEQUENCE
       The sequence

\value MONOMER_MODIF
       Monomer modifications

\value POLYMER_MODIF
       Polymer modifications
*/


/*!
\enum MsXpS::libXpertMassCore::Enums::CleavageAction
\ingroup Globals

This enum specifies the cleavage operation to be carried out.

This enum is typically used when CleavageMotif objects are configured,
either for cleavage (after arginine,  for Trypsin) or not-for-cleavage,
at K/P,  for Trypsin).

\value NOT_SET
       The CleavageAction has not been configured

\value NO_CLEAVE
       The opeartion is actual cleavage

\value CLEAVE
       The operation is no cleavage
*/

/*!
\variable MsXpS::libXpertMassCore::CleavageActionMap
\ingroup Globals

\brief Map relating each \l{CleavageAction} member to a corresponding textual
representation.
*/
std::map<Enums::CleavageAction, QString> CleavageActionMap{
  {Enums::CleavageAction::NOT_SET, "NOT_SET"},
  {Enums::CleavageAction::NO_CLEAVE, "NO_CLEAVE"},
  {Enums::CleavageAction::CLEAVE, "CLEAVE"}};


/*!
\enum MsXpS::libXpertMassCore::Enums::FragEnd
\ingroup Globals

This enum specifies the end of the polymer that is found in a fragment.

This enum is typically used to tell what polymer end is found in a fragment ion
product. For example, in protein fragmentations, the a, b, c fragments contain
the left end of the peptide that was fragmented, while the x, y, z fragments
contain the right end of the fragmented peptide.

\value NE
       The fragment contains none of the precursor oligomer ion ends (immonium
ions, for example).

\value LE
       The fragment contains the left end of the precursor oligomer ion.

\value RE
       The fragment contains the right end of the precursor oligomer ion.

\value BE
       The fragment contains both the left and the right ends of the precursor
oligomer ion.
*/


/*!
\variable MsXpS::libXpertMassCore::fragEndMap
\ingroup Globals

\brief Map relating each \l{FragEnd} member to a corresponding textual
representation.
*/
std::map<Enums::FragEnd, QString> fragEndMap{{Enums::FragEnd::NE, "NE"},
                                             {Enums::FragEnd::LE, "LE"},
                                             {Enums::FragEnd::RE, "RE"},
                                             {Enums::FragEnd::BE, "BE"}};


/*!
\enum MsXpS::libXpertMassCore::Enums::ChemicalGroupTrapped
\ingroup Globals

This enum specifies how the chemical group behaves when the chemical entity
that it holds polymerizes into a \l Polymer.

One example will clear things out:

An amino acid has a amino group and a carboxylic acid group. The amino group
gets entrapped in the monomer-to-monomer bond (the peptide bond) if the
polymerization occurs at the left of the monomer. That means that if the
Monomer holding this ChemicalGroup is N-terminal, then the amino group should
be accounted for because it is intact. Conversely, the carboxylic acid group
gets entrapped in the peptide bond if the polymerization occurs at the right of
the monomer. That means that if the Monomer holding this ChemicalGroup is
C-terminal, then the carboxylic acid group should be accounted for because it is
intact.

\value NEVER
        The chemical group is not lost upon polymerization, it should thus
always be accounted for.

\value LEFT
        The chemical group gets trapped in the inter-monomer bond if
polymerization occurs at left of the \l Monomer.

\value RIGHT
        The chemical group gets trapped in the inter-monomer bond if
polymerization occurs at right of the \l Monomer.
*/

/*!
\variable MsXpS::libXpertMassCore::chemicalGroupTrappedMap
\ingroup Globals

\brief Map relating each \l{ChemicalGroupTrapped} member to a corresponding
textual representation.
*/
std::map<Enums::ChemicalGroupTrapped, QString> chemicalGroupTrappedMap{
  {Enums::ChemicalGroupTrapped::NEVER, "NEVER"},
  {Enums::ChemicalGroupTrapped::LEFT, "LEFT"},
  {Enums::ChemicalGroupTrapped::RIGHT, "RIGHT"}};


/*!
\enum MsXpS::libXpertMassCore::Enums::ChemicalGroupFate
\ingroup Globals

This enum specifies how the chemical group behaves when the chemical entity
that it holds polymerizes into a \l Polymer.

This example clarifies the concept:

\code
    <monomer>
      <code>C</code>
      <mnmchemgroup>
        <name>N-term NH2</name>
        <pka>9.6</pka>
        <acidcharged>TRUE</acidcharged>
        <polrule>left_trapped</polrule>
        <chemgrouprule>
          <entity>LE_PLM_MODIF</entity>
          <name>Acetylation</name>
          <outcome>LOST</outcome>
        </chemgrouprule>
      </mnmchemgroup>
\endcode

When the Cysteine's amino group is modified because the Cys residue
on on the N-terminal end of the polymer, if it gets acetylated, then the amino
group is lost because it is trapped in the amide bond. It is thus not accounted
for when computing the pI of the protein.

\value LOST
        The chemical group is lost upon modification of the \l Monomer.
\value PRESERVED
        The chemical group is preserved upon modification of the \l Monomer.
*/

/*!
\variable MsXpS::libXpertMassCore::chemicalGroupFateMap
\ingroup Globals

\brief Map relating each \l{ChemicalGroupFate} member to a corresponding textual
representation.
*/
std::map<Enums::ChemicalGroupFate, QString> chemicalGroupFateMap{
  {Enums::ChemicalGroupFate::LOST, "LOST"},
  {Enums::ChemicalGroupFate::PRESERVED, "PRESERVED"}};


/*!
\enum MsXpS::libXpertMassCore::Enums::MassPeakShapeType
\ingroup Globals

This enum specifies how the peak shape needs to be computed.

\value NOT_SET
       The value is not set.
\value GAUSSIAN
        The peak shape is computed using the Gaussian function.
\value LORENTZIAN
        The peak shape is computed using the Lorentzian function.
*/

/*!
\variable MsXpS::libXpertMassCore::massPeakShapeTypeMap
\ingroup Globals

\brief Map relating each \l{MassPeakShapeType} member to a corresponding textual
representation.
*/
std::map<Enums::MassPeakShapeType, QString> massPeakShapeTypeMap{
  {Enums::MassPeakShapeType::NOT_SET, "NOT_SET"},
  {Enums::MassPeakShapeType::GAUSSIAN, "GAUSSIAN"},
  {Enums::MassPeakShapeType::LORENTZIAN, "LORENTZIAN"}};


/*!
\enum  MsXpS::libXpertMassCore::Enums::MassPeakWidthLogic
\ingroup Globals

This enum specifies how the peak shape needs to be computed.

\value NOT_SET
       The value is not set.
\value FWHM
        The width of the peak shape is determined using the FWHM (full width at
half maximum).
\value RESOLUTION
        The width of the peak shape is determined using the resolving power of
the instrument.
*/

/*!
\variable MsXpS::libXpertMassCore::massPeakWidthLogicMap
\ingroup Globals

\brief Map relating each \l{MassPeakWidthLogic} member to a corresponding
textual representation.
*/
std::map<Enums::MassPeakWidthLogic, QString> massPeakWidthLogicMap{
  {Enums::MassPeakWidthLogic::NOT_SET, "NOT_SET"},
  {Enums::MassPeakWidthLogic::FWHM, "FWHM"},
  {Enums::MassPeakWidthLogic::RESOLUTION, "RESOLUTION"}};

/*!
\enum MsXpS::libXpertMassCore::Enums::MassDataType
\ingroup Globals

This enum type specifies the kind of mass data that are encoded in a CBOR
container.

\value NOT_SET
       The mass data type is not set

\value MASS_SPECTRUM
       The mass data type is a mass spectrum

\value DRIFT_SPECTRUM
       The mass data type is a drift spectrum (ion mobility data)

\value TIC_CHROMATOGRAM
       The mass data type is total ion current chromatogram

\value XIC_CHROMATOGRAM
       The mass data type is an extract ion current chromatogram

\value MZ_RT_COLORMAP
       The mass data type is an MZ/RT color map

\value DT_RT_COLORMAP
       The mass data type is a DT/RT color map

\value DT_MZ_COLORMAP
       The mass data type is DT/MZ color map

\omitvalue LAST
 */

/*!
\brief Map relating each \l{
  MassDataType} member to a corresponding textual representation.
  */
std::map<Enums::MassDataType, QString> massDataTypeMap{
  {Enums::MassDataType::NOT_SET, "NOT_SET"},
  {Enums::MassDataType::MASS_SPECTRUM, "MASS_SPECTRUM"},
  {Enums::MassDataType::DRIFT_SPECTRUM, "DRIFT_SPECTRUM"},
  {Enums::MassDataType::TIC_CHROMATOGRAM, "TIC_CHROMATOGRAM"},
  {Enums::MassDataType::XIC_CHROMATOGRAM, "XIC_CHROMATOGRAM"},
  {Enums::MassDataType::MZ_RT_COLORMAP, "MZ_RT_COLORMAP"},
  {Enums::MassDataType::DT_RT_COLORMAP, "DT_RT_COLORMAP"},
  {Enums::MassDataType::DT_MZ_COLORMAP, "DT_MZ_COLORMAP"},
  {Enums::MassDataType::LAST, "LAST"}};


/*!
\brief Number of decimal places after the decimal symbol for unconfigured
values.
\ingroup Globals
 */
int DEFAULT_DEC_PLACES = 3;

/*!
\brief Number of decimal places after the decimal symbol for atom masses.
\ingroup Globals
 */
int ATOM_DEC_PLACES = 10;

/*!
\brief Number of decimal places after the decimal symbol for oligomer masses.
\ingroup Globals
 */
int OLIGOMER_DEC_PLACES = 6;

/*!
\brief Number of decimal places after the decimal symbol for polymer masses.
\ingroup Globals
 */
int POLYMER_DEC_PLACES = 3;

/*!
\brief Number of decimal places after the decimal symbol for pH/pKa values.
\ingroup Globals
 */
int PKA_PH_PI_DEC_PLACES = 2;

/*!
\brief Number of decimal places after the decimal symbol for m/z values.
\ingroup Globals
 */
int MZ_DEC_PLACES = 3;

/*!
\brief Number of decimal places after the decimal symbol for delta m/z values.
\ingroup Globals
 */
int DELTA_MZ_DEC_PLACES = 4;

/*!
\brief Number of decimal places after the decimal symbol for retention time
values in minutes.
\ingroup Globals
 */
int RT_MINUTES_DEC_PLACES = 2;

/*!
\brief Number of decimal places after the decimal symbol for retention time
values in seconds.
\ingroup Globals
 */
int RT_SECONDS_DEC_PLACES = 1;

/*!
\brief Number of decimal places after the decimal symbol for intensity values.
\ingroup Globals
 */
int INTENSITY_DEC_PLACES = 0;

/*!
    \typedef MsXpS::libXpertMassCore::ErrorList
    \relates QString

    Synonym for std::vector<QString> ErrorList.
*/

} // namespace libXpertMassCore
} // namespace MsXpS
