/**
 * \file CaloViewer.cpp
 * \author Elena Vannuccini
 */
#include <CaloViewer.h>

#define TUNGSIZE 26   // ACCERTARSI!!!!!!!
#define TUNGTICK 0.26
#define VCOL 1   // volume color
#define TCOL 13  // tungsten plane color 
#define SSIZE 0.12 // strip hit half-size
#define STICK 0.16 // strip hit half-tickness

// (mechanical) z-parameter of the calorimeter planes

/**
 * Method to retrieve x(y)-coordinate of a calorimeter strip
 */
Float_t GetCoordXY(Int_t view, Int_t plane, Int_t strip){

//     Float_t pich = 0.24;
//     Float_t edge = 0.16;
// //  ------------------------
//     Float_t shift = 0;
//     if( !view ){  // view=0 -> X	
// 	if( plane%2 ) shift = 0.05;
// 	else          shift = -0.05;
//     }else{        // view=1 -> Y
// 	if( plane%2 ) shift = -0.15;
// 	else          shift = -0.05;
//     }
// //  ------------------------
//     Float_t coord = 0;
// //    coord = coord + strip*pich; //strip = 0-95
//     coord = coord + strip*pich; //strip = 0-95
//     coord = coord + (Int_t)(strip/32)*edge*2;
//     coord = coord - 12.28;
//     coord = coord + shift;
//     return coord;
 
    CaloStrip st = CaloStrip(1);
//    st.UseMechanicalAlig();

    st.Set(view,plane,strip);
    if( !view ) return st.GetX();
    else        return st.GetY();
}

/**
 * Method to retrieve z-coordinate of a calorimeter strip
 */
Float_t GetCoordZ(Int_t view, Int_t plane){

//     Float_t coord = 0;    
//     if( !view ){  // view=0 -> X	
// 	if( plane%2 ) coord = -0.809*plane - 0.2*(plane-1)/2 - 26.762;
// 	else          coord = -0.809*plane - 0.2*plane/2 - 26.762;
//     }else{        // view=1 -> Y
// 	if( plane%2 ) coord = -0.809*plane - 0.2*(plane-1)/2 - 26.181;
// 	else          coord = -0.809*plane - 0.2*plane/2 - 26.181;
//     }
//     return coord;

    CaloStrip st = CaloStrip(1);
//    st.UseMechanicalAlig();

    st.Set(view,plane,0);
    return st.GetZ();
}

/**
 * Calorimeter volume (projections) constructor
 */
GCaloVolume::GCaloVolume(){

    Float_t marg = 0.5;
// cavity_l = new TBox(-1*TUNGSIZE/2,-26.181+0.16,TUNGSIZE/2,-45.751-0.16);
    cavity_l = new TBox(GetCoordXY(0,21,0)-marg-SSIZE,GetCoordZ(0,21)-marg-STICK,GetCoordXY(0,21,95)+marg+SSIZE,GetCoordZ(1,0)+marg+STICK);
    cavity_l->SetFillColor(VCOL);
    cavity_l->SetLineColor(1);
    
// cavity_r = new TBox(-1*TUNGSIZE/2-0.1,-26.181+0.16,TUNGSIZE/2-0.1,-45.751-0.16);
    cavity_r = new TBox(GetCoordXY(1,21,0)-marg-SSIZE,GetCoordZ(0,21)-marg-STICK,GetCoordXY(1,21,95)+marg+SSIZE,GetCoordZ(1,0)+marg+STICK);
    cavity_r->SetFillColor(VCOL);
    cavity_r->SetLineColor(1);
    
    for(Int_t ip=0; ip<22; ip++){
	Float_t zp =0;
	if( ip%2 ) zp = -0.809*ip-0.2*(ip-1)/2-26.4715;
	else       zp = -0.809*ip-0.2*ip/2-26.4715;
//     tplane_l[ip] =  new TBox(-1*TUNGSIZE/2,zp-TUNGTICK/2,TUNGSIZE/2,zp+TUNGTICK/2 );
	tplane_l[ip] =  new TBox(GetCoordXY(0,21,0)-marg-SSIZE,zp-TUNGTICK/2,GetCoordXY(0,21,95)+marg+SSIZE,zp+TUNGTICK/2 );
	tplane_l[ip]->SetFillColor(TCOL);
//     tplane_r[ip] =  new TBox(-1*TUNGSIZE/2-0.1,zp-TUNGTICK/2,TUNGSIZE/2-0.1,zp+TUNGTICK/2 );
	tplane_r[ip] =  new TBox(GetCoordXY(1,21,0)-marg-SSIZE,zp-TUNGTICK/2,GetCoordXY(1,21,95)+marg+SSIZE,zp+TUNGTICK/2 );
	tplane_r[ip]->SetFillColor(TCOL);
    }
    
}
//
void GCaloVolume::DrawProjectionX(){
    cavity_l->Draw();
    for(Int_t ip=0; ip<22; ip++)tplane_l[ip]->Draw();
}
//
void GCaloVolume::DrawProjectionY(){
    cavity_r->Draw();
    for(Int_t ip=0; ip<22; ip++)tplane_r[ip]->Draw();
}
//
void GCaloVolume::Delete(){
    cavity_l->Delete();
    cavity_r->Delete();
    for(Int_t ip=0; ip<22; ip++)tplane_l[ip]->Delete();
    for(Int_t ip=0; ip<22; ip++)tplane_r[ip]->Delete();
};

//===============================================================
//
//
//===============================================================


/**
 * Constructor
 */
GCaloLevel2::GCaloLevel2(){
    HitX = new TClonesArray("GCaloHit");
    HitY = new TClonesArray("GCaloHit");
    DRAWCBAR=false;
}
GCaloLevel2::GCaloLevel2(CaloLevel1 *l1){
    HitX = new TClonesArray("GCaloHit");
    HitY = new TClonesArray("GCaloHit");
    SetLevel1(l1);
    DRAWCBAR=false;
}
GCaloLevel2::GCaloLevel2(PamLevel2* event){
    HitX = new TClonesArray("GCaloHit");
    HitY = new TClonesArray("GCaloHit");
    if(event->GetCaloLevel1())SetLevel1(event->GetCaloLevel1());
    if(event->GetCaloLevel2())SetLevel2(event->GetCaloLevel2());
    DRAWCBAR=false;
}
/**
 * Set level1 variables
 */
void GCaloLevel2::SetLevel1(CaloLevel1* l1){


    TClonesArray &hx = *HitX; Int_t nhx =0;
    TClonesArray &hy = *HitY; Int_t nhy =0;


//     cout<<"Calo event: "<<l1->istrip<<" hit strips \n";
    for(Int_t ih=0; ih<l1->istrip; ih++){
	Int_t view = -1;
	Int_t plane = -1;
	Int_t strip = -1;
	Float_t mip = l1->DecodeEstrip(ih,view,plane,strip);
// 	if(strip==96)cout<<"strip "<<strip<<endl;
	GCaloHit h = GCaloHit( GetCoordXY(view,plane,strip), GetCoordZ(view,plane), mip);
	if( !view ){ 
	    new(hx[nhx]) GCaloHit(&h);
	    nhx++;
	}else{
	    new(hy[nhy]) GCaloHit(&h);
	    nhy++; 
	}
    }

}
/**
 * Set level1 variables
 */
void GCaloLevel2::SetLevel2(CaloLevel2* l2){

    float cbarx[22];
    float cbary[22];
    float cbarxz[22];
    float cbaryz[22];
    for(Int_t ip=0; ip<22; ip++){
	cbarx[ip]=l2->cbar[ip][0];
	cbary[ip]=l2->cbar[ip][1];
	cbarxz[ip]=GetCoordZ(0,ip);
	cbaryz[ip]=GetCoordZ(1,ip);
    }
    cbarX = new TPolyMarker(22,cbarx,cbarxz);
    cbarY = new TPolyMarker(22,cbary,cbaryz);
    cbarX->SetMarkerSize(0.5);
    cbarX->SetMarkerColor(0);
    cbarY->SetMarkerSize(0.5);
    cbarY->SetMarkerColor(0);
    

}

void GCaloLevel2::Delete(){
    HitX->Delete();
    HitY->Delete();
    if(cbarX)cbarX->Delete();
    if(cbarY)cbarY->Delete();
}
void GCaloLevel2::Clear(){
    HitX->Clear("C");
    HitY->Clear("C");
    if(cbarX)cbarX->Delete();
    if(cbarY)cbarY->Delete();
}

void GCaloLevel2::DrawProjectionX(){
    TClonesArray &s = *(HitX);
//     cout<<"Calorimeter: X hits: "<<HitX->GetEntries()<<endl;
    for(Int_t is=0; is<HitX->GetEntries(); is++){
	((GCaloHit*)s[is])->Draw();
    };    
    if(DRAWCBAR)cbarX->Draw();
}

void GCaloLevel2::DrawProjectionY(){
    TClonesArray &s = *(HitY);
//     cout<<"Calorimeter: Y hits: "<<HitY->GetEntries()<<endl;
    for(Int_t is=0; is<HitY->GetEntries(); is++){
	((GCaloHit*)s[is])->Draw();
    };    
    if(DRAWCBAR)cbarY->Draw();
}
//===============================================================
//
//
//===============================================================
GCaloHit::GCaloHit(){
    hit = new TBox();
}

GCaloHit::GCaloHit(Float_t x, Float_t y, Float_t w){

//    cout << "box "<<x<<" "<<y<<endl;
//    hit = new TBox(x-0.12,y-0.2745,x+0.12,y+0.2745);
    hit = new TBox(x-SSIZE,y-STICK,x+SSIZE,y+STICK);
    //set color according to w
    Int_t colo = 10;
    if ( w > 0.7  ) colo = 38;
    if ( w > 2.   ) colo = 4;    
    if ( w > 10.  ) colo = 3;
    if ( w > 100. ) colo = 2;
    if ( w > 500. ) colo = 6;
    hit->SetFillColor(colo);

}

GCaloHit::GCaloHit( GCaloHit* gc ){
    hit = new TBox(*(gc->hit));
}

ClassImp(GCaloVolume);
ClassImp(GCaloLevel2);
ClassImp(GCaloHit);
