/* massXpert - the true massist's program.
   --------------------------------------
   Copyright(C) 2006,2007 Filippo Rusconi

   http://www.massxpert.org/massXpert

   This file is part of the massXpert project.

   The massxpert project is the successor to the "GNU polyxmass"
   project that is an official GNU project package(see
   www.gnu.org). The massXpert project is not endorsed by the GNU
   project, although it is released ---in its entirety--- under the
   GNU General Public License. A huge part of the code in massXpert
   is actually a C++ rewrite of code in GNU polyxmass. As such
   massXpert was started at the Centre National de la Recherche
   Scientifique(FRANCE), that granted me the formal authorization to
   publish it under this Free Software License.

   This software is free software; you can redistribute it and/or
   modify it under the terms of the GNU  General Public
   License version 3, as published by the Free Software Foundation.
   

   This software 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 software; if not, write to the

   Free Software Foundation, Inc.,

   51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/


#ifndef MODIF_HPP
#define MODIF_HPP


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


/////////////////////// Local includes
#include "polChemDefEntity.hpp"
#include "formula.hpp"
#include "ponderable.hpp"
#include "prop.hpp"
#include "propListHolder.hpp"

namespace massXpert
{

  //! 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 Formula, 
		public Ponderable,
		public PropListHolder
  {
  private:
    QString m_targets;
    int m_maxCount;
      
  public:
    Modif(const PolChemDef *, QString, QString = QString());
    Modif(const Modif &);
    ~Modif();
  
    Modif *clone() const;
    void clone(Modif *) const;
    void mold(const Modif &);
    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);
    
    bool validate();
  
    bool calculateMasses();

    bool accountMasses(double *mono = 0, double *avg = 0, int times = 1);
  
    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 massXpert


#endif // MODIF_HPP
