/* 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 MODIF_HPP
#define MODIF_HPP


/////////////////////// Qt includes
#include <QString>


/////////////////////// Local includes
#include <massxpert/nongui/PolChemDefEntity.hpp>
#include <libmass/Formula.hpp>
#include <libmass/Ponderable.hpp>
#include <massxpert/nongui/Prop.hpp>
#include <massxpert/nongui/PropListHolder.hpp>


namespace msXpSmassXpert
{


//! The Modif class provides a chemical modification.

/*! Chemical modifications are found very often in biopolymers. These
  can be phophorylations of seryl residues or acetylation of lysyl
  residues or methylation of DNA bases, for example.

  Monomers and polymers are typical substrates for chemical
  modifications.
 */
class Modif : public PolChemDefEntity,
              public msXpSlibmass::Formula,
              public msXpSlibmass::Ponderable,
              public PropListHolder
{
  private:
  QString m_targets;
  int m_maxCount;

  public:
  Modif(const PolChemDef *, QString, QString = QString());
  Modif(const Modif &);
  ~Modif();

  Modif *clone() const;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Woverloaded-virtual"
  void clone(Modif *) const;
  void mold(const Modif &);
#pragma clang diagnostic pop

  Modif &operator=(const Modif &);
  void reset();

  QString &setTargets(QString);
  QString targets() const;
  int targets(QStringList &) const;
  bool hasMonomerTarget(QString) const;
  bool validateTargets(bool = true);

  void setMaxCount(int);
  int maxCount();

  QString formula() const;

  bool operator==(const Modif &);
  bool operator!=(const Modif &);

  int isNameKnown();
  static int isNameInList(const QString &, const QList<Modif *> &, Modif * = 0);

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Woverloaded-virtual"
  bool validate();
  bool accountMasses(double *mono = 0, double *avg = 0, int times = 1);
#pragma clang diagnostic pop

  bool calculateMasses();

  bool renderXmlMdfElement(const QDomElement &, int);
  bool renderXmlMdfElement(const QDomElement &);
  bool renderXmlMdfElementV2(const QDomElement &);
  bool renderXmlMdfElementV3(const QDomElement &);

  QString *formatXmlMdfElement(int, const QString & = QString("  "));

  void debugPutStdErr();
};


//////////////////////// ModifProp ////////////////////////

//! The ModifProp class provides a modif property.

/*! A ModifProp property is a simple property in which the data
  is a pointer to an allocated modif object.

 */
class ModifProp : public Prop
{
  public:
  ModifProp(Modif *);
  virtual ~ModifProp();
  virtual void deleteData();

  virtual void *clone() const;
  virtual void cloneOut(void *) const;
  virtual void cloneIn(const void *);

  virtual bool renderXmlElement(const QDomElement &, int);
  bool renderXmlElement(const QDomElement &);
  bool renderXmlElementV2(const QDomElement &);

  virtual QString *formatXmlElement(int, const QString & = QString("  "));
};

} // namespace msXpSmassXpert


#endif // MODIF_HPP
