/**
 * \file src/gui/xic_view/xicwindow.cpp
 * \date 11/1/2018
 * \author Olivier Langella
 * \brief XIC window
 */

/*******************************************************************************
 * Copyright (c) 2018 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 "xicwindow.h"
#include "ui_xic_window.h"
#include "../project_view/projectwindow.h"
#include "xic_box/xicbox.h"
#include <pappsomspp/core/pappsoexception.h>

XicWindow::XicWindow(ProjectWindow *parent)
  : QMainWindow(parent), ui(new Ui::XicWindow)
{
  _project_window = parent;

  ui->setupUi(this);


  MasschroqFileParametersSp masschroqFileParametersSp =
    _project_window->getProjectSP().get()->getMasschroqFileParametersSp();

  masschroqFileParametersSp.get()->load(
    _project_window->getProjectSP()
      .get()
      ->getProposedMassSpectrometerParameterFamily());

  msp_detect_zivy =
    masschroqFileParametersSp.get()
      ->m_quantificationMethod.getTraceDetectionInterfaceCstSPtr();

  _p_zivy_dialog = new ZivyDialog(this);
  _p_zivy_dialog->setMasschroqFileParametersSp(masschroqFileParametersSp);
  _p_zivy_dialog->setXicExportParams();


  ui->xic_precision->setPrecision(
    masschroqFileParametersSp.get()
      ->m_quantificationMethod.getXicExtractionUppersPrecisionPtr());

  connect(_p_zivy_dialog,
          &ZivyDialog::accepted,
          this,
          &XicWindow::doAcceptedZivyDialog);
  connect(this,
          &XicWindow::operateXicAreaToCsv,
          _project_window,
          &ProjectWindow::doExportXicAreaToCsv);

#if QT_VERSION >= 0x050000
  // Qt5 code

#else
// Qt4 code
#endif
}

XicWindow::~XicWindow()
{
  qInfo();
  delete _p_zivy_dialog;
}

void
XicWindow::doEditZivyParams()
{
  _p_zivy_dialog->show();
}

void
XicWindow::clear()
{
  QLayoutItem *wItem;
  while((wItem = ui->xic_vertical_layout->layout()->takeAt(0)))
    {
      wItem->widget()->setVisible(false);
      ui->xic_vertical_layout->layout()->removeWidget(wItem->widget());
      delete wItem->widget();
    }
}

ProjectWindow *
XicWindow::getProjectWindow()
{
  return _project_window;
}
void
XicWindow::addXic(const PeptideEvidence *p_peptide_evidence)
{
  XicBox *p_box = new XicBox(this);
  p_box->setPeptideEvidence(p_peptide_evidence);
  ui->xic_vertical_layout->layout()->addWidget(p_box);
}

void
XicWindow::addXicInMsRun(const PeptideEvidence *p_peptide_evidence,
                         MsRunSp msrun_sp)
{
  XicBox *p_box = new XicBox(this);
  p_box->setPeptideEvidenceInMsRun(p_peptide_evidence, msrun_sp);
  ui->xic_vertical_layout->layout()->addWidget(p_box);
}

void
XicWindow::removeXicBox(XicBox *xic_box)
{
  xic_box->setVisible(false);
  ui->xic_vertical_layout->layout()->removeWidget(xic_box);
  delete xic_box;
}

pappso::PrecisionPtr
XicWindow::getXicExtractPrecision() const
{
  return (ui->xic_precision->getPrecision());
}


pappso::Enums::XicExtractMethod
XicWindow::getXicExtractionMethod() const
{
  return (ui->xic_extraction_method_widget->getXicExtractionMethod());
}


void
XicWindow::xicPrecisionChanged(pappso::PrecisionPtr precision [[maybe_unused]])
{
  qInfo();
  _project_window->getProjectSP()
    .get()
    ->getMasschroqFileParametersSp()
    .get()
    ->m_quantificationMethod.setXicExtractionUpperPrecisionPtr(precision);
  _project_window->getProjectSP()
    .get()
    ->getMasschroqFileParametersSp()
    .get()
    ->m_quantificationMethod.setXicExtractionLowerPrecisionPtr(precision);
  emit reExtractXicNeeded();
  qInfo();
}

void
XicWindow::xicDetect(const pappso::Xic &xic,
                     pappso::TraceDetectionSinkInterface *sink) const
{
  try
    {
      msp_detect_zivy->detect(xic, *sink, m_removePeakBase);
    }
  catch(pappso::PappsoException &error)
    {
      throw pappso::PappsoException(tr("Error in %1 %2 :\n%3")
                                      .arg(__FILE__)
                                      .arg(__FUNCTION__)
                                      .arg(error.qwhat()));
    }
  catch(std::exception &std_error)
    {
      throw pappso::PappsoException(tr("Error in %1 %2 std_error:\n%3")
                                      .arg(__FILE__)
                                      .arg(__FUNCTION__)
                                      .arg(std_error.what()));
    }
}

void
XicWindow::rtUnitChanged(QAbstractButton *button [[maybe_unused]])
{
  qInfo() << " begin";
  emit rtUnitChangeNeeded();
  qInfo() << "end";
}

bool
XicWindow::isRetentionTimeSeconds() const
{
  if(ui->rt_sec_radiobutton->isChecked())
    {
      return true;
    }
  return false;
}

void
XicWindow::doAcceptedZivyDialog()
{
  _p_zivy_dialog->updateProjectMasschroqFileParameters();
  msp_detect_zivy =
    _project_window->getProjectSP()
      .get()
      ->getMasschroqFileParametersSp()
      .get()
      ->m_quantificationMethod.getTraceDetectionInterfaceCstSPtr();
  _p_zivy_dialog->saveXicExportSettings();
  emit reExtractXicNeeded();
}


void
XicWindow::doXicExtractionMethodChanged(pappso::Enums::XicExtractMethod xic_method
                                        [[maybe_unused]])
{

  _project_window->getProjectSP()
    .get()
    ->getMasschroqFileParametersSp()
    .get()
    ->m_quantificationMethod.setXicExtractMethod(xic_method);
  emit reExtractXicNeeded();
}

void
XicWindow::doExportXicToCsv()
{
  QSettings settings;
  QString default_location = settings.value("path/export_ods", "").toString();

  QString filename =
    QFileDialog::getSaveFileName(this,
                                 tr("Save CSV directory"),
                                 QString("%1/new_dir").arg(default_location));

  settings.setValue("path/export_ods", QFileInfo(filename).absolutePath());


  std::vector<XicBox *> xic_boxs;

  for(int i = 0; i < ui->verticalLayout->layout()->count(); i++)
    {
      xic_boxs.push_back(
        dynamic_cast<XicBox *>(ui->verticalLayout->itemAt(i)->widget()));
    }
  emit operateXicAreaToCsv(filename, xic_boxs);
}

void
XicWindow::doChangeLockXaxisRule()
{
  if(m_lockXaxis)
    {
      ui->toolButton->setIcon(
        QIcon(":/icons/resources/icons/apache/firefox/unlock_icon.svg"));
      m_lockXaxis = false;
    }
  else
    {
      ui->toolButton->setIcon(
        QIcon(":/icons/resources/icons/apache/firefox/lock_icon.svg"));
      m_lockXaxis = true;
    }
}

void
XicWindow::doFitAllAxis(QString axis_name, QCPRange new_range)
{
  if(m_lockXaxis)
    {
      for(int i = 0; i < ui->verticalLayout->layout()->count(); i++)
        {
          XicBox *p_xic =
            dynamic_cast<XicBox *>(ui->verticalLayout->itemAt(i)->widget());
          p_xic->rescaleXicWidget(axis_name, new_range);
        }
    }
}
