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


/////////////////////// Qt includes
#include <QChar>
#include <QDebug>
#include <QString>


/////////////////////// Local includes
#include "CalcOptions.hpp"


namespace msxps
{

	namespace massxpert
	{


//! Constructs a calculation options object.
CalcOptions::CalcOptions()
{
  m_deepCalculation = false;
  m_massType        = MassType::MASS_BOTH;
  m_capping         = CAP_BOTH;
  m_monomerEntities = MONOMER_CHEMENT_NONE;
  m_polymerEntities = POLYMER_CHEMENT_NONE;
}


//! Constructs a calculation options object.
CalcOptions::CalcOptions(bool deepCalculation,
                         int massType,
                         int capping,
                         int monomerEntities,
                         int polymerEntities)
  : m_deepCalculation(deepCalculation),
    m_massType(massType),
    m_capping(capping),
    m_monomerEntities(monomerEntities),
    m_polymerEntities(polymerEntities)
{
}


//! Constructs a calculation options object.
CalcOptions::CalcOptions(const CalcOptions &other)
  : m_deepCalculation(other.m_deepCalculation),
    m_coordinateList(other.m_coordinateList),
    m_massType(other.m_massType),
    m_capping(other.m_capping),
    m_monomerEntities(other.m_monomerEntities),
    m_polymerEntities(other.m_polymerEntities),
    m_selectionType(other.m_selectionType)
{
}


//! Destroys the calculation options object.
CalcOptions::~CalcOptions()
{
  // Free all the coordinates from the list.
  while(!m_coordinateList.isEmpty())
    delete(m_coordinateList.takeFirst());
}


//! Modifies \p other to be identical to \p this.
/*!  \param other calculation options instance.
 */
void
CalcOptions::clone(CalcOptions *other) const
{
  Q_ASSERT(other != 0);

  other->m_deepCalculation = m_deepCalculation;
  other->m_massType        = m_massType;
  other->m_capping         = m_capping;
  other->m_monomerEntities = m_monomerEntities;
  other->m_polymerEntities = m_polymerEntities;

  other->m_coordinateList.empty();
  other->setCoordinateList(m_coordinateList);

  other->setSelectionType(m_selectionType);
}


//! Modifies \p this  to be identical to \p other.
/*!  \param other calculation options instance to be used as a mold.
 */
void
CalcOptions::mold(const CalcOptions &other)
{
  if(&other == this)
    return;

  m_deepCalculation = other.m_deepCalculation;
  m_massType        = other.m_massType;
  m_capping         = other.m_capping;
  m_monomerEntities = other.m_monomerEntities;
  m_polymerEntities = other.m_polymerEntities;

  m_coordinateList.empty();
  setCoordinateList(other.m_coordinateList);

  setSelectionType(other.m_selectionType);
}


//! Assigns other to \p this calculation options instance.
/*! \param other calculation options instance used as the mold to set
  values to \p this instance.

  \return a reference to \p this calculation options instance.
*/
CalcOptions &
CalcOptions::operator=(const CalcOptions &other)
{
  if(&other != this)
    mold(other);

  return *this;
}


//! Sets if the calculation is deep.
/*!  A deep calculation is a calculation that involves the
  recalculation of the mass of the monomers.

  \param deep true if the calculation must be deep, false otherwise.
*/
void
CalcOptions::setDeepCalculation(bool deep)
{
  m_deepCalculation = deep;
}


//! Returns if the calculation is deep.
/*!  A deep calculation is a calculation that involves the
  recalculation of the mass of the monomers.

  \return true if the calculation is deep, false otherwise.
*/
bool
CalcOptions::isDeepCalculation() const
{
  return m_deepCalculation;
}


void
CalcOptions::setCoordinateList(const Coordinates &coord)
{
  m_coordinateList.setCoordinates(coord);
}


void
CalcOptions::setCoordinateList(const CoordinateList &list)
{
  m_coordinateList.setCoordinates(list);
}


const CoordinateList &
CalcOptions::coordinateList() const
{
  return m_coordinateList;
}


//! Sets the mass type.
/*!
  \param value New mass type.
*/
void
CalcOptions::setMassType(int value)
{
  m_massType = value;
}


//! Returns the mass type.
/*!
  \return the mass type.
*/
int
CalcOptions::massType() const
{
  return m_massType;
}

void
CalcOptions::setSelectionType(SelectionType type)
{
  m_selectionType = type;
}


SelectionType
CalcOptions::selectionType() const
{
  return m_selectionType;
}


//! Sets the capping.
/*!
  \param value New capping.
*/
void
CalcOptions::setCapping(int value)
{
  m_capping = value;
}


//! Returns the capping.
/*!
  \return the capping.
*/
int
CalcOptions::capping() const
{
  return m_capping;
}


//! Sets the monomer entities.
/*!
  \param value New monomer entities.
*/
void
CalcOptions::setMonomerEntities(int value)
{
  m_monomerEntities = value;
}


//! Returns the monomer entities.
/*!
  \return the monomer entities.
*/
int
CalcOptions::monomerEntities() const
{
  return m_monomerEntities;
}


//! Sets the polymer entities.
/*!
  \param value New polymer entities.
*/
void
CalcOptions::setPolymerEntities(int value)
{
  m_polymerEntities = value;
}


//! Returns the polymer entities.
/*!
  \return the polymer entities.
*/
int
CalcOptions::polymerEntities() const
{
  return m_polymerEntities;
}

void
CalcOptions::debugPutStdErr() const
{
  qDebug() << "\n~~~~~~~~~~~~~~CalcOptions instance:\n"
           << this << "\n"
           << "m_deepCalculation:" << m_deepCalculation << "\n"
           << "m_coordinateList: \n";

  for(int iter = 0; iter < m_coordinateList.size(); ++iter)
    {
      Coordinates *coord = m_coordinateList.at(iter);
      qDebug() << "iter:" << iter << "-"
               << "[" << coord->start() << "-" << coord->end() << "]\n";
    }

  qDebug() << "m_capping:" << m_capping << "\n"
           << "m_monomerEntities:" << m_monomerEntities << "\n"
           << "m_polymerEntities:" << m_polymerEntities << "\n"
           << "m_selectionType:" << m_selectionType << "\n"
           << "~~~~~~~~~~~~~~\n";
}

} // namespace massxpert

} // namespace msxps
