/* BEGIN software license
 *
 * msXpertSuite - mass spectrometry software suite
 * -----------------------------------------------
 * Copyright(C) 2009,...,2026 Filippo Rusconi
 *
 * http://www.msxpertsuite.org
 *
 * This file is part of the msXpertSuite project.
 *
 * The msXpertSuite project is the successor of the massXpert project. This
 * project now includes various independent modules:
 *
 * - massXpert, model polymer chemistries and simulate mass spectrometric data;
 * - mineXpert, a powerful TIC chromatogram/mass spectrum viewer/miner;
 *
 * This program 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.
 *
 * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * END software license
 */

/////////////////////// StdLib includes

/////////////////////// Qt includes
#include <QDebug>
#include <QMainWindow>
#include <QSettings>
#include <pappsomspp/core/processing/combiners/mzintegrationparams.h>
#include <pappsomspp/core/trace/datapoint.h>

/////////////////////// pappsomspp includes

/////////////////////// Local includes
#include "../nongui/MassDataIntegratorTask.hpp"
#include "Application.hpp"
#include "ProgramWindow.hpp"
#include "TicXicChromTracePlotCompositeWidget.hpp"
#include "TicXicChromTracePlotWnd.hpp"
#include <MsXpS/libXpertMassGui/ColorSelector.hpp>

namespace MsXpS
{
namespace MineXpert
{

int TicXicChromTracePlotWnd::widgetCount = 0;

//! Construct an TicXicChromTracePlotWnd instance.
TicXicChromTracePlotWnd::TicXicChromTracePlotWnd(QWidget *parent,
                                                 const QString &title,
                                                 const QString &settingsTitle,
                                                 const QString &description)
  : BaseTracePlotWnd(parent, title, settingsTitle, description)
{
  setWindowIcon(qApp->windowIcon());
}

//! Destruct \c this TicXicChromTracePlotWnd instance.
TicXicChromTracePlotWnd::~TicXicChromTracePlotWnd()
{
  // qDebug();
}

QCPGraph *
TicXicChromTracePlotWnd::addTracePlot(
  const pappso::Trace &trace,
  [[maybe_unused]] MsRunDataSetCstSPtr ms_run_data_set_csp,
  const ProcessingFlow &processing_flow,
  const QColor &color,
  QCPAbstractPlottable *parent_plottable_p)
{
  // qDebug() << "Adding new trace plot with parent plottable:"
  //<< parent_plottable_p;

  // Allocate a TIC/XIC chromatogram-specific composite plot widget.

  TicXicChromTracePlotCompositeWidget *composite_widget_p =
    new TicXicChromTracePlotCompositeWidget(
      this, "retention time (min)", "counts (a.u.)");
  // qDebug() << "The color:" << color;

  QCPGraph *new_graph_p = finalNewTracePlotConfiguration(
    composite_widget_p, trace, processing_flow, color, parent_plottable_p);

  // Make sure we do create a new JS item for both the plot widget and the
  // graph.

  QJSValue returned_js_value;

  getProgramWindow()
    ->getScriptingWnd()
    ->getScriptingEnvironment()
    ->exposeQObject("plotWidget" /*name*/,
                    QString() /*alias*/,
                    "The newly created TicXicChromTracePlot widget",
                    dynamic_cast<QObject *>(composite_widget_p),
                    dynamic_cast<QObject *>(this),
                    returned_js_value,
                    QJSEngine::CppOwnership);

  QString sample_name = ms_run_data_set_csp->getMsRunId()->getSampleName();

  // qDebug() << "The color:" << color;

  getProgramWindow()
    ->getScriptingWnd()
    ->getScriptingEnvironment()
    ->exposeQObject("plotGraph" /*name*/,
                    sample_name.replace(" ", "_").replace("-", "_") /*alias*/,
                    "The newly created TicXicChromTracePlot graph",
                    dynamic_cast<QObject *>(new_graph_p),
                    dynamic_cast<QObject *>(composite_widget_p),
                    returned_js_value,
                    QJSEngine::CppOwnership);

  return new_graph_p;
}

std::pair<MsRunDataSetCstSPtr, QColor>
TicXicChromTracePlotWnd::finishedIntegratingToInitialTicChromatogram(
  MsRunDataSetTreeMassDataIntegratorToRt *mass_data_integrator_p)
{
  // qDebug();

  // This place might be construed as the root of the data analysis process,
  // because this function is called right after having loaded a mass spectrum
  // acquisition file. This is the place some of the parameters for integration
  // to a mass spectrum are defined depending on the fact that the user
  // has saved such parameters as default using the QSettings feature.

  // We get back the integrator that was made to work in another thread. Now get
  // the obtained data and work with them.

  // Store the MsRunDataSetSPtr for later use before deleting the integrattor.

  MsRunDataSetCstSPtr ms_run_data_set_csp =
    mass_data_integrator_p->getMsRunDataSet();

  pappso::Trace integrated_trace =
    mass_data_integrator_p->getMapTrace().toTrace();

  // Let's see the usage count of the MsRunDataSetCstSPtr.
  // qDebug() << "Usage count:" << ms_run_data_set_csp.use_count();

  if(!ms_run_data_set_csp->size())
    {
      qInfo() << "The MS run data set is empty.";

      // We can double-check this:
      if(integrated_trace.size())
        {
          // That's absurd, if the MS run data set is empty and we get data
          // points, programming error.
          qFatal() << "Programming error.";
        }

      // At this point, we have nothing to do. Inform the user.

      QMessageBox::information(
        this,
        "The MS run that was to be loaded is empty.",
        "Please, check that the file is not corrupted.\n",
        QMessageBox::Ok);

      // We have nothing to show, return.
      return std::pair(nullptr, QColor());
    }

  // Another possibility is that there are only MSn (n>1) data in the file, in
  // which case it is logical that the TIC trace returned by the integrator is
  // empty. Just inform the user.

  if(!integrated_trace.size())
    {
      QMessageBox::information(
        this,
        "The TIC chromatogram has no single point in it",
        "The loaded MS run data set has data that did not produce\n"
        "a TIC chromatogram. This might be due to several reasons:\n"
        "\n"
        "- the mass data file contains no data\n"
        "- the mass data file contains only MSn data (no MS1 data).\n"
        "Since the TIC chromatogram is computed using *only* MS1 data,\n"
        "it is empty.\n"
        "\n"
        "In that last case, please check the data tree table view and start\n"
        "the mining session from there.\n",
        QMessageBox::Ok);
    }
  else if(integrated_trace.size() < 2)
    {
      // Note that if the mass data file that was loaded contained a single mass
      // spectrum, or if the integration yielded a single TIC value for a single
      // retention time, then there would be no TIC. So we need to craft a fake
      // one with two points: (current,TIC) and (current+1,TIC).

      // This situation might be encountered when the user integration to RT:
      //
      // 1. a single spectrum for a given RT
      //
      // 2. multiple spectra for a single RT (that is, multiple specra of
      // different DT values but of a single RT value).

      // In this situation the single data point that is there has x = <value> ;
      // so just create a new one with x = <value + 1>.

      pappso::DataPoint unique_data_point = integrated_trace.back();

      // qDebug() << "tic trace:" << integrated_trace.toString();

      integrated_trace.push_back(
        pappso::DataPoint(unique_data_point.x + 1, unique_data_point.y));

      // qDebug() << "tic trace:" << integrated_trace.toString();
    }

  // The mass data integrator, in its constructor (MassDataIntegrator base
  // class) allocates a new ProcessingFlow. That member is never nullptr.

  // Do not forget to copy the processing flow from the integrator,
  // because the integrator is the parent of that ProcessingFlow instance and it
  // will be deleted below. This processing flow will be set into the plot
  // widget ! Do a copy of it, without parentship (nullptr) because that copy
  // will later be passed as a reference to downstream code that will actually
  // allocate a new instance with proper parentship. Right after that we delete
  // the temporary ProcessingFlow.

  ProcessingFlow *temp_processing_flow_p =
    mass_data_integrator_p->getProcessingFlow()->clone(nullptr);

  // qDebug()
  //   << "After integrating to the first TIC chromatogram, processing flow:"
  //   << temp_processing_flow_p->toString(0, "  ");

  // Note that we are in special situation: we are now handling a TIC
  // chromatogram that was computed as a very first integration right after
  // having read data from file. We did set MS level to 1, because, by
  // definition the TIC chromatogram is computed using MS1 data only. But, there
  // is a problem: we cannot let that MS level: 1 value there, because it will
  // prevent all the other integrations to access data with MS level > 1. We
  // thus replace that MS level to 0, that means that all the data (whatever the
  // MS level) will be handled from here.

  ProcessingStepSPtr most_recent_step_sp =
    std::const_pointer_cast<ProcessingStep>(
      temp_processing_flow_p->mostRecentStep());

  // Logically, there should be no previous step since this should be the very
  // first step in the processing flow right after opening a data file.

  if(most_recent_step_sp != nullptr)
    qDebug() << "Odd situation that a processing step existed before now.";

  // if(most_recent_step_sp->destMatches("FILE_RT"))
  //   qFatal(
  //     "Cannot be that there are either no or more than one processing step
  //     for " "type FILE_RT");

  MsFragmentationSpec *fragmentation_spec_p =
    most_recent_step_sp->getMsFragmentationSpecPtr();

  // While we had set the MS level to 1 because when computing a TIC
  // chromatogram we only do that with MS1 data, we now want to set it to 0
  // because all the later integrations need to be capable of involving any
  // MS level. 0 states that MS level matches.

  fragmentation_spec_p->setMsLevel(0);

  // Sanity check
  if(ms_run_data_set_csp != temp_processing_flow_p->getMsRunDataSetCstSPtr())
    qFatal() << "Cannot be that the ms run data set pointers be different.";

  // Finally, we can delete the integrator, now that the
  // calculation is finished.
  delete mass_data_integrator_p;
  mass_data_integrator_p = nullptr;

  // Let's see the usage count of the MsRunDataSetCstSPtr.
  // qDebug() << "Usage count:" << ms_run_data_set_csp.use_count();

  // First thing is create the data plot graph tree, because this is the entry
  // point to the whole set of data plot graphs : the tree is root into the TIC
  // chromatogram plot graph because this is where the data exploration starts.

  // At this point, we need to get a color for the plot.
  // Set true to ask that the color be selected randomly if no color is
  // available.
  QColor plot_color = libXpertMassGui::ColorSelector::getColor(true);

  // Now we should document the mz integration parameters in the processing flow
  // that is mapped to the graph in such a way that the default mz integration
  // parameters that were calculated while loading the ms run from file are
  // available for the very first integration to mz that might occur.

  // All this is handled by the ProcessingFlow:
  // Heap-allocated
  pappso::MzIntegrationParams *mz_integration_params_p =
    temp_processing_flow_p->getSensibleMzIntegrationParams();

  // Finally, set it.
  temp_processing_flow_p->setDefaultMzIntegrationParams(
    *mz_integration_params_p);

  delete mz_integration_params_p;

#ifndef NDEBUG
  mz_integration_params_p =
    temp_processing_flow_p->getDefaultMzIntegrationParams();
  // We have set them above, they must be found!
  Q_ASSERT(mz_integration_params_p);

  // qDebug().noquote()
  //   << "The mz integration params set to the processing flow:\n"
  //   << mz_integration_params_p->toString(0, "  ");

#endif

  // Let's see the usage count of the MsRunDataSetCstSPtr.
  //	qDebug() << "Usage count:" << ms_run_data_set_csp.use_count();

  // And now that these params are documented, create the graph! Note the
  // nullptr parameter that shows that there is no parent graph here.

  // qDebug() << "going to call addTracePlot()";

  // FIXME:: we could get the graph and expose it to the JavaScript environment.
  addTracePlot(integrated_trace,
               ms_run_data_set_csp,
               *temp_processing_flow_p,
               plot_color,
               nullptr);

  delete temp_processing_flow_p;

  return std::pair<MsRunDataSetCstSPtr, QColor>(ms_run_data_set_csp,
                                                plot_color);
}

void
TicXicChromTracePlotWnd::integrateToRt(
  QCPAbstractPlottable *parent_plottable_p,
  std::shared_ptr<QualifiedMassSpectraVector> qualified_mass_spectra_sp,
  const ProcessingFlow &processing_flow)
{
  // Get the ms run data set that for the graph we are going to base the
  // integration on.
  MsRunDataSetCstSPtr ms_run_data_set_csp =
    processing_flow.getMsRunDataSetCstSPtr();
  if(ms_run_data_set_csp == nullptr)
    qFatal() << "Cannot be that the pointer is nullptr.";

  // FIXME: BEGIN Sanity check that might be removed when the program is
  // stabilized.
  std::pair<double, double> range_pair;

  bool integration_rt = processing_flow.innermostRange("ANY_RT", range_pair);

  if(!integration_rt)
    qFatal() << "Programming error.";

  // qDebug() << qSetRealNumberPrecision(10) << "Innermost RT range:"
  //          << "for y axis: " << range_pair.first << "-" << range_pair.second;

  // bool integration_dt = processing_flow.innermostRange("ANY_DT", range_pair);
  //
  // if(integration_dt)
  //   qDebug() << qSetRealNumberPrecision(10) << "Innermost DT range:"
  //            << "for y axis: " << range_pair.first << "-" <<
  //            range_pair.second;

  // FIXME: END Sanity check that might be removed when the program is
  // stabilized.

  // First prepare a vector of QualifiedMassSpectrumCstSPtr. If the
  // qualified_mass_spectra_sp is not empty, the
  // fillInQualifiedMassSpectraVector() function below does not change the
  // vector and returns its size.

  std::size_t qualified_mass_spectra_count = fillInQualifiedMassSpectraVector(
    ms_run_data_set_csp, qualified_mass_spectra_sp, processing_flow);

  // qDebug()
  //   << "The number of selected mass spectra on the basis of rough RT/DT
  //   values:"
  //   << qualified_mass_spectra_count;

  if(!qualified_mass_spectra_count)
    return;

  // Now start the actual integration work.

  // Allocate a mass data integrator to integrate the data.

  QualifiedMassSpectrumVectorMassDataIntegratorToRt *mass_data_integrator_p =
    new QualifiedMassSpectrumVectorMassDataIntegratorToRt(
      ms_run_data_set_csp, processing_flow, qualified_mass_spectra_sp);

  mass_data_integrator_p->setMaxThreadUseCount(
    mp_programWindow->getMaxThreadUseCount());

  // Ensure the mass data integrator messages are used.

  connect(
    mass_data_integrator_p,
    &QualifiedMassSpectrumVectorMassDataIntegrator::logTextToConsoleSignal,
    mp_programWindow,
    &ProgramWindow::logTextToConsole);

  MassDataIntegratorTask *mass_data_integrator_task_p =
    new MassDataIntegratorTask();

  // This signal starts the computation in the MassDataIntegratorTask object.
  connect(this,

          static_cast<void (TicXicChromTracePlotWnd::*)(
            QualifiedMassSpectrumVectorMassDataIntegratorToRt *)>(
            &TicXicChromTracePlotWnd::integrateToRtSignal),

          mass_data_integrator_task_p,

          static_cast<void (MassDataIntegratorTask::*)(
            QualifiedMassSpectrumVectorMassDataIntegratorToRt *)>(
            &MassDataIntegratorTask::integrateToRt),

          // Fundamental for signals that travel across QThread instances...
          Qt::QueuedConnection);

  // Allocate the thread in which the integrator task will run.
  QThread *thread_p = new QThread;

  // Move the task to the matching thread.
  mass_data_integrator_task_p->moveToThread(thread_p);
  thread_p->start();

  // Since we allocated the QThread dynamically we need to be able to destroy it
  // later, so make the connection.

  connect(mass_data_integrator_task_p,

          static_cast<void (MassDataIntegratorTask::*)(
            QualifiedMassSpectrumVectorMassDataIntegrator *)>(
            &MassDataIntegratorTask::finishedIntegratingDataSignal),

          this,

          [this,
           thread_p,
           mass_data_integrator_p,
           parent_plottable_p,
           mass_data_integrator_task_p]() {
            // Do not forget that we have to delete the MassDataIntegratorTask
            // allocated instance.
            mass_data_integrator_task_p->deleteLater();
            // Once the task has been labelled to be deleted later, we can stop
            // the thread and ask for it to also be deleted later.
            thread_p->deleteLater(), thread_p->quit();
            thread_p->wait();
            this->finishedIntegratingToRt(mass_data_integrator_p,
                                          parent_plottable_p);
          });

  // qDebug() << "the integrator pointer:" << mass_data_integrator_p;

  // Allocate a new TaskMonitorCompositeWidget that will receive all the
  // integrator's signals and provide feedback to the user about the ongoing
  // integration.

  libXpertMassGui::TaskMonitorCompositeWidget *task_monitor_composite_widget_p =
    mp_programWindow->mp_taskMonitorWnd->addTaskMonitorWidget(Qt::red);

  // Initialize the monitor composite widget's widgets and make all the
  // connections mass data integrator <--> widget.

  task_monitor_composite_widget_p->taskSetMainIdentifierText(
    ms_run_data_set_csp->getMsRunId()->getSampleName());
  task_monitor_composite_widget_p->taskSetDescriptionText(
    "Integrating to a TIC/XIC chromatogram");
  task_monitor_composite_widget_p->taskSetMinValue(0);

  // Make the connections

  // When the MsRunReadTask instance has finished working, it will send a signal
  // that we trap to finally destroy (after a time lag of some seconds, the
  // monitor widget.

  connect(mass_data_integrator_task_p,

          static_cast<void (MassDataIntegratorTask::*)(
            QualifiedMassSpectrumVectorMassDataIntegrator *)>(
            &MassDataIntegratorTask::finishedIntegratingDataSignal),

          task_monitor_composite_widget_p,

          &libXpertMassGui::TaskMonitorCompositeWidget::taskFinished,

          Qt::QueuedConnection);

  // If the user clicks the cancel button, relay the signal to the loader.
  connect(task_monitor_composite_widget_p,
          &libXpertMassGui::TaskMonitorCompositeWidget::cancelTaskSignal,
          mass_data_integrator_p,
          &QualifiedMassSpectrumVectorMassDataIntegrator::cancelOperation);

  // We need to register the meta type for std::size_t because otherwise it
  // cannot be shipped though signals.

  qRegisterMetaType<std::size_t>("std::size_t");

  task_monitor_composite_widget_p->makeSignalSlotConnections(
    mass_data_integrator_p);

  // task_monitor_composite_widget_p->makeMassDataIntegratorConnections(
  //   mass_data_integrator_p);

  emit integrateToRtSignal(mass_data_integrator_p);

  // We do not want to make signal/slot calls more than once. This is because
  // one user might well trigger more than one integration from this window to a
  // mass spectrum. Thus we do not want that *this window be still connected to
  // the specific mass_data_integrator_task_p when a new integration is
  // triggered. We want the signal/slot pairs to be contained to specific
  // objects. Each TicXicChromTracePlotWnd::integrateToRt() call must be
  // contained to a this/mass_data_integrator_task_p specific signal/slot pair.
  disconnect(this,

             static_cast<void (TicXicChromTracePlotWnd::*)(
               QualifiedMassSpectrumVectorMassDataIntegratorToRt *)>(
               &TicXicChromTracePlotWnd::integrateToRtSignal),

             mass_data_integrator_task_p,

             static_cast<void (MassDataIntegratorTask::*)(
               QualifiedMassSpectrumVectorMassDataIntegratorToRt *)>(
               &MassDataIntegratorTask::integrateToRt));
}

void
TicXicChromTracePlotWnd::finishedIntegratingToRt(
  QualifiedMassSpectrumVectorMassDataIntegrator *mass_data_integrator_p,
  QCPAbstractPlottable *parent_plottable_p)
{
  // This function is actually a slot that is called when the integration to mz
  // is terminated in a QThread.

  // qDebug() << "the integrator pointer:" << mass_data_integrator_p;

  // We get back the integrator that was made to work in another thread. Now get
  // the obtained data and work with them.

  // Make sure we make a copy of the ProcessingFlow stored in the
  // mass data integrator, because that ProcessingFlow is owned by the
  // mass data integrator and the latter will be destroyed below. We can make
  // the copy without parentship because we'll pass it as reference to
  // downstream code that will use that ref to allocate a new fully parented
  // instance.

  ProcessingFlow *temp_processing_flow_p =
    mass_data_integrator_p->getProcessingFlow()->clone(nullptr);

  // Store the MsRunDataSetSPtr for later use before deleting the integrattor.

  MsRunDataSetCstSPtr ms_run_data_set_csp =
    mass_data_integrator_p->getMsRunDataSet();

  // Sanity check
  if(ms_run_data_set_csp != temp_processing_flow_p->getMsRunDataSetCstSPtr())
    qFatal() << "Programming error. Not possible that the MsRunDataSet "
                "pointers do not match.";

  pappso::Trace integrated_trace =
    mass_data_integrator_p->getMapTrace().toTrace();
  // qDebug() << "mass spectrum trace size:" << integrated_trace.size();

  if(!integrated_trace.size())
    {
      qInfo() << "There is not a single point in the integrated trace.";
      return;
    }

  // Note that if the mass data file that was loaded contained a single mass
  // spectrum, or if the integration yielded a single TIC value for a single
  // retention time, then there would be no TIC. So we need to craft a fake one
  // with two points: (current,TIC) and (current+1,TIC).

  if(integrated_trace.size() < 2)
    {
      // This situation might be encountered when the user integration to RT:
      //
      // 1. a single spectrum for a given RT
      //
      // 2. multiple spectra for a single RT (that is, multiple specra of
      // different DT values but of a single RT value).

      // In this situation the single data point that is there has x = <value> ;
      // so just create a new one with x = <value + 1>.

      pappso::DataPoint unique_data_point = integrated_trace.back();

      // qDebug() << "tic trace:" << integrated_trace.toString();

      integrated_trace.push_back(
        pappso::DataPoint(unique_data_point.x + 1, unique_data_point.y));

      // qDebug() << "tic trace:" << integrated_trace.toString();
    }

  // Now that we got all we need and that we have made a safe copy
  // of the ProcessingFlow, we can delete the integrator.
  delete mass_data_integrator_p;
  mass_data_integrator_p = nullptr;

  // At this point, we need to get a color for the plot. That color needs to be
  // that of the parent.

  QColor plot_color;

  // There are two situations: either the integration started from a plot widget
  // and the color is certainly obtainable via the pen of the plot.
  if(parent_plottable_p != nullptr)
    plot_color = parent_plottable_p->pen().color();
  else
    // Or the integration started at the MsRunDataSetTableView and the color can
    // only be obtained via the MsRunDataSet in the OpenMsRunDataSetsDlg.
    plot_color = mp_programWindow->getColorForMsRunDataSet(ms_run_data_set_csp);

  // The new trace checks if there are push-pinned widgets. If so, the new trace
  // will be apportioned to the widgets according to the required mechanics:
  // new plot, sum, combine...

  newTrace(integrated_trace,
           ms_run_data_set_csp,
           *temp_processing_flow_p,
           plot_color,
           static_cast<QCPGraph *>(parent_plottable_p));

  // At this point, if the window is really not visible, then show it, otherwise
  // I was told that the user does not think that they can ask for the window to
  // show up in the main program window.

  if(!isVisible())
    {
      showWindow();
    }

  delete temp_processing_flow_p;
}

void
TicXicChromTracePlotWnd::integrateToMz(QCPAbstractPlottable *parent_plottable_p,
                                       const ProcessingFlow &processing_flow)
{
  if(parent_plottable_p == nullptr)
    qFatal() << "Cannot be that pointer is nullptr.";

  // We do not handle integrations to m/z, because each trace plot window
  // handles their own data. So we just relay this call to the main program
  // window that will in turn relay it to the mass spec plot window.

  // qDebug().noquote()
  //   << "Integrating to mz for graph with processing flow:"
  //   << processing_flow.toString();

  mp_programWindow->integrateToMz(parent_plottable_p, nullptr, processing_flow);
}

void
TicXicChromTracePlotWnd::integrateToDt(QCPAbstractPlottable *parent_plottable_p,
                                       const ProcessingFlow &processing_flow)
{
  if(parent_plottable_p == nullptr)
    qFatal() << "Cannot be that pointer is nullptr.";

  // We do not handle integrations to dt, because each trace plot window
  // handles their own data. So we just relay this call to the main program
  // window that will in turn relay it to the mass spec plot window.

  mp_programWindow->integrateToDt(parent_plottable_p, nullptr, processing_flow);
}

void
TicXicChromTracePlotWnd::integrateToDtMz(
  QCPAbstractPlottable *parent_plottable_p,
  const ProcessingFlow &processing_flow)
{
  if(parent_plottable_p == nullptr)
    qFatal() << "Cannot be that pointer is nullptr.";

  // We do not handle integrations to dt, because each trace plot window
  // handles their own data. So we just relay this call to the main program
  // window that will in turn relay it to the mass spec plot window.

  mp_programWindow->integrateToDtMz(
    parent_plottable_p, nullptr, processing_flow);
}

void
TicXicChromTracePlotWnd::integrateToMzRt(
  QCPAbstractPlottable *parent_plottable_p,
  const ProcessingFlow &processing_flow)
{
  if(parent_plottable_p == nullptr)
    qFatal() << "Cannot be that pointer is nullptr.";

  mp_programWindow->integrateToMzRt(
    parent_plottable_p, nullptr, processing_flow);
}

void
TicXicChromTracePlotWnd::integrateToDtRt(
  QCPAbstractPlottable *parent_plottable_p,
  const ProcessingFlow &processing_flow)
{
  if(parent_plottable_p == nullptr)
    qFatal() << "Cannot be that pointer is nullptr.";

  mp_programWindow->integrateToDtRt(
    parent_plottable_p, nullptr, processing_flow);
}

} // namespace MineXpert

} // namespace MsXpS
