/***************************************************************************
**
**  This file is part of DinverDCCore.
**
**  DinverDCCore 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.
**
**  DinverDCCore 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: 2009-05-14
**  Copyright: 2009-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "Forward.h"
#include "ParamLayer.h"

namespace DinverDCCore {

  /*!
    \class Forward Forward.h
    \brief Brief description of class still missing

    Full description of class still missing
  */

  /*!
    Description of constructor still missing
  */
  Forward::Forward()
  {
    TRACE;
    _targets=0;
    _paramModel=0;
  }

  /*!
    Description of destructor still missing
  */
  Forward::~Forward()
  {
    TRACE;
    delete _paramModel;
    delete _targets;
  }

  AbstractForward * Forward::clone() const
  {
    TRACE;
    Forward * forward=new Forward;
    if(_targets) {
      forward->setTargets(new TargetList(*_targets));
    }
    // Returned value assumed to be true (was true for this)
    if(_paramModel) {
      forward->setParamSpace(new ParamGroundModel(*_paramModel));
    }
    return forward;
  }

  bool Forward::setParamSpace(ParamGroundModel * gm)
  {
    TRACE;
    _paramModel=gm;
    /*
       Compatibility with older parameterizations without Poisson profile and
       with older parameterizations with Poisson profile but without type specification
    */
    ParamProfile * nu=_paramModel->find("Nu");
    if(nu && nu->type()!=ParamProfile::Condition) {
      _paramModel->removeProfile(nu);
      nu=nullptr;
    }
    if(!nu) {
      ParamProfile * p=new ParamProfile("Nu", tr("Poisson's Ratio"), tr(""), 0.2, 0.5,
                                        ParamProfile::Condition, SimpleCondition::GreaterThan);
      p->addLayer(new ParamLayer(p, 0, 0.2, 0.5, 0.0, 0.0) );
      _paramModel->addProfile(p);
    }

    _paramModel->initFinalProfiles();
    parameterSpace().clearParameters();
    if(!_paramModel->toParameters(parameterSpace())) return false;
    //_targets->setAlpha(addParam( "alpha", "", 0.0, 1.0));
    _targets->setParamProfiles(_paramModel, parameterSpace());
    return true;
  }

  void Forward::xml_writeChildren(XML_WRITECHILDREN_ARGS) const
  {
    TRACE;
    _targets->xml_save(s, context);
    _paramModel->xml_save(s, context);
  }

  XMLMember Forward::xml_member(XML_MEMBER_ARGS)
  {
    TRACE;
    Q_UNUSED(attributes)
    Q_UNUSED(context)
    if(tag=="TargetList" ) {
      if(_targets) delete _targets;
      _targets=new TargetList;
      return XMLMember(_targets);
    }
    else if(tag=="ParamGroundModel" ) {
      if(_paramModel) delete _paramModel;
      _paramModel=new ParamGroundModel;
      return XMLMember(_paramModel);
    }
    else return XMLMember(XMLMember::Unknown);
  }

  bool Forward::xml_polish(XML_POLISH_ARGS)
  {
    TRACE;
    Q_UNUSED(context)
    setParamSpace(_paramModel);
    parameterSpace().setVariableParameters();
    parameterSpace().adjustRanges();
    parameterSpace().humanInfo();
    return true;
  }

} // namespace DinverDCCore
