#ifndef MARS_MJOptimizeBase
#define MARS_MJOptimizeBase

#ifndef MARS_MJob
#include "MJob.h"
#endif

class MTask;
class MFilter;

class MJOptimizeBase : public MJob
{
protected:
    Int_t  fDebug;
    Bool_t fEnableWeights;

    TList fRules;

    TList fPreCuts;
    TList fTrainCuts;
    TList fTestCuts;
    TList fPreTasks;
    TList fPostTasks;

    void AddCut(TList &l, const char *rule);
    void AddPar(TList &l, const char *rule, const char *name);
    void Add(TList &l, MTask *f);

public:
    MJOptimizeBase() : fDebug(-1), fEnableWeights(kFALSE)
    {
    }

    void AddPreTask(MTask *t)                    { Add(fPreTasks,  t); }
    void AddPreTask(const char *rule,
                    const char *name="MWeight")  { AddPar(fPreTasks, rule, name); }

    void AddPostTask(MTask *t)                   { Add(fPostTasks, t); }
    void AddPostTask(const char *rule,
                     const char *name="MWeight") { AddPar(fPostTasks, rule, name); }

    void SetDebug(Bool_t b=kTRUE)      { fDebug = b; }

    void SetWeights(const char *rule)  { if (fEnableWeights) return; fEnableWeights=kTRUE; AddPostTask(rule); }
    void SetWeights(MTask *t)          { if (fEnableWeights) return; fEnableWeights=kTRUE; AddPostTask(t);    }

    void AddPreCut(const char *rule)   { AddCut(fPreCuts, rule); }
    void AddPreCut(MFilter *f)         { Add(fPreCuts, (MTask*)(f)); }

    void AddTrainCut(const char *rule) { AddCut(fTrainCuts, rule); }
    void AddTrainCut(MFilter *f)       { Add(fTrainCuts, (MTask*)(f)); }

    void AddTestCut(const char *rule)  { AddCut(fTestCuts, rule); }
    void AddTestCut(MFilter *f)        { Add(fTestCuts, (MTask*)(f)); }

    Int_t AddParameter(const char *rule);

    ClassDef(MJOptimizeBase, 0)//Base class for all optimizations and trainings
};

#endif
