/*
 * PndLmdDetector.cxx
 *
 *  Created on: Apr 28, 2009
 *      Author: huagen
  *Interface to virtual Monto Carlo
  * */
#include "PndLmd.h"

using std::cout;
using std::endl;

//class PndLmdGeo;

//default construtor
PndLmd :: PndLmd()
       : FairDetector()
{
    fPndLmdPointCollection = new TClonesArray("PndLmdMCPoint");
    fVerboseLevel = 1;

    ResetParameters();
}

//Construtor
PndLmd :: PndLmd(const char* name, Bool_t active, Int_t verbose)
   :FairDetector(name,active)
{
    fPndLmdPointCollection = new TClonesArray("PndLmdMCPoint");
    fVerboseLevel = verbose;
}

PndLmd :: ~PndLmd(){
		    if (fPndLmdPointCollection){
	    	fPndLmdPointCollection->Delete();
	    	delete fPndLmdPointCollection;
	    }
}

//void PndLmd::Initialize()
//{
// Registers hits collection in Root manager;
// sets sensitive volumes.
// ---
//  std::cout<<" -I- Initializing PndLmd()"<<std::endl;
//}

Bool_t PndLmd :: ProcessHits(FairVolume* vol){


	    TParticle* particle =  gMC->GetStack()->GetCurrentTrack();
		Int_t PDGCode = particle->GetPdgCode();

		if (PDGCode == -2212)
		 {
				//cout << " Particle MCId which hit the sensor : " << PDGCode <<endl;
		    	if (gMC->IsTrackEntering())
		    	 {
		    		PndStack* stack = (PndStack*) gMC->GetStack();
		    		stack->AddPoint(kLUMI);

		    		// Set parameters at entrance of volume. Reset ELoss.
		    		fEnergyLoss  = 0.;
		    		fTime   = gMC->TrackTime() * 1.0e09;
		    		fLength = gMC->TrackLength();
		    		gMC->TrackPosition(fPosIn);
		    		gMC->TrackMomentum(fMomIn);

		    	}

		    	// Sum energy loss for all steps in the active volume
		    	fEnergyLoss += gMC->Edep();

		    	if (gMC->IsTrackExiting() ||
		    		gMC->IsTrackDisappeared() ||
		    		gMC->IsTrackStop())
		    	  {
		    		// Create PndLmdPoint at exit of active volume

		    		fTrackID  = gMC->GetStack()->GetCurrentTrackNumber();
		    		fVolumeID = vol->getMCid();
		    		gMC->TrackPosition(fPosOut);
		    		gMC->TrackPosition(fMomOut);
		    		fDetName = gMC->CurrentVolPath();

					AddPoint(fTrackID, fVolumeID, fDetName,
							TVector3 (fPosIn.X(), fPosIn.Y(), fPosIn.Z()),
							TVector3 (fPosOut.X(), fPosOut.Y(), fPosOut.Z()),
							TVector3 (fMomIn.X(), fMomIn.Y(), fMomIn.Z()),
							TVector3 (fMomOut.X(), fMomOut.Y(), fMomOut.Z()),
		    				fTime, fLength, fEnergyLoss);

		    		PndStack* stack = (PndStack*) gMC->GetStack();
		    		stack->AddPoint(kLUMI);

		    		ResetParameters();
		    	   }
		    }
		return kTRUE;
}

//define the EndOfEvent
  void PndLmd :: EndOfEvent(){
	if(fVerboseLevel)
		Print();
	Reset();
}

//define the Register
void PndLmd :: Register(){
	FairRootManager::Instance()->Register("LmdMCPoint", "PndLmd", fPndLmdPointCollection, kTRUE);
}

//define collection
TClonesArray* PndLmd::GetCollection(Int_t iColl) const {
    	if(iColl==0)
    		return fPndLmdPointCollection;
    	else
    		return NULL;
}

// -----   Public method Print   -------------------------------------------
void PndLmd::Print() const
{
  Int_t
    nHits = fPndLmdPointCollection->GetEntriesFast();

  std::cout << "-I- PndLmd: " << nHits << " points registered in this event."  << std::endl;

  if (fVerboseLevel>1)
    for (Int_t i=0; i<nHits; i++)
      (*fPndLmdPointCollection)[i]->Print();
}

//-------    Public method reset--------------------------------
void PndLmd :: Reset(){
	fPndLmdPointCollection->Clear();
	ResetParameters();
}

//-----------  Public method construct geometry-----------------

void PndLmd::ConstructGeometry()
{
    FairGeoLoader *geoLoad = FairGeoLoader::Instance();

    FairGeoInterface *geoFace = geoLoad->getGeoInterface();

    PndLmdGeo *thePndLmdGeo  = new PndLmdGeo();

    thePndLmdGeo->setGeomFile(GetGeometryFileName());
    geoFace->addGeoModule(thePndLmdGeo);

    Bool_t	rc = geoFace->readSet(thePndLmdGeo);

    if (rc)
    	thePndLmdGeo->create(geoLoad->getGeoBuilder());

    TList* volList = thePndLmdGeo->getListOfVolumes();

    ProcessNodes(volList);
}


//--------------  Private method AddHit    --------------------------
	PndLmdMCPoint* PndLmd :: AddPoint(Int_t trackID, Int_t detID, TString detname,
	    		TVector3 posIn, TVector3 posOut,
	    		TVector3 momIn, TVector3 momOut,
	    		Double_t time, Double_t length, Double_t eLoss) const
	    	{

		// Get a reference to the hit collection
		    TClonesArray &points = *fPndLmdPointCollection;

		//Get the number of hits
		    Int_t size=points.GetEntriesFast();

		//// create a new hit after the last one present in the collection
		    return new(points[size]) PndLmdMCPoint(trackID, detID, posIn, momIn,
		    		time, length, eLoss, posOut, momOut, detname);

	}

//-------------- Private method ResetParameters  -------------------
  void PndLmd :: ResetParameters(){
	    fTrackID = fVolumeID = 0;
	    fTime = fLength = fEnergyLoss = 0;

	    fPosIn.SetXYZT(0., 0., 0., 0.);
	    fPosOut.SetXYZT(0., 0., 0., 0.);
	    fMomIn.SetXYZT(0., 0., 0., 0.);
	    fMomOut.SetXYZT(0., 0., 0., 0.);
}

ClassImp(PndLmd)










