/**
 * \file gui/ptm_peptide_list_window/ptmpeptidetableproxymodel.cpp
 * \date 10/6/2017
 * \author Olivier Langella
 */

/*******************************************************************************
 * 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 "ptmpeptidetableproxymodel.h"
#include "ptmpeptidetablemodel.h"
#include "ptmpeptidelistwindow.h"
#include "../../grouping/ptm/ptmgroupingexperiment.h"
#include <pappsomspp/core/pappsoexception.h>
#include <QTextDocument>

PtmPeptideMenuQicon::PtmPeptideMenuQicon(
  const PtmGroupingExperiment *p_ptm_grouping_experiment,
  const PtmSampleScan *p_ptm_sample,
  const PeptideMatch *p_peptide_match)
  : QIcon(), _peptide_match(*p_peptide_match)
{
  _p_ptm_sample_scan         = p_ptm_sample;
  _p_ptm_grouping_experiment = p_ptm_grouping_experiment;
}
PtmPeptideMenuQicon::~PtmPeptideMenuQicon()
{
}
void
PtmPeptideMenuQicon::paint(QPainter *painter,
                           const QRect &rect [[maybe_unused]],
                           Qt::Alignment alignment [[maybe_unused]],
                           Mode mode [[maybe_unused]],
                           State state [[maybe_unused]]) const
{

  // if (option.state & QStyle::State_Selected)
  //    painter->fillRect(option.rect, option.palette.highlight());
  QTextDocument document;
  document.setDocumentMargin(2);
  document.setHtml(
    _p_ptm_sample_scan->getHtmlSequence(_p_ptm_grouping_experiment));
  // painter->translate(option.rect.topLeft());
  document.drawContents(painter);
  // painter->translate(-option.rect.topLeft());

  // edit_seq.render(painter);
  // edit..paint(painter, option.rect, option.palette,
  //                 StarRating::ReadOnly);
}


PtmPeptideMenuQaction::PtmPeptideMenuQaction(
  PtmPeptideTableProxyModel *parent,
  const PtmGroupingExperiment *p_ptm_grouping_experiment,
  const PtmSampleScan *p_ptm_sample,
  PeptideMatch *p_peptide_match)
  : QAction(parent)
{

  _p_ptm_peptide_table_proxy_model = parent;
  _peptide_match                   = *p_peptide_match;
  this->setIcon(PtmPeptideMenuQicon(
    p_ptm_grouping_experiment, p_ptm_sample, p_peptide_match));
  // this->setText(p_peptide_match->getPeptideXtpSp().get()->getSequence());

  QStringList position_list;
  for(unsigned int position :
      p_ptm_grouping_experiment->getPtmPositions(*p_peptide_match))
    {
      position_list << QString("%1").arg(position + 1);
    }
  this->setText(QString("%1 (%2)")
                  .arg(p_peptide_match->getPeptideEvidence()
                         ->getPeptideXtpSp()
                         .get()
                         ->toString())
                  .arg(position_list.join(" ")));
  // evalue_action.setChecked(_display_evalue);
  // connect(p_action, SIGNAL(toggled(bool)), this,
  // SLOT(showEvalueColumn(bool)));

#if QT_VERSION >= 0x050000
  // Qt5 code
  connect(this,
          &PtmPeptideMenuQaction::triggered,
          this,
          &PtmPeptideMenuQaction::doTriggered);
#else
  // Qt4 code
  connect(this, SIGNAL(triggered(bool)), this, SLOT(doTriggered(bool)));
#endif
}
void
PtmPeptideMenuQaction::doTriggered(bool triggered [[maybe_unused]])
{
  PeptideEvidence *p_peptide_evidence = _peptide_match.getPeptideEvidence();
  qDebug() << "PtmPeptideMenuQaction::doTriggered begin"
           << _peptide_match.getPeptideEvidence();
  qDebug() << "PtmPeptideMenuQaction::doTriggered begin 2 "
           << p_peptide_evidence;
  qDebug() << "PtmPeptideMenuQaction::doTriggered begin 3 "
           << p_peptide_evidence->getPeptideXtpSp().get()->toString();
  _p_ptm_peptide_table_proxy_model->getPtmPeptideListWindowP()
    ->askPeptideDetailView(p_peptide_evidence);
}

PtmPeptideMenuQaction::~PtmPeptideMenuQaction()
{
  // if (_p_ms_data_file != nullptr) delete _p_ms_data_file;
  qDebug() << "PtmPeptideMenuQaction::~PtmPeptideMenuQaction begin ";
}
PtmPeptideTableProxyModel::PtmPeptideTableProxyModel(
  PtmPeptideListWindow *p_ptm_peptide_list_window,
  PtmPeptideTableModel *ptm_table_model_p)
{
  _p_ptm_peptide_list_window = p_ptm_peptide_list_window;
  _p_ptm_table_model         = ptm_table_model_p;
}

PtmPeptideTableProxyModel::~PtmPeptideTableProxyModel()
{
}
PtmPeptideListWindow *
PtmPeptideTableProxyModel::getPtmPeptideListWindowP()
{
  return _p_ptm_peptide_list_window;
}

bool
PtmPeptideTableProxyModel::lessThan(const QModelIndex &left,
                                    const QModelIndex &right) const
{
  QVariant leftData  = sourceModel()->data(left);
  QVariant rightData = sourceModel()->data(right);

  if(leftData.canConvert<PtmSampleScan *>())
    {
      PtmSampleScan *p_ptm_sample_scan_left =
        qvariant_cast<PtmSampleScan *>(leftData);
      PtmSampleScan *p_ptm_sample_scan_right =
        qvariant_cast<PtmSampleScan *>(rightData);
      return p_ptm_sample_scan_left->getRepresentativePeptideMatch()
               .getPeptideEvidence()
               ->getPeptideXtpSp()
               .get()
               ->toAbsoluteString() <
             p_ptm_sample_scan_right->getRepresentativePeptideMatch()
               .getPeptideEvidence()
               ->getPeptideXtpSp()
               .get()
               ->toAbsoluteString();
    }
  else
    {
      return QSortFilterProxyModel::lessThan(left, right);
    }
}

bool
PtmPeptideTableProxyModel::filterAcceptsRow(int source_row,
                                            const QModelIndex &source_parent
                                            [[maybe_unused]]) const
{
  try
    {
      PtmSampleScanSp sample_scan =
        _p_ptm_table_model->getPtmSampleScanSpList().at(source_row);
      if(m_hideNoPtm)
        {
          if(sample_scan
               ->getObservedPtmPositionList(
                 _p_ptm_table_model->getPtmGroupingExperiment())
               .size() == 0)
            {
              return false;
            }
        }
    }
  catch(pappso::PappsoException &exception_pappso)
    {
      qDebug() << "Error in PtmPeptideTableProxyModel::acceptRow :"
               << exception_pappso.qwhat();
    }
  catch(std::exception &exception_std)
    {
      qDebug() << "Error in PtmPeptideTableProxyModel::acceptRow :"
               << exception_std.what();
    }

  return true;
}

void
PtmPeptideTableProxyModel::hideNoPtm(bool hide)
{
  qDebug() << hide;
  m_hideNoPtm = hide;
}


void
PtmPeptideTableProxyModel::showContextMenu(const QModelIndex &index)
{
  if(_p_context_menu == nullptr)
    {
      _p_context_menu = new QMenu(tr("Context menu"));
    }
  _p_context_menu->clear();
  QModelIndex source_index(this->mapToSource(index));
  int row = source_index.row();
  PtmSampleScanSp sp_ptm_sample_scan =
    _p_ptm_table_model->getPtmSampleScanSpList().at(row);

  PtmPeptideMenuQaction *p_action;
  for(auto p_peptide_match : sp_ptm_sample_scan.get()->getPeptideMatchList())
    {
      p_action = new PtmPeptideMenuQaction(
        this,
        _p_ptm_table_model->getPtmGroupingExperiment(),
        sp_ptm_sample_scan.get(),
        &p_peptide_match);
      _p_context_menu->addAction(p_action);
    }

  _p_context_menu->exec(QCursor::pos());

  //_p_context_menu->exec(_p_ptm_peptide_list_window->
  // mapToGlobal(QCursor::pos()));

  _p_context_menu->show();
}

void
PtmPeptideTableProxyModel::onTableClicked(const QModelIndex &index)
{
  qDebug() << "PtmPeptideTableProxyModel::onTableClicked begin " << index.row();
  qDebug() << "PtmPeptideTableProxyModel::onTableClicked begin "
           << this->mapToSource(index).row();

  //_protein_table_model_p->onTableClicked(this->mapToSource(index));
  QModelIndex source_index(this->mapToSource(index));
  int row = source_index.row();
  // int col = source_index.column();
  PtmSampleScanSp sp_ptm_sample_scan =
    _p_ptm_table_model->getPtmSampleScanSpList().at(row);

  if(sp_ptm_sample_scan.get()->getPeptideMatchList().size() == 1)
    {
      _p_ptm_peptide_list_window->askPeptideDetailView(sp_ptm_sample_scan.get()
                                                         ->getPeptideMatchList()
                                                         .at(0)
                                                         .getPeptideEvidence());
    }
  else
    {
      this->showContextMenu(index);
    }
  qDebug() << "PtmPeptideTableProxyModel::onTableClicked end " << index.row();
}
