#include "MDispCalc.h"

#include "MParList.h"

#include "MDisp.h"
#include "MHillas.h"
#include "MHillasSrc.h"

#include "MLog.h"
#include "MLogManip.h"

ClassImp(MDispCalc);

using namespace std;

static const TString gsDefName  = "MDispCalc";
static const TString gsDefTitle = "Calculate Disp related parameters";

// -------------------------------------------------------------------------
//
// Default constructor.
//
MDispCalc::MDispCalc(const char *name, const char *title)
    : fHillas(NULL), fHillasSrc(NULL), fSrcPos(NULL), fDisp(NULL)
{
    fName  = name  ? name  : gsDefName.Data();
    fTitle = title ? title : gsDefTitle.Data();

}

// -------------------------------------------------------------------------
//
Int_t MDispCalc::PreProcess(MParList *pList)
{

    fHillas = (MHillas*)pList->FindObject("MHillas");
    if (!fHillas)
    {
        *fLog << err << dbginf << "MHillas not found... aborting." << endl;
        return kFALSE;
    }

    fHillasSrc = (MHillasSrc*)pList->FindObject("MHillasSrc");
    if (!fHillasSrc)
    {
        *fLog << err << dbginf << "MHillasSrc not found... aborting." << endl;
        return kFALSE;
    }

    fSrcPos = (MSrcPosCam*)pList->FindObject("MSrcPosCam");
    if (!fSrcPos)
    {
        *fLog << err << dbginf << "SrcPosCam not found... aborting." << endl;
        return kFALSE;
    }

    fDisp = (MDisp*)pList->FindCreateObj("MDisp");
    if (!fDisp)
        return kFALSE;
 
    return kTRUE;
}

// -------------------------------------------------------------------------
//
Int_t MDispCalc::Process()
{

    fDisp->SetPsi(fPsi);

    if ( fHillas->GetWidth()==-1 || fHillas->GetLength()==-1 )
      {
	fErrors++;
	return kTRUE;
      }

    Float_t xshift = 0.;
    Float_t yshift = 0.;

    if ( fSrcPos )
      {
	xshift = fSrcPos->GetX();
	yshift = fSrcPos->GetY();
      }

    fDisp->SetDisp(fPsi*(1-(fHillas->GetWidth()/fHillas->GetLength())));
    fDisp->SetPosDisp("X1", fHillas->GetMeanX() - (fDisp->GetDisp()*fHillas->GetCosDelta()) - xshift);
    fDisp->SetPosDisp("Y1", fHillas->GetMeanY() - (fDisp->GetDisp()*fHillas->GetSinDelta()) - yshift);
    fDisp->SetPosDisp("X2", fHillas->GetMeanX() + (fDisp->GetDisp()*fHillas->GetCosDelta()) - xshift);
    fDisp->SetPosDisp("Y2", fHillas->GetMeanY() + (fDisp->GetDisp()*fHillas->GetSinDelta()) - yshift);

    if ( (1-fHillas->GetWidth()/fHillas->GetLength()) == 0. )
      {
	fErrors++;
	return kTRUE;
      }

    fDisp->SetPsiEvent(fHillasSrc->GetDist()/(1-fHillas->GetWidth()/fHillas->GetLength()));

    fDisp->SetReadyToSave();

    return kTRUE;
}

// --------------------------------------------------------------------------
//
//  Prints some statistics about the disp calculation. The percentage
//  is calculated with respect to the number of executions of this task.
//
Int_t MDispCalc::PostProcess()
{
    if (GetNumExecutions()==0)
        return kTRUE;

    *fLog << inf << endl;
    *fLog << GetDescriptor() << " execution statistics:" << endl;
    *fLog << dec << setfill(' ');
    *fLog << " " << fErrors << " (" << (int)(fErrors*100/GetNumExecutions()) << "%) Evts skipped due to: (1-w/l)==0 or (Width or Length == -1)" << endl;
    *fLog << endl;

    /*
    delete fHillas;
    delete fHillasSrc;
    delete fSrcPos;
    delete fDisp;
    */

    return kTRUE;
}
