/***************************************************************************
**
**  This file is part of DinverCore.
**
**  DinverCore 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.
**
**  DinverCore 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: 2007-02-26
**  Copyright: 2007-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#ifndef SIMPLECONDITION_H
#define SIMPLECONDITION_H

#include "AbstractCondition.h"
#include "DinverCoreDLLExport.h"

namespace DinverCore {

class DINVERCORE_EXPORT SimpleCondition : public AbstractCondition
{
public:
  SimpleCondition(Parameter * p1, Type type, double factor, Parameter * p2, double constant);
  virtual bool operator==(const AbstractCondition& o) const;

  virtual const QString& xml_tagName() const {return xmlSimpleConditionTag;}
  static const QString xmlSimpleConditionTag;

  inline virtual void getLimits(int paramIndex, double& min, double& max) const;
  virtual bool adjustRanges();
  virtual void humanInfo() const;
protected:
  virtual uint internalChecksum() const;
  virtual void xml_writeProperties(XML_WRITEPROPERTIES_ARGS) const;
  virtual XMLMember xml_member(XML_MEMBER_ARGS);
  virtual bool xml_setProperty(XML_SETPROPERTY_ARGS);
private:
  Type _type;
  double _factor;
  double _constant;
};

} // namespace DinverCore

#include "Parameter.h"

namespace DinverCore {

inline void SimpleCondition::getLimits(int paramIndex, double& min, double& max) const
{
  TRACE;
  double threshold;
  switch (paramIndex) {
  case 0:
    threshold=_factor*parameter(1).realValue()+_constant;
    switch (_type) {
    case LessThan:
      if(threshold < max) {
        max=threshold;
      }
      break;
    case GreaterThan:
      if(threshold > min) {
        min=threshold;
      }
      break;
    case NoCondition:
      break;
    }
    break;
  default:
    threshold=parameter(0).realValue()-_constant;
    if(_factor==1.0) {
      switch (_type) {
      case LessThan:
        if(threshold>min) {
          min=threshold;
        }
        break;
      case GreaterThan:
        if(threshold<max) {
          max=threshold;
        }
        break;
      case NoCondition:
        break;
      }
    } else {
      switch (_type) {
      case LessThan:
        if(threshold>_factor*min) {
          min=threshold/_factor;
        }
        break;
      case GreaterThan:
        if(threshold<_factor*max) {
          max=threshold/_factor;
        }
        break;
      case NoCondition:
        break;
      }
    }
    break;
  }
}

} // namespace DinverCore

#endif // SIMPLECONDITION_H
