/**
 * \file protein/peptidemodificatorbase.h
 * \date 6/12/2016
 * \author Olivier Langella
 * \brief base class for all peptide modification builders
 */

/*******************************************************************************
 * Copyright (c) 2016 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 "peptidemodificatorbase.h"

namespace pappso
{
PeptideModificatorBase::PeptideModificatorBase()
{
}

PeptideModificatorBase::~PeptideModificatorBase()
{
}

void
PeptideModificatorBase::setModificationPattern(QString &pattern)
{
  m_pattern.setPattern(pattern);
}

void
PeptideModificatorBase::getModificationPositionList(
  std::vector<unsigned int> &position_list, const QString &peptide_str)
{

  int pos                               = 0;
  QRegularExpressionMatch match_pattern = m_pattern.match(peptide_str, pos);

  while(match_pattern.hasMatch())
    {
      pos = match_pattern.capturedStart(0);
      if(match_pattern.lastCapturedIndex() == 0)
        {
          // no motif, just push position
          position_list.push_back(pos);
          pos++;
        }
      else
        {
          // there is a motif : target this position
          pos = match_pattern.capturedStart(1);
          if((position_list.size() > 0) &&
             (position_list.back() == (unsigned int)pos))
            {
              pos = match_pattern.capturedStart(0) + 1;
            }
          else
            {
              position_list.push_back(pos);
              pos = match_pattern.capturedStart(0) + 1;
            }
        }
      match_pattern = m_pattern.match(peptide_str, pos);
    }
}

void
PeptideModificatorBase::getModificationPositionList(
  std::vector<unsigned int> &position_list,
  const Peptide *p_peptide,
  AaModificationP mod,
  unsigned int modification_counter)
{

  int pos                               = 0;
  const QString peptide_str             = p_peptide->getSequence();
  QRegularExpressionMatch match_pattern = m_pattern.match(peptide_str, pos);

  while(match_pattern.hasMatch())
    {
      pos = match_pattern.capturedStart(0);
      if(match_pattern.lastCapturedIndex() == 0)
        {
          // no motif, just push position
          if(p_peptide->getConstAa(pos).getNumberOfModification(mod) ==
             modification_counter)
            {
              position_list.push_back(pos);
            }
          pos++;
        }
      else
        {
          // there is a motif : target this position
          pos = match_pattern.capturedStart(1);
          if((position_list.size() > 0) &&
             (position_list.back() == (unsigned int)pos))
            {
              pos = match_pattern.capturedStart(0) + 1;
            }
          else
            {
              if(p_peptide->getConstAa(pos).getNumberOfModification(mod) ==
                 modification_counter)
                {
                  position_list.push_back(pos);
                }
              pos = match_pattern.capturedStart(0) + 1;
            }
        }
      match_pattern = m_pattern.match(peptide_str, pos);
    }
}
} // namespace pappso
