/**
 * \file grouping/ptm/ptmsamplescan.cpp
 * \date 23/7/2017
 * \author Olivier Langella
 * \brief collection of PTM peptides sharing the same spectrum (sample scan)
 */

/*******************************************************************************
 * Copyright (c) 2017 Olivier Langella <olivier.langella@u-psud.fr>.
 *
 * This file is part of i2MassChroQ.
 *
 *     i2MassChroQ 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.
 *
 *     i2MassChroQ 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 i2MassChroQ.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Olivier Langella <olivier.langella@u-psud.fr> - initial API and
 *implementation
 ******************************************************************************/

#include "ptmsamplescan.h"
#include "../../grouping/ptm/ptmgroupingexperiment.h"


QColor PtmSampleScan::_color_best       = QColor("red");
QColor PtmSampleScan::_color_other_best = QColor("#ff7878");
QColor PtmSampleScan::_color_no_best    = QColor("yellow");


PtmSampleScan::PtmSampleScan(const PeptideMatch &peptide_match)
{
  _peptide_match_list.push_back(peptide_match);
}

PtmSampleScan::PtmSampleScan(const PtmSampleScan &other)
{
  _peptide_match_list = other._peptide_match_list;
}

PtmSampleScan::~PtmSampleScan()
{
}
const PeptideMatch &
PtmSampleScan::getRepresentativePeptideMatch() const
{
  // qDebug() << __FILE__ << " " << __FUNCTION__<< " " << __LINE__ << " " <<
  // _peptide_match_list.size();
  return _peptide_match_list[0];
}
bool
PtmSampleScan::add(const PeptideMatch &peptide_match)
{
  // qDebug() << __FILE__ << " " << __FUNCTION__<< " " << __LINE__ ;
  if(getRepresentativePeptideMatch()
       .getPeptideEvidence()
       ->getHashSampleScan() !=
     peptide_match.getPeptideEvidence()->getHashSampleScan())
    {
      return false;
    }

  // qDebug() << __FILE__ << " " << __FUNCTION__<< " " << __LINE__ ;
  if(getRepresentativePeptideMatch()
       .getPeptideEvidence()
       ->getPeptideXtpSp()
       .get()
       ->getSequence() !=
     peptide_match.getPeptideEvidence()->getPeptideXtpSp().get()->getSequence())
    {
      return false;
    }

  // qDebug() << __FILE__ << " " << __FUNCTION__<< " " << __LINE__ ;
  if(getRepresentativePeptideMatch()
       .getPeptideEvidence()
       ->getPeptideXtpSp()
       .get()
       ->getMass() !=
     peptide_match.getPeptideEvidence()->getPeptideXtpSp().get()->getMass())
    {
      return false;
    }
  _peptide_match_list.push_back(peptide_match);

  // qDebug() << __FILE__ << " " << __FUNCTION__<< " " << __LINE__ ;

  // sort list
  std::sort(_peptide_match_list.begin(),
            _peptide_match_list.end(),
            [](const PeptideMatch &first, const PeptideMatch &second) {
              return (first.getPeptideEvidence()->getEvalue() <
                      second.getPeptideEvidence()->getEvalue());
            });

  // qDebug() << __FILE__ << " " << __FUNCTION__<< " " << __LINE__ << " " <<
  // true;
  return true;
}

std::vector<unsigned int>
PtmSampleScan::getBestPtmPositionList(
  const PtmGroupingExperiment *p_ptm_grouping_experiment) const
{
  return p_ptm_grouping_experiment->getPtmPositions(
    getRepresentativePeptideMatch());
}

std::vector<unsigned int>
PtmSampleScan::getObservedPtmPositionList(
  const PtmGroupingExperiment *p_ptm_grouping_experiment) const
{
  std::vector<unsigned int> position_list;

  for(const PeptideMatch &peptide_match : _peptide_match_list)
    {
      std::vector<unsigned int> positionb_list =
        p_ptm_grouping_experiment->getPtmPositions(peptide_match);
      for(unsigned int position : positionb_list)
        {
          position_list.push_back(position);
        }
    }
  std::sort(position_list.begin(), position_list.end());
  auto last = std::unique(position_list.begin(), position_list.end());
  position_list.erase(last, position_list.end());
  return position_list;
}

const QString
PtmSampleScan::getHtmlSequence(
  const PtmGroupingExperiment *p_ptm_grouping_experiment) const
{
  const PeptideMatch &representative_peptide = getRepresentativePeptideMatch();
  size_t pep_size = representative_peptide.getPeptideEvidence()
                      ->getPeptideXtpSp()
                      .get()
                      ->size();
  // qDebug() << "ProteinMatch::getCoverage begin prot_size=" << prot_size << "
  // " << _protein_sp.get()-//>getSequence();
  if(pep_size == 0)
    {
      return 0;
    }

  bool best_bool[pep_size];
  bool other_best_bool[pep_size];
  bool nobest_bool[pep_size];
  for(size_t i = 0; i < pep_size; i++)
    {
      best_bool[i]       = false;
      other_best_bool[i] = false;
      nobest_bool[i]     = false;
    }


  double best_evalue = representative_peptide.getPeptideEvidence()->getEvalue();


  for(auto &peptide_match : _peptide_match_list)
    {
      bool is_best = false;
      if(peptide_match.getPeptideEvidence()->getEvalue() == best_evalue)
        {
          is_best = true;
        }
      std::vector<unsigned int> position_list =
        p_ptm_grouping_experiment->getPtmPositions(peptide_match);
      for(unsigned int position : position_list)
        {
          if(representative_peptide == peptide_match)
            {
              best_bool[position] = true;
            }
          else if(is_best)
            {
              other_best_bool[position] = true;
            }
          else
            {
              nobest_bool[position] = true;
            }
        }
    }
  QString sequence = representative_peptide.getPeptideEvidence()
                       ->getPeptideXtpSp()
                       .get()
                       ->getSequence();
  QString sequence_html;
  for(unsigned int i = 0; i < pep_size; i++)
    {
      if(best_bool[i])
        {
          sequence_html.append(QString("<span style=\"color:%2;\">%1</span>")
                                 .arg(sequence[i])
                                 .arg(_color_best.name()));
        }
      else if(other_best_bool[i])
        {
          sequence_html.append(QString("<span style=\"color:%2;\">%1</span>")
                                 .arg(sequence[i])
                                 .arg(_color_other_best.name()));
        }
      else if(nobest_bool[i])
        {
          sequence_html.append(QString("<span style=\"color:%2;\">%1</span>")
                                 .arg(sequence[i])
                                 .arg(_color_no_best.name()));
        }
      else
        {
          sequence_html.append(sequence[i]);
        }
    }
  return sequence_html;
}

std::vector<PeptideMatch> &
PtmSampleScan::getPeptideMatchList()
{
  return _peptide_match_list;
}
