/* BEGIN software license
 *
 * msXpertSuite - mass spectrometry software suite
 * -----------------------------------------------
 * Copyright(C) 2009,...,2019 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


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


/////////////////////// Local includes
#include "ProcessingSpec.hpp"
#include "MsFragmentationSpec.hpp"


namespace msxps
{
namespace minexpert
{

ProcessingSpec::ProcessingSpec()
{
}


ProcessingSpec::ProcessingSpec(const MsFragmentationSpec &ms_fragmentation_spec)
{
  mpa_msFragmentationSpec = new MsFragmentationSpec(ms_fragmentation_spec);
}


ProcessingSpec::ProcessingSpec(double start_value, double end_value)
  : m_start(start_value), m_end(end_value)
{
}


ProcessingSpec::ProcessingSpec(const MsFragmentationSpec &ms_fragmentation_spec,
                               double start_value,
                               double end_value)
  : mpa_msFragmentationSpec(new MsFragmentationSpec(ms_fragmentation_spec)),
    m_start(start_value),
    m_end(end_value)
{
}


ProcessingSpec::ProcessingSpec(const ProcessingSpec &other)
{
  if(other.mpa_msFragmentationSpec != nullptr)
    mpa_msFragmentationSpec =
      new MsFragmentationSpec(*other.mpa_msFragmentationSpec);

  m_start = other.m_start;
  m_end   = other.m_end;
}


ProcessingSpec::~ProcessingSpec()
{
  if(mpa_msFragmentationSpec != nullptr)
    delete mpa_msFragmentationSpec;
}


ProcessingSpec &
ProcessingSpec::operator=(const ProcessingSpec &other)
{
  if(this == &other)
    return *this;

  if(other.mpa_msFragmentationSpec != nullptr)
    mpa_msFragmentationSpec =
      new MsFragmentationSpec(*other.mpa_msFragmentationSpec);

  m_start = other.m_start;
  m_end   = other.m_end;

  return *this;
}


void
ProcessingSpec::setMsFragmentationSpec(
  const MsFragmentationSpec &fragmentation_spec)
{
  if(mpa_msFragmentationSpec != nullptr)
    delete mpa_msFragmentationSpec;

  mpa_msFragmentationSpec = new MsFragmentationSpec(fragmentation_spec);
}


MsFragmentationSpec
ProcessingSpec::getMsFragmentationSpec() const
{
  if(mpa_msFragmentationSpec != nullptr)
    return *mpa_msFragmentationSpec;

  return MsFragmentationSpec();
}


MsFragmentationSpec *
ProcessingSpec::getMsFragmentationSpecPtr()
{
  return mpa_msFragmentationSpec;
}


double
ProcessingSpec::getStart() const
{
  return m_start;
}


double
ProcessingSpec::getEnd() const
{
  return m_end;
}


void
ProcessingSpec::setRange(double start, double end)
{
  m_start = start;
  m_end   = end;
}


void
ProcessingSpec::resetRange()
{
  m_start = std::numeric_limits<double>::max();
  m_end   = std::numeric_limits<double>::min();
}


bool
ProcessingSpec::hasValidRange() const
{
  return (m_start < std::numeric_limits<double>::max() &&
          m_end > std::numeric_limits<double>::min());
}


bool
ProcessingSpec::hasValidFragmentationSpec() const
{
  if(mpa_msFragmentationSpec != nullptr)
    return mpa_msFragmentationSpec->isValid();
  else
    return false;
}


QString
ProcessingSpec::toString(int offset,
                         const QString &spacer,
                         const ProcessingType &processing_type) const
{
  QString lead;

  for(int iter = 0; iter < offset; ++iter)
    lead += spacer;

  QString text = lead;

  text += "Processing spec:\n";

  text += lead;
  text += spacer;
  text += "Type: ";
  text += processing_type.toString();
  text += "\n";

  QString start_string;
  if(m_start == std::numeric_limits<double>::max())
    start_string = "not set";
  else
    start_string = QString("%1").arg(m_start, 0, 'f', 6);

  QString end_string;
  if(m_end == std::numeric_limits<double>::min())
    end_string = "not set";
  else
    end_string = QString("%1").arg(m_end, 0, 'f', 6);

  text += lead;
  text += spacer;
  text +=
    QString("Integration range: [%1 -- %2]").arg(start_string).arg(end_string);

  text += "\n";

  if(mpa_msFragmentationSpec && mpa_msFragmentationSpec->isValid())
    {
      text += mpa_msFragmentationSpec->toString(offset + 1, spacer);
      // text += "\n";
    }

  return text;
}


} // namespace minexpert

} // namespace msxps
