#ifndef AdvMethod_h
#define AdvMethod_h

#include "Header.hh"
#include "AdvDomain.hh"
#include "AdvParamSet.hh"
#include "ElementContainer.hh"



/** @author TANIMORI Souichirou, AdvanceSoft Corp.
     *  @version 0.0
     */
class AdvMethod {

 protected:
    string methodName; // reffrence only afer initialising on construction

 protected:

    Double valueOfLikehood;


 protected:

     /**
      *  @return the value of the likehood for a method
      */
     virtual Double likehood()  = 0;

 public:

    /** default constructor */
    AdvMethod() ;

    /** copy constructor */
    AdvMethod(const AdvMethod &method);

    /** constructor */
    AdvMethod(const string name) { methodName=name; valueOfLikehood=0.0; };

    /** destructor */
    virtual ~AdvMethod() ;

    /** assignement operator */
    AdvMethod& operator = (const AdvMethod &method) ;

    /**
     *  set default values of parameters
     *
     *  @param[in] src an element container as the source
     */
    virtual AdvParamSet setDefaultParam(ElementContainer &src) = 0;


    /** 
     *  check the parameters for the method before fitting and vevaluation
     *
     *  @param[in] src    element container as source
     *  @param[in] domain domain for the method
     *  @param[in] param  parameters for the method
     */
    virtual Bool checkParam( ElementContainer &src,  AdvDomain &domain,  AdvParamSet &param) = 0;

    /**
     *  translate parameters to inner form
     *
     *  @param[in] src    element container as source
     *  @param[in] domain domain for the method
     *  @param[in] param  parameters for the method
     */
    virtual void toInnerForm( ElementContainer &src,  AdvDomain &domain,  AdvParamSet &param)  = 0;


    /** 
     *  fit the parameters so that the the function reporduces the source
     */
    virtual void fit()  = 0;


    /** 
     *  evaluate the values of the function in the domain
     */
    virtual void eval()  = 0;


    /**
     *  get trend / increase and decrease table;
     *
     *  table[0][i] : veluated value  of the fitted function at i / averaged value of histogram
     *  table[1][i] : 1st. derivative of the fitted function at i / averaged "1st. difference quatient"
     *  table[2][i] : 2nd. derivative of the fitted function at i / averaged "2nd. difference quatient"
     */
    virtual vector< vector<Double> > getTrend() = 0 ;


    ///**
    // *  Dump
    // */
    // void Dump() ;


    /**
     *
     */
    virtual void toElementContainer(ElementContainer &src, ElementContainer &dest) const = 0;


    /** 
     *  get the method name
     */
    string getMethodName() const ;

    /**
     * get the value of the likehood
     */
    Double getLikehood() const ;


    /** 
     *  get the fitted parameters
     */
    virtual AdvParamSet getFittedParam() const = 0;


    /**
     *  get the descriptions of parameters for the method.
     */
    virtual void getParamDescription() const  = 0;


    /**
     *  @retval true if the result function is analytically diffreantiable
     */
    virtual Bool differentiable() const = 0;


    /**
     *  @retval true if the Methosd supprot multi-thread processing
     */
    virtual Bool isMultiThreaded() const = 0;

    /**
     *  @retval true if fitting is not finished
     */
    virtual Bool isFitting() { return false ; };

    /**
     *
     */
    virtual void stopFit() {};

    virtual AdvParamSet *getLatestConvergenceStat() const = 0;
};

#endif // Manyo_develop_operation_AdvMethod_h

