#include "machdefs.h"
#include <stdlib.h>
#include <typeinfo>
#include <iostream>
#include <string>

#include "nomgfdadapter.h"
#include "pipodrw.h"

#ifndef SANS_EVOLPLANCK
#include "objfitter.h"
#endif

//-------------------------------------------------------------------------
// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet GeneralFitData
//-------------------------------------------------------------------------

/* --Methode-- */
NOMAdapter_GeneralFitData::NOMAdapter_GeneralFitData(GeneralFitData* o)
  : NObjMgrAdapter(o)
{
mG = o;
}

/* --Methode-- */
NOMAdapter_GeneralFitData::~NOMAdapter_GeneralFitData()
{
}

/* --Methode-- */
NObjMgrAdapter* NOMAdapter_GeneralFitData::Clone(AnyDataObj* o)
{
GeneralFitData* g = dynamic_cast<GeneralFitData *>(o);
if (g) return ( new NOMAdapter_GeneralFitData(g) );
return ( new NObjMgrAdapter(o) );
}

/* --Methode-- */
string NOMAdapter_GeneralFitData::GetDataObjType()
{
return( "GeneralFitData " );
}


/* --Methode-- */
AnyDataObj* NOMAdapter_GeneralFitData::CloneDataObj(bool /*share*/)
{
return( new GeneralFitData(*mG) );
}

/* --Methode-- */
void NOMAdapter_GeneralFitData::SavePPF(POutPersist& pos, string const & nom)
{
#ifdef SANS_EVOLPLANCK
string tag = nom;  // A cause de const
mG->Write(pos,0,tag);
#else
ObjFileIO<GeneralFitData> fio(mG);
fio.Write(pos, nom);
#endif
}

/* --Methode-- */
void NOMAdapter_GeneralFitData::Print(ostream& os)
{
os << *(mG);
}

/* --Methode-- */
NTupleInterface* NOMAdapter_GeneralFitData::GetNTupleInterface(bool& adel)
{
adel = false;
return(mG);
}

/* --Methode-- */
GeneralFitData* NOMAdapter_GeneralFitData::GetGeneralFitData(bool& adel
 ,GeneralFitData::FitErrType errtype,double errscale,double errmin
 ,int i1,int i2,int j1,int j2)
{
adel = false;
if(!mG) return(NULL);

int n = mG->NData();
if(n<=0) return(NULL);
int nv = mG->NVar();
if(nv<=0) return(NULL);

i1 = (i1<0||i1>=n)? 0: i1;
i2 = (i2<0||i2>=n||i2<i1)? n-1: i2;
n = i2-i1+1;

// Pas de gestion des erreurs sur les Abscisses Xi
GeneralFitData* mGData = new GeneralFitData(nv,n,0);
adel = true;

double *x = new double[nv];
for(int i=i1;i<=i2;i++) {
  for(int j=0;j<nv;j++) x[j] = mG->Absc(j,i);
  double f = mG->Val(i);
  double e = mG->EVal(i);
  e = GeneralFitData::ComputeError(f,e,errtype,errscale,errmin);
  mGData->AddData(x,f,e);
  if(!mG->IsValid(i)) mGData->KillData(i);
}
delete [] x;

return mGData;
}

AnyDataObj* NOMAdapter_GeneralFitData::FitResidusObj(GeneralFit& mfit)
{
GeneralFitData* g = NULL;
#ifdef SANS_EVOLPLANCK
g = mG->FitResidus(mfit); 
#else
g = new GeneralFitData(ObjectFitter::FitResidus(*mG,mfit));
#endif
return g;
}

AnyDataObj* NOMAdapter_GeneralFitData::FitFunctionObj(GeneralFit& mfit)
{
GeneralFitData* g = NULL;
#ifdef SANS_EVOLPLANCK
g = mG->FitFunction(mfit); 
#else
g = new GeneralFitData(ObjectFitter::FitFunction(*mG,mfit));
#endif
return g;
}
