/* 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 <massxpert/nongui/CrossLinkList.hpp>
#include <massxpert/nongui/Polymer.hpp>


namespace msXpSmassXpert
{

CrossLinkList::CrossLinkList(const QString &name,
                             Polymer *polymer,
                             const QString &comment)
  : m_name(name), mp_polymer(polymer), m_comment(comment)
{
}


CrossLinkList::CrossLinkList(const CrossLinkList *other)
  : QList<CrossLink *>(*other),
    m_name(other->m_name),
    mp_polymer(other->mp_polymer),
    m_comment(other->m_comment)
{
  // And now copy all the items from other in here:
  for(int iter = 0; iter < other->size(); ++iter)
    {
      CrossLink *crossLink = other->at(iter);

      CrossLink *crossLinkNew = new CrossLink(crossLink->polChemDef(),
                                              crossLink->polymer(),
                                              crossLink->name(),
                                              crossLink->formula(),
                                              crossLink->comment());

      append(crossLinkNew);
    }
}


CrossLinkList::~CrossLinkList()
{
  qDeleteAll(begin(), end());
  clear();
}


CrossLinkList *
CrossLinkList::clone() const
{
  CrossLinkList *other = new CrossLinkList(this);

  return other;
}


void
CrossLinkList::clone(CrossLinkList *other) const
{
  Q_ASSERT(other);

  if(other == this)
    return;

  other->m_name     = m_name;
  other->m_comment  = m_comment;
  other->mp_polymer = mp_polymer;

  // Now empty and clear the other list.
  qDeleteAll(other->begin(), other->end());
  other->clear();

  // And now copy all the items to other from here:
  for(int iter = 0; iter < size(); ++iter)
    {
      CrossLink *crossLink = at(iter);

      CrossLink *crossLinkNew = new CrossLink(crossLink->polChemDef(),
                                              crossLink->polymer(),
                                              crossLink->name(),
                                              crossLink->formula(),
                                              crossLink->comment());

      other->append(crossLinkNew);
    }
}


void
CrossLinkList::mold(const CrossLinkList &other)
{
  if(&other == this)
    return;

  m_name     = other.m_name;
  m_comment  = other.m_comment;
  mp_polymer = other.mp_polymer;

  // Now empty and clear this list.
  qDeleteAll(begin(), end());
  clear();

  // And now copy all the items from other in here:
  for(int iter = 0; iter < other.size(); ++iter)
    {
      CrossLink *crossLink = other.at(iter);

      CrossLink *crossLinkNew = new CrossLink(crossLink->polChemDef(),
                                              crossLink->polymer(),
                                              crossLink->name(),
                                              crossLink->formula(),
                                              crossLink->comment());

      append(crossLinkNew);
    }
}


CrossLinkList &
CrossLinkList::operator=(const CrossLinkList &other)
{
  if(&other != this)
    mold(other);

  return *this;
}


//! Sets the name.
/*!  \param name new name.
 */
void
CrossLinkList::setName(QString name)
{
  if(!name.isEmpty())
    m_name = name;
}


QString
CrossLinkList::name()
{
  return m_name;
}


//! Sets the comment.
/*!  \param comment new comment.
 */
void
CrossLinkList::setComment(QString comment)
{
  if(!comment.isEmpty())
    m_comment = comment;
}


const QString &
CrossLinkList::comment() const
{
  return m_comment;
}


void
CrossLinkList::setPolymer(Polymer *polymer)
{
  mp_polymer = polymer;
}


const Polymer *
CrossLinkList::polymer() const
{
  return mp_polymer;
}


int
CrossLinkList::crossLinksInvolvingMonomer(const Monomer *monomer,
                                          QList<int> *list) const
{
  int count = 0;

  for(int iter = 0; iter < size(); ++iter)
    {
      CrossLink *crossLink = at(iter);

      for(int jter = 0; jter < crossLink->monomerList()->size(); ++jter)
        {
          const Monomer *iterMonomer = crossLink->monomerList()->at(jter);

          if(monomer == iterMonomer)
            {
              count++;

              if(list)
                list->append(iter);
            }
        }
    }

  return count;
}

} // namespace msXpSmassXpert
