/* 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
 */


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


namespace MsXpS
{

namespace libXpertMass
{


/*!
\class MsXpS::libXpertMass::PolChemDefEntity
\inmodule libXpertMass
\ingroup PolChemDef
\inheaderfile PolChemDefEntity.hpp

\brief The PolChemDefEntity class describes a chemical entity that belongs to a
specific \l PolChemDef polymer chemistry definition.
*/

/*!
\variable MsXpS::libXpertMass::PolChemDefEntity::m_name

\brief The name of the chemical entity.
*/

/*!
\variable MsXpS::libXpertMass::PolChemDefEntity::mcsp_polChemDef

\brief The polymer chemistry definition that is the context of this
chemical entity.
*/


/*! Constructs a polymer chemistry definition entity.

\a pol_chem_def_csp reference polymer chemistry definition. This pointer
cannot be nullptr.

\a name name of the entity.
*/
PolChemDefEntity::PolChemDefEntity(PolChemDefCstSPtr pol_chem_def_csp,
                                   const QString &name)
{
  Q_ASSERT(pol_chem_def_csp);
  Q_ASSERT(pol_chem_def_csp.get());

  mcsp_polChemDef = pol_chem_def_csp;

  Q_ASSERT(!name.isEmpty());
  m_name = name;
}


/*! Constructs a PolChemDefEntity instance as a copy of \a other.
 */
PolChemDefEntity::PolChemDefEntity(const PolChemDefEntity &other)
  : mcsp_polChemDef(other.mcsp_polChemDef), m_name(other.m_name)
{
  if(mcsp_polChemDef == nullptr)
    qFatal("Programming error. The pointer cannot be nullptr.");

  if(m_name.isEmpty())
    qFatal(
      "Programming error. The polymer chemistry entity cannot have an empty "
      "name.");
}

/*!
\brief Destructs this PolChemDefEntity instance.
*/
PolChemDefEntity::~PolChemDefEntity()
{
}

/*!
\brief Assigns \a other to this PolChemDef instance.

Returns a reference to this PolChemDef instance
 */
PolChemDefEntity &
PolChemDefEntity::operator=(const PolChemDefEntity &other)
{
  if(&other == this)
    return *this;

  mcsp_polChemDef = other.mcsp_polChemDef;
  m_name          = other.m_name;

  return *this;
}


/*!
\brief Sets the \a name.
*/
void
PolChemDefEntity::setName(const QString &name)
{
  m_name = name;
}


/*!
\brief Returns the name.
*/
QString
PolChemDefEntity::name() const
{
  Q_ASSERT(!m_name.isEmpty());
  return m_name;
}


/*!
\brief Sets this PolChemDefEntity's \a pol_chem_def_csp.
*/
void
PolChemDefEntity::setPolChemDefCstSPtr(PolChemDefCstSPtr pol_chem_def_csp)
{
  mcsp_polChemDef = pol_chem_def_csp;
}


/*!
\brief Returns the polymer chemistry definition.
*/
PolChemDefCstSPtr
PolChemDefEntity::getPolChemDefCstSPtr() const
{
  Q_ASSERT(mcsp_polChemDef);
  Q_ASSERT(mcsp_polChemDef.get());
  return mcsp_polChemDef;
}

/*!
\brief Returns true if this PolChemDefEntity instance and \a other are
identical, false otherwise.
*/
bool
PolChemDefEntity::operator==(const PolChemDefEntity &other) const
{
  int tests = 0;

  Q_ASSERT(mcsp_polChemDef && other.mcsp_polChemDef);
  Q_ASSERT(mcsp_polChemDef.get() && other.mcsp_polChemDef.get());
  tests += (mcsp_polChemDef == other.mcsp_polChemDef);

  Q_ASSERT(!m_name.isEmpty() && !other.m_name.isEmpty());
  tests += (m_name == other.m_name);

  if(tests < 2)
    return false;

  return true;
}

/*! Returns true if this PolChemDefEntity instance and \a other differ, false
otherwise.
*/
bool
PolChemDefEntity::operator!=(const PolChemDefEntity &other) const
{
  int tests = 0;

  Q_ASSERT(mcsp_polChemDef && other.mcsp_polChemDef);
  Q_ASSERT(mcsp_polChemDef.get() && other.mcsp_polChemDef.get());
  tests += (mcsp_polChemDef != other.mcsp_polChemDef);

  Q_ASSERT(!m_name.isEmpty() && !other.m_name.isEmpty());
  tests += (m_name != other.m_name);

  if(tests > 0)
    return true;

  return false;
}

/*!
\brief Returns true if this PolChemDef instance validates successfully, false
otherwise.

The name cannot be empty and the polymer chemistry definition cannot be nullptr.
*/
bool
PolChemDefEntity::validate() const
{
  int tests = 0;

  tests += (m_name.isNull() || m_name.isEmpty());
  tests += (!mcsp_polChemDef);
  tests += (!mcsp_polChemDef.get());

  if(tests)
    return false;

  return true;
}

} // namespace libXpertMass

} // namespace MsXpS
