/***************************************************************************
**
**  This file is part of QGpCompatibility.
**
**  QGpCompatibility 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.
**
**  QGpCompatibility 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 Foobar.  If not, see <http://www.gnu.org/licenses/>
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2004-10-21
**  Copyright: 2004-2019
**    Marc Wathelet
**    Marc Wathelet (ULg, Liège, Belgium)
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <QGpCoreTools.h>
#include "CompatModalCurves.h"

namespace QGpCompatibility {

const QString CompatModalCurves::xmlModalCurvesTag="ModalCurves";

void CompatModalCurves::operator=(const CompatModalCurves& o)
{
  TRACE;
  CompatModalDataVector::operator=(o);
  _invalidValue=o._invalidValue;
}

CompatVDataPointVector CompatModalCurves::invalidMode()
{
  TRACE;
  CompatVDataPointVector m;
  CompatVDataPoint invalidPoint(_invalidValue, 0.0, 0.0);
  int nf=nOmegas();
  m.resize(nf);
  for(int i=0;i<nf;i++) m[i]=invalidPoint;
  return m;
}

void CompatModalCurves::setNModes(int nm)
{
  TRACE;
  if(nm>nModes()) {
   CompatVDataPointVector m=invalidMode();
   while(nModes()<nm) append(m);
  } else if(nm<nModes()) {
    resize(nm);
  }
}

void CompatModalCurves::setNOmegas(int nf)
{
  TRACE;
  int nm=nModes();
  for(int i=0;i<nm;i++) mode(i).resize(nf);
}

void CompatModalCurves::addInvalid()
{
  TRACE;
  int nm=nModes();
  CompatVDataPoint invalidPoint(_invalidValue, 0.0, 0.0);
  for(int im=0;im<nm;im++) {
    mode(im).append(invalidPoint);
  }
}

void CompatModalCurves::insertInvalidAt(int i)
{
  TRACE;
  int nm=nModes();
  CompatVDataPoint invalidPoint(_invalidValue, 0.0, 0.0);
  for(int im=0;im<nm;im++) {
    mode(im).insert(i,invalidPoint);
  }
}

void CompatModalCurves::insertModes(int atMode, int nNewModes)
{
  TRACE;
  CompatVDataPointVector m=invalidMode();
  insert(atMode, nNewModes, m);
}

int CompatModalCurves::validValues(int im) const
{
  TRACE;
  int n=0;
  const CompatVDataPointVector& point=mode(im);
  int nf=nOmegas();
  for(int i=0;i<nf;i++) {
    if(point[i].value()!=_invalidValue) n++;
  }
  return n;
}

void CompatModalCurves::resetValues()
{
  TRACE;
  int nm=nModes();
  for(int im=0;im<nm;im++) resetValues(im);
}

void CompatModalCurves::resetValues(int im)
{
  TRACE;
  int nf=nOmegas();
  CompatVDataPointVector& point=mode(im);
  for(int i=0;i<nf;i++) point[i].setValue(_invalidValue);
}

QVector<double> * CompatModalCurves::meanVector(int im) const
{
  ASSERT(im<nModes());
  return (*this)[im].meanVector();
}

QVector<double> * CompatModalCurves::stddevVector(int im) const
{
  ASSERT(im<nModes());
  return (*this)[im].stddevVector();
}

QVector<double> * CompatModalCurves::weightVector(int im) const
{
  ASSERT(im<nModes());
  return (*this)[im].weightVector();
}

QDataStream& operator<<(QDataStream& s, const CompatModalCurves& p)
{
  TRACE;
  int nf=p.nOmegas();
  for(int im=0;im<p.nModes();im++) {
    const CompatVDataPointVector& point=p.mode(im);
    for(int i=0;i<nf;i++) s << point[i].value();
  }
  return s;
}

QDataStream& operator>>(QDataStream& s, CompatModalCurves& p)
{
  TRACE;
  int nf=p.nOmegas();
  for(int im=0;im<p.nModes();im++) {
    CompatVDataPointVector& point=p.mode(im);
    double val;
    for(int i=0;i<nf;i++) {
      s >> val;
      point[i].setValue(val);
    }
  }
  return s;
}

void CompatModalCurves::xml_writeChildren(XML_WRITECHILDREN_ARGS) const
{
  TRACE;
  int nm=nModes();
  static const QString key("mode");
  XMLSaveAttributes att;
  QString& value=att.add(key);
  for(int i=0;i<nm;i++) {
    value=QString::number(i);
    (*this)[i].xml_save(s, context, att);
  }
}

XMLMember CompatModalCurves::xml_member(XML_MEMBER_ARGS)
{
  TRACE;
  Q_UNUSED(attributes)
  Q_UNUSED(context)
  if(tag=="DataPointVector") {
    append(CompatVDataPointVector());
    return XMLMember(&last());
  } else return XMLMember(XMLMember::Unknown);
}

} // namespace QGpCompatibility
