/***************************************************************************
 *   Copyright (C) 2005 by Roberto Virga                                   *
 *   rvirga@users.sourceforge.net                                          *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 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 Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef KBSPREDICTORDATA_H
#define KBSPREDICTORDATA_H

#include <qdatetime.h>
#include <qstring.h>
#include <qstringlist.h>

enum KBSPredictorAppType {MFOLD, CHARMM};

enum KBSPredictorAminoAcid
  {GLY, ALA, SER, CYS, VAL, THR, ILE, PRO, MET, ASP,
   ASN, LEU, LYS, GLU, GLN, ARG, HIS, PHE, TYR, TRP,
   AminoAcids};

enum KBSPredictorElement
  {Hydrogen,
   Helium,
   Lithium,
   Boron,
   Carbon,
   Nitrogen,
   Oxygen,
   Fluorine,
   Neon,
   Sodium,
   Magnesium,
   Aluminium,
   Silicon,
   Phosphorus,
   Sulphur,
   Chlorine,
   Argon,
   Potassium,
   Calcium,
   Titanium,
   Chromium,
   Manganese,
   Iron,
   Nickel,
   Copper,
   Zinc,
   Gallium,
   Arsenic,
   Selenium,
   Bromine,
   Krypton,
   Palladium,
   Silver,
   Cadmium,
   Indium,
   Tin,
   Tellurium,
   Iodine,
   Xenon,
   Barium,
   Platinum,
   Gold,
   Mercury,
   Thallium,
   Lead,
   Uranium,
   Elements};

struct KBSPredictorBurials
{
  double avg[AminoAcids+1][AminoAcids+1];
  double sdev[AminoAcids+1][AminoAcids+1];
  unsigned pairs[AminoAcids+1][AminoAcids+1];
  
  bool parse(const QStringList &lines);
};

struct KBSPredictorECovers24
{
  double value[AminoAcids][25];
  
  bool parse(const QStringList &lines);
};

struct KBSPredictorProfile3
{
  double value[AminoAcids][5][5][5];
  
  bool parse(const QStringList &lines);
};

struct KBSPredictorQuasi3
{
  double par[2][AminoAcids][AminoAcids];
  double mid[2][AminoAcids][AminoAcids];
  double ant[2][AminoAcids][AminoAcids];
  
  bool parse(const QStringList &lines);
};

struct KBSPredictorScale3B
{
  KBSPredictorAminoAcid aa[3];
  unsigned count[3];
  double value;
  
  bool parse(const QString &line);
};

struct KBSPredictorS1234
{
  double r1_2[AminoAcids][AminoAcids][3];
  double r1_3[AminoAcids][AminoAcids][4];
  double r1_4[AminoAcids][AminoAcids][14];
  double r1_5[AminoAcids][AminoAcids][7];
  
  bool parse(const QStringList &lines);
};

struct KBSPredictorMonssterAtom
{
  unsigned x, y, z;
  
  bool parse(const QString &line);
};

struct KBSPredictorMonssterInput
{
  unsigned random,                    // random seed
           ncycle,                    // number of cycles per temperature step
           icycle,                    // Monte Carlo moves per cycle
           tsteps,                    // temperature steps
           resmin,                    // first fragment residue (fixed template)
           resmax;                    // last fragment residue (fixed template)
  double temp[2],                     // temperature range
         softcore,                    // soft core radius for large residues
         central,                     // centrosymmetric potential scaling
         stiff,                       // general stiffness potential scaling
         pair,                        // pair potential scaling,
         kdcore,                      // hydrophobic core potential scaling
         hbond,                       // H-bond cooperativity potential scaling
         shrt,                        // short scale potential scaling
         burial,                      // burial potential scaling
         multibody,                   // multi body potential scaling
         threebody;                   // three body potential scaling
  
  bool parse(const QStringList &lines);
};

struct KBSPredictorMonssterResidue
{
  unsigned resSeq;
  KBSPredictorAminoAcid resName;
  unsigned count[2];
  
  bool parse(const QString &line);
};

struct KBSPredictorMonssterSeq
{
  QValueList<KBSPredictorMonssterResidue> groups;
  unsigned atoms;
  
  bool parse(const QStringList &lines);
  
  QString toString() const;
};

struct KBSPredictorMonssterRestraint
{
  unsigned num;
  double value;
  
  bool parse(const QString &line);
};

struct KBSPredictorAtomPDB
{
  unsigned serial;                    // Atom serial number
  struct {
    unsigned remoteness,              // Distance from the alpha carbon
             branch;                  // Branch
    QString iupac;                    // Atom name in IUPAC format
  } name;
  QChar altLoc;                       // Alternate location indicator
  KBSPredictorAminoAcid resName;      // Residue name
  QChar chainID;                      // Chain identifier
  unsigned resSeq;                    // Residue sequence number
  QChar iCode;                        // Code for insertion of residues
  double x,                           // Orthogonal coordinates for X in Angstroms
         y,                           // Orthogonal coordinates for Y in Angstroms
         z,                           // Orthogonal coordinates for Z in Angstroms
         occupancy,                   // Occupancy
         tempFactor;                  // Temperature factor
  QString segID;                      // Segment identifier
  KBSPredictorElement element;        // Element symbol
  QString charge;                     // Charge on the atom
  
  bool parse(const QString &line);
  
  bool covalentBond(const KBSPredictorAtomPDB &atom) const;
};

bool operator<(const KBSPredictorAtomPDB &a1, const KBSPredictorAtomPDB &a2);

enum KBSPredictorFeature {AlphaHelix, BetaSheet, Turn, Features};

enum KBSPredictorHelixClass
{ RightHandedApha=1, RightHandedOmega, RightHandedPi, RightHandedGamma, RightHanded310,
  LeftHandedAlpha, LeftHandedOmega, LeftHandedGamma, Ribbon27, Polyproline };

struct KBSPredictorHelixPDB
{
  unsigned serNum;                    // Helix serial number
  QString helixID;                    // Helix identifier
  struct {
    KBSPredictorAminoAcid resName;    // Name of the residue
    QChar chainID;                    // Chain identifier
    unsigned seqNum;                  // Sequence number
    QChar iCode;                      // Insertion code
  } init, end;
  KBSPredictorHelixClass helixClass;  // Helix class
  QString comment;                    // Comment about the helix
  unsigned length;                    // Length of the helix
  
  bool parse(const QString &line);
};

bool operator<(const KBSPredictorHelixPDB &h1, const KBSPredictorHelixPDB &h2);

struct KBSPredictorSheetPDB
{
  unsigned strand;                    // Strand number
  QString sheetID;                    // Sheet identifier
  unsigned numStrands;                // Number of strands in sheet
  struct {
    KBSPredictorAminoAcid resName;    // Residue name
    QChar chainID;                    // Chain identifier
    unsigned seqNum;                  // Residue sequence number
    QChar iCode;                      // Insertion code
  } init, end;
  int sense;                          // Sense (0=first, 1=parallel, -1=anti-parallel)
  struct {
    QString atom;                     // Atom
    KBSPredictorAminoAcid resName;    // Residue name
    QChar chainId;                    // Chain identifier
    unsigned resSeq;                  // Residue sequence number
    QChar iCode;                      // Insertion code
  } curr, prev;                       // Registration
  
  bool parse(const QString &line);
};

bool operator<(const KBSPredictorSheetPDB &s1, const KBSPredictorSheetPDB &s2);

struct KBSPredictorTurnPDB
{
  unsigned seq;                       // Turn number
  QString turnID;                     // Turn identifier
  struct {
    KBSPredictorAminoAcid resName;    // Name of the residue
    QChar chainID;                    // Chain identifier
    unsigned seqNum;                  // Sequence number
    QChar iCode;                      // Insertion code
  } init, end;
  QString comment;                    // Comment about the turn
  
  bool parse(const QString &line);
};

bool operator<(const KBSPredictorTurnPDB &t1, const KBSPredictorTurnPDB &t2);

struct KBSPredictorStructurePDB
{
  QValueList<KBSPredictorHelixPDB> helix;
  QValueList<KBSPredictorSheetPDB> sheet;
  QValueList<KBSPredictorTurnPDB> turn;
  
  KBSPredictorFeature feature(unsigned group, unsigned *index = NULL);
};

struct KBSPredictorProteinPDB
{
  unsigned groups;
  QValueList<KBSPredictorAtomPDB> atom;
  KBSPredictorStructurePDB structure;

  bool parse(const QStringList &lines);
  
  QString toString() const;
  
  KBSPredictorAminoAcid resName(unsigned resSeq) const;
  bool hydrogenBond(unsigned i, unsigned j, double threshold=-0.5) const;
  
  void predictStructure(double threshold=-0.5);
};

struct KBSPredictorProteinNOE
{
  struct {
    unsigned index;
    QString name;
  } select[2];
  double kmin,
         rmin,
         kmax,
         rmax;
  
  bool parse(const QString &line);
};

struct KBSPredictorMFold
{
  KBSPredictorBurials burials;
  KBSPredictorECovers24 ecovers_24;
  KBSPredictorProfile3 profile3;
  KBSPredictorQuasi3 quasi3;
  QValueList<KBSPredictorScale3B> scale3b;
  KBSPredictorS1234 s1234, s1234h, s1234e;
  struct {
    QValueList<KBSPredictorMonssterAtom> init_chain;
    KBSPredictorMonssterInput input;
    KBSPredictorMonssterSeq seq;
    QValueList<KBSPredictorMonssterRestraint> restraints;
    struct {
      QValueList<KBSPredictorMonssterAtom> chain;
      KBSPredictorProteinPDB pdb;
      QValueList<KBSPredictorProteinNOE> noe;
    } final;
  } monsster;
};

struct KBSPredictorSeed
{
  unsigned stream;
  
  bool parse(const QStringList &lines);
};

struct KBSPredictorCharmmInp
{
  unsigned ntemps,
           nsteps;
  struct {
    unsigned low,
             high;
  } t;

  bool parse(const QStringList &lines);
};

struct KBSPredictorCharmm
{
  KBSPredictorCharmmInp inp;
  struct {
    KBSPredictorProteinPDB pdb, final_pdb;
    QValueList<KBSPredictorProteinNOE> noe;
    unsigned residuals;
  } protein;
  struct {
    unsigned stream;
  } seed;
};

struct KBSPredictorResult
{
  KBSPredictorAppType app_type;
  KBSPredictorMFold mfold;
  KBSPredictorCharmm charmm;
};

struct KBSPredictorMonssterRestart
{
  unsigned line1a[2];
  double line1b[5];
  unsigned line2[3];
  double line3[2];
  QValueList<KBSPredictorMonssterAtom> chain;
  
  bool parse(const QStringList &lines);
};

struct KBSPredictorState
{
  KBSPredictorAppType app_type;
  KBSPredictorMonssterRestart monsster_restart;
};

#endif
