#ifndef MARS_MRFEnergyEst
#define MARS_MRFEnergyEst

#ifndef MARS_MTask
#include "MTask.h"
#endif

#ifndef ROOT_TObjArray
#include <TObjArray.h>
#endif
#ifndef ROOT_TArrayD
#include <TArrayD.h>
#endif

class MHMatrix;
class MDataArray;
class MParameterD;

class MRFEnergyEst : public MTask
{
public:
    enum EstimationMode_t
    {
        kMean,
        kMaximum,
        kFit
    };
private:
    Bool_t       fDebug;      // Debugging of eventloop while training on/off

    TString      fFileName;   // File name to forest
    TObjArray    fEForests;   // List of forests

    MDataArray  *fData;       //! Used to store the MDataChains to get the event values
    MParameterD *fEnergyEst;  //! Used to storeestimated energy

    Int_t        fNumTrees;   //! Training parameters
    Int_t        fNumTry;     //! Training parameters
    Int_t        fNdSize;     //! Training parameters

    MHMatrix    *fTestMatrix; //! Test Matrix

    EstimationMode_t fEstimationMode;

    // MRFEnergyEst
    Int_t ReadForests(MParList &plist);

    // MTask
    Int_t PreProcess(MParList *plist);
    Int_t Process();

    // MParContainer
    Int_t ReadEnv(const TEnv &env, TString prefix, Bool_t print);

public:
    MRFEnergyEst(const char *name=NULL, const char *title=NULL);
    ~MRFEnergyEst();

    // Setter for estimation
    void  SetFileName(TString str)     { fFileName = str; }
    void  SetEstimationMode(EstimationMode_t op) { fEstimationMode = op; }

    // Setter for training
    void  SetNumTrees(Int_t n=-1)      { fNumTrees = n; }
    void  SetNdSize(Int_t n=-1)        { fNdSize   = n; }
    void  SetNumTry(Int_t n=-1)        { fNumTry   = n; }
    void  SetDebug(Bool_t b=kTRUE)     { fDebug = b; }

    // Train Interface
    Int_t Train(const MHMatrix &n, const TArrayD &grid);

    // Test Interface
    void  SetTestMatrix(MHMatrix *m=0) { fTestMatrix=m; }
    void  InitMapping(MHMatrix *m=0)   { fTestMatrix=m; }

    ClassDef(MRFEnergyEst, 0) // Task
};

#endif
