/* massXpert - the true massist's program.
   --------------------------------------
   Copyright(C) 2006,2007 Filippo Rusconi

   http://www.massxpert.org/massXpert

   This file is part of the massXpert project.

   The massxpert project is the successor to the "GNU polyxmass"
   project that is an official GNU project package(see
   www.gnu.org). The massXpert project is not endorsed by the GNU
   project, although it is released ---in its entirety--- under the
   GNU General Public License. A huge part of the code in massXpert
   is actually a C++ rewrite of code in GNU polyxmass. As such
   massXpert was started at the Centre National de la Recherche
   Scientifique(FRANCE), that granted me the formal authorization to
   publish it under this Free Software License.

   This software is free software; you can redistribute it and/or
   modify it under the terms of the GNU  General Public
   License version 3, as published by the Free Software Foundation.
   

   This software 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 software; if not, write to the

   Free Software Foundation, Inc.,

   51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/


/////////////////////// Local includes
#include "globals.hpp"
#include "massList.hpp"


namespace massXpert
{

  MassList::MassList(QString name, const QLocale &locale)
  {
    m_name = name;
    m_locale = locale;
  }


  MassList::MassList(QString name, 
		      const QString &text,
		      const QLocale &locale)
  {
    m_name = name;
    m_massText = text;
    m_locale = locale;
  }


  MassList::MassList(QString name, 
		      const QStringList & stringList,
		      const QLocale &locale)
  {
    m_name = name;
    m_locale = locale;
  
    if (!stringList.isEmpty())
      m_massStringList = stringList;
  }


  MassList::MassList(QString name, 
		      const QList <double> &doubleList,
		      const QLocale &locale)
  {
    m_name = name;
    m_locale = locale;
  
    QListIterator<double> iter(doubleList);
  
    while(iter.hasNext())
      {
	m_massList.append(iter.next());
      }
  }



  MassList::~MassList()
  {
  }


  MassList::MassList(const MassList &other)
    : m_name(other.m_name), m_comment(other.m_comment), 
      m_locale(other.m_locale),
      m_massText(other.m_massText), m_massStringList(other.m_massStringList)
  {
    QListIterator<double> iter(other.m_massList);
  
    while(iter.hasNext())
      {
	m_massList.append(iter.next());
      }
  }


  MassList * 
  MassList::clone() const
  {
    MassList *other = new MassList(*this);
  
    return other;
  }


  void 
  MassList::clone(MassList *other) const
  {
    Q_ASSERT(other);
  
    if (other == this)
      return;
  
    other->m_name = m_name;
    other->m_comment = m_comment;
    other->m_locale = m_locale;
  
    other->m_massText = m_massText;
    other->m_massStringList = m_massStringList;
  
    other->m_massList.clear();
  
    QListIterator<double> iter(m_massList);
  
    while(iter.hasNext())
      {
	other->m_massList.append(iter.next());
      }
  }


  void 
  MassList::mold(const MassList &other)
  { 
    if (&other == this)
      return;
  
    m_name = other.m_name;
    m_comment = other.m_comment;
    m_locale = other.m_locale;
  
    m_massText = other.m_massText;
    m_massStringList = other.m_massStringList;
  
    m_massList.clear();

    QListIterator<double> iter(other.m_massList);
  
    while(iter.hasNext())
      {
	m_massList.append(iter.next());
      }
  }


  MassList &
  MassList::operator =(const MassList &other)
  {
    if (&other != this)
      mold(other);
  
    return *this;
  }


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


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


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


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


  void 
  MassList::setLocale(const QLocale &locale)
  {
    m_locale = locale;
  }


  int 
  MassList::size() const
  {
    return m_massList.size();
  }


  const QList <double> &
  MassList::massList() const
  {
    return m_massList;
  }


  double 
  MassList::at(int index) const
  {
    Q_ASSERT(index >= 0 && index < m_massList.size());
  
    return m_massList.at(index);
  }


  const QString &
  MassList::massText() const
  {
    return m_massText;
  }


  int
  MassList::makeMassList()
  {
    if (m_massText.isEmpty())
      return 0;

    QStringList errorList;
  
    m_massStringList = m_massText.split(QRegExp("\n"), 
					 QString::SkipEmptyParts);

    for (int iter = 0; iter < m_massStringList.size(); ++iter)
      {
	bool ok = false;
      
	double value = m_locale.toDouble(m_massStringList.at(iter), &ok);
      
	if(!value && !ok)
	  {
	    errorList.append(m_massStringList.at(iter));
	  }
      
	m_massList.append(value);
      }
  
    // Because there was text, if an error occurred, then output the
    // error list and return -1.
  
    if (!errorList.isEmpty())
      {
	qDebug() << __FILE__ << __LINE__ 
		  << "Error list:" << errorList;
      
	return -1;
      }
    else
      return m_massList.size();
  }

  
  int
  MassList::makeMassText()
  {
    m_massText.clear();
  
    for (int iter = 0; iter < m_massList.size(); ++iter)
      {
	QString mass = 
	  m_locale.toString(m_massList.at(iter), 'f', MXP_OLIGOMER_DEC_PLACES);
		
	m_massText.append(mass + "\n");
      }

    return m_massText.size();
  }


  void
  MassList::sortAscending()
  {
    qSort(m_massList.begin(), m_massList.end());
  }


  void
  MassList::sortDescending()
  {
    qSort(m_massList.begin(), m_massList.end(), qGreater<double>());
  }


  void
  MassList::applyMass(double mass)
  {
    for (int iter = 0; iter < m_massList.size(); ++iter)
      {
	double value = m_massList.at(iter) + mass;

	m_massList.replace(iter, value);
      }
  }


  void
  MassList::removeLessThan(double mass)
  {
    QMutableListIterator<double> iter(m_massList);

    while(iter.hasNext())
      {
	double value = iter.next();
	if(value < mass)
	  {
	    iter.remove();
	  }
      }
  }

} // namespace massXpert
