
/*******************************************************************************
 * Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
 *
 * This file is part of the PAPPSOms++ library.
 *
 *     PAPPSOms++ 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.
 *
 *     PAPPSOms++ 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 PAPPSOms++.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and
 *implementation
 ******************************************************************************/

#include <QDebug>
#include "obopsimodterm.h"
#include "../pappsoexception.h"

int oboPsiModTermMetaTypeId =
  qRegisterMetaType<pappso::OboPsiModTerm>("pappso::OboPsiModTerm");

inline void
initMyResource()
{
  Q_INIT_RESOURCE(libpappsomsppresources);
}


namespace pappso
{

QRegularExpression OboPsiModTerm::m_firstParse("^([a-z,A-Z,_]+):\\s(.*)$");
QRegularExpression OboPsiModTerm::m_findExactPsiModLabel(
  "^(.*)\\sEXACT\\sPSI-MOD-label\\s\\[\\]$");

// synonym: "Carbamidomethyl" RELATED PSI-MS-label []
QRegularExpression OboPsiModTerm::m_findRelatedPsiMsLabel(
  "^(.*)\\sRELATED\\sPSI-MS-label\\s\\[\\]$");


OboPsiModTerm::OboPsiModTerm()
{
}

OboPsiModTerm::~OboPsiModTerm()
{
}
OboPsiModTerm::OboPsiModTerm(const OboPsiModTerm &other)
{
  m_accession   = other.m_accession;
  m_name        = other.m_name;
  m_definition  = other.m_definition;
  m_psiModLabel = other.m_psiModLabel;
  m_psiMsLabel  = other.m_psiMsLabel;
  m_diffFormula = other.m_diffFormula;
  m_formula     = other.m_formula;
  m_origin      = other.m_origin;

  m_diffMono = other.m_diffMono;
  m_massMono = other.m_massMono;
  m_isA      = other.m_isA;
}

OboPsiModTerm &
OboPsiModTerm::operator=(const OboPsiModTerm &other)
{
  m_accession   = other.m_accession;
  m_name        = other.m_name;
  m_definition  = other.m_definition;
  m_psiModLabel = other.m_psiModLabel;
  m_psiMsLabel  = other.m_psiMsLabel;
  m_diffFormula = other.m_diffFormula;
  m_origin      = other.m_origin;

  m_diffMono = other.m_diffMono;
  m_massMono = other.m_massMono;
  m_isA      = other.m_isA;
  return *this;
}


bool
OboPsiModTerm::isValid() const
{
  return (!m_accession.isEmpty());
}

bool
OboPsiModTerm::isA(const QString &accession) const
{
  return m_isA.contains(accession);
}

void
OboPsiModTerm::parseLine(const QString &line)
{
  // qDebug() << "OboPsiModTerm::parseLine begin " << line;
  //  id: MOD:00007
  //  is_a: MOD:01441 ! natural, standard, encoded residue
  QRegularExpressionMatch match_line = m_firstParse.match(line);
  if(match_line.hasMatch())
    {
      QStringList pline = match_line.capturedTexts();
      // qDebug() << "OboPsiModTerm::parseLine match " << pline[0] << pline[1];
      if(pline[1] == "id")
        {
          m_accession = pline[2].trimmed();
          // qDebug() << "OboPsiModTerm::parseLine accession = " << m_accession;
        }
      else if(pline[1] == "name")
        {
          m_name = pline[2].trimmed();
          // qDebug() << "OboPsiModTerm::parseLine accession = " << m_accession;
        }
      else if(pline[1] == "is_a")
        {
          m_isA << pline[2].section(" ", 0, 0);
          // qDebug() << "OboPsiModTerm::parseLine is_a = " << m_isA.join(" ");
        }
      else if(pline[1] == "xref")
        {
          // xref: DiffMono: "1.007276"
          QRegularExpressionMatch match_subline = m_firstParse.match(pline[2]);
          if(match_subline.hasMatch())
            {
              QStringList psecond = match_subline.capturedTexts();
              if(psecond[1] == "DiffMono")
                {
                  m_diffMono = psecond[2].replace("\"", "").toDouble();
                  // qDebug() << "OboPsiModTerm::parseLine m_diffMono = " <<
                  // m_diffMono;
                }
              else if(psecond[1] == "DiffFormula")
                {
                  m_diffFormula = psecond[2].trimmed().replace("\"", "");
                  // qDebug() << "OboPsiModTerm::parseLine m_diffFormula = |" <<
                  // m_diffFormula<<"|";
                }
              else if(psecond[1] == "Formula")
                {
                  m_formula = psecond[2].trimmed().replace("\"", "");
                  // qDebug() << "OboPsiModTerm::parseLine m_diffFormula = |" <<
                  // m_diffFormula<<"|";
                }
              else if(psecond[1] == "Origin")
                {
                  m_origin =
                    psecond[2].trimmed().replace("\"", "").replace(",", "");
                  // qDebug() << "OboPsiModTerm::parseLine m_diffFormula = |" <<
                  // m_diffFormula<<"|";
                }
              // xref: MassMono: "71.037114"

              else if(psecond[1] == "MassMono")
                {
                  bool is_ok = false;
                  double mass_mono =
                    psecond[2].replace("\"", "").toDouble(&is_ok);
                  if(is_ok)
                    m_massMono = mass_mono;
                  else
                    m_massMono = 0;
                  // qDebug() << "OboPsiModTerm::parseLine m_diffFormula = |" <<
                  // m_diffFormula<<"|";
                }
            }
        }
      else if(pline[1] == "synonym")
        {
          // synonym: "Se(S)Res" EXACT PSI-MOD-label []
          QRegularExpressionMatch match_exact_psimod =
            m_findExactPsiModLabel.match(pline[2]);
          if(match_exact_psimod.hasMatch())
            {
              m_psiModLabel =
                match_exact_psimod.captured(1).trimmed().replace("\"", "");
              // qDebug() << "OboPsiModTerm::parseLine m_psiModLabel = |" <<
              // m_psiModLabel<<"|";
            }
          else
            {
              QRegularExpressionMatch match_related_psims =
                m_findRelatedPsiMsLabel.match(pline[2]);
              if(match_related_psims.hasMatch())
                {
                  m_psiMsLabel =
                    match_related_psims.captured(1).trimmed().replace("\"", "");
                  // qDebug() << "OboPsiModTerm::parseLine m_psiModLabel = |" <<
                  // m_psiModLabel<<"|";
                }
            }
        }
      else if(pline[1] == "def")
        {
          // def: "A protein modification that modifies an L-asparagine
          // residue." [PubMed:18688235]
          m_definition = pline[2];
        }
    }
}
void
OboPsiModTerm::clearTerm()
{
  m_accession   = "";
  m_name        = "";
  m_definition  = "";
  m_psiModLabel = "";
  m_diffFormula = "";
  m_diffMono    = 0;
  m_origin      = "";
  m_massMono    = 0;
  m_isA.clear();
}

} // namespace pappso
