#include "MLons.hxx"

using namespace std;

MLons::MLons(){
  //-----------------------------------------------------------------
  //
  //   Default constructor
  //

  fTrigShape = 0.0;
  fAmplTrig = 1.0;  
  fFwhmTrig = 2.0;

  fFadcShape = 0.0;
  fIntegFadc = 1.0;
  fFwhmFadc = 2.0;

  RandomNumber = new TRandom() ;
  RandomNumber -> SetSeed(0);

}

MLons::MLons(Float_t in_shapeT, Float_t in_amplT, Float_t in_FwhmT, 
	     Float_t in_shapeF, Float_t in_integF, Float_t in_FwhmF){
  //--------------------------------------------------------------------
  //
  //  Constructor overloaded I
  //

  fTrigShape = in_shapeT;
  fAmplTrig = in_amplT; 
  fFwhmTrig = in_FwhmT;

  fFadcShape = in_shapeF;
  fIntegFadc = in_integF;
  fFwhmFadc = in_FwhmF;

  RandomNumber = new TRandom() ; 
  RandomNumber -> SetSeed(0);
}

void MLons::Reset() {
  //-----------------------------------------------------------------
  //
  //  Reset the member variables
  //

  fTrigShape   = 0. ; 
  fAmplTrig    = 0. ; 
  fFwhmTrig    = 0. ; 

  fFadcShape   = 0. ; 
  fIntegFadc    = 0. ; 
  fFwhmFadc    = 0. ; 

  MSLStored.Reset();

}

void MLons::SetSeed(Int_t in)
{
  RandomNumber -> SetSeed(in);
}

Float_t MLons::GetAmplTrig () 
{
  return fAmplTrig  ; 
}

void MLons::SetAmplTrig (Float_t in ) 
{
  fAmplTrig = in ; 
}

Float_t  MLons::GetFwhmTrig () 
{
  return fFwhmTrig  ; 
}

void MLons::SetFwhmTrig (Float_t in ) 
{
  fFwhmTrig = in ; 
}


Float_t MLons::GetIntegFadc () 
{
  return fIntegFadc  ; 
}

void MLons::SetIntegFadc (Float_t in ) 
{
  fIntegFadc = in ; 
}

Float_t  MLons::GetFwhmFadc () 
{
  return fFwhmFadc  ; 
}

void MLons::SetFwhmFadc (Float_t in ) 
{
  fFwhmFadc = in ; 
}

void MLons::SetPath (Char_t in[])
{
  strcpy(path, & in[0]);  
}

void MLons::ReadBinaryMStarLight(char *filename){

  MSLStored.ReadBinary(filename); 

}

Int_t MLons::CheckTrig(){
  //--------------------------------------------------------------------
  //
  //  Parameters of MSLStored should be the same than the required ones
  //

  if (  fAmplTrig == MSLStored.GetAmplTrig() && 
	fFwhmTrig == MSLStored.GetFwhmTrig())
    return 1;

  return 0;
}

Int_t MLons::CheckFADC(){
  //--------------------------------------------------------------------
  //
  //  Parameters of MSLStored should be the same than the required ones
  //

  if (  fIntegFadc == MSLStored.GetIntegFadc() && 
	fFwhmFadc == MSLStored.GetFwhmFadc() && 
	fFadcShape == MSLStored.GetShapeFadc())
    return 1;

  return 0;
}

Int_t MLons::GetResponse(Float_t in_br, Float_t in_pre,
			 Float_t *out_tr, Float_t *out_Fr){
  //-------------------------------------------------------------------------
  //
  //   It reads the response from the database and put it in out_tr
  //

  Char_t filename_slt[256];
  Char_t cbright[10];
  Char_t cstoredbright[10];

  Int_t i;
  Int_t bin;
  Float_t start_bin;
  Float_t time;

  // The following code line commented means that the simulation will crash if
  // some pixel ask for more lons than what we have in the database.
  // The following code line uncommented would mean that the simulation does
  //  not crash if a pixel ask for more than it is simulated but would 
  // assign to it lees lons.
  if (in_br>49.9) in_br=49.9;  //  To avoid error for high required brightness
                                 //  It has to be improved

  //  Check if the the brightness is the same than the last time.
  //  NOTE: Same means, the smae inside the required precision!!!

  if(in_br<1.0){
    sprintf(cbright,"%4.2f",in_br);
    sprintf(cstoredbright,"%4.2f",MSLStored.GetBrightness());
  }
  else{
    sprintf(cbright,"%3.1f",in_br);
    sprintf(cstoredbright,"%3.1f",MSLStored.GetBrightness());
  }
  if (strcmp(cbright, cstoredbright)){
    
    // Building the filename
    // Note: it would be nice to get an algorithm that gets the name of 
    // files it needs to get brightness as a function of precison(in_pre),
    // brightnes (in_br) and the Star_files that are in the "Path" directory.

    strcpy(filename_slt, & path[0]);
    strcat(filename_slt, "Brightness");
    strcat(filename_slt, & cbright[0]);
  
    strcat(filename_slt, ".slt");
 
    // If brightness is different it check if the new file has the
    // required parameters.
    // Note: I could be faster to store the whole trigger and fadc
    // response and use it while brightness does not change. Then the
    // root file should be open and close here.

    ReadBinaryMStarLight( & filename_slt[0]);

    if (!(CheckTrig() && CheckFADC())) {
      cout<<"ERROR: The Database for light from Night Sky Background is wrong"<<endl<<"       Make sure that you generated the database with the same shape for Fadc and trigger taht you are asking now."<<endl; 
      return 0;
    }
    MSLStored.SetBrightness(in_br);

 }

  // Random number that decides the set of bins that the program will get
  start_bin=RandomNumber->Uniform(1.0e4);

  //  Filling trigger response

  bin=(Int_t)(start_bin*4);

  for (i=0;i<TRIGGER_TIME_SLICES;i++){

    time=((float)i)/SLICES_PER_NSEC;
    
    if (time>(bin-start_bin*4.0)/4.0) bin++;

    if (bin>=TRIGBINS) bin=bin-TRIGBINS;

    out_tr[i]=MSLStored.GetTrig(bin);
  }

  //  Filling fadc response

  bin=(Int_t) (start_bin*0.3);

  for (i=0;i<(Int_t) SLICES_MFADC;i++){

    time=((float)i)*WIDTH_FADC_TIMESLICE;
    
    if (time>(bin-start_bin*0.3)/0.3) bin++;

    if (bin>=FADCBINS) bin=bin-FADCBINS;

    out_Fr[i]=MSLStored.GetFadc(bin);
  }

  return 1;
}
