#include "starresponse.hxx" 

#include <TROOT.h>
#include <TRandom2.h>  

#include "MStarLight.hxx" 
#include "MTrigger.hxx" 
#include "MFadc.hxx" 

using namespace std;

Int_t BuildStarLight( Float_t brightness, char *path, MTrigger *trigger, MFadc *fadc ) 
{ 
  //     this functions fills the things with the standard response
  //     function of MTrigger and MFadc
  //

  cout << " filling Starlight for Brightness " << brightness 
       << " phe/nsec " << endl ; 

  char filename[256] ; 
  
  TRandom2 Zufall( (UInt_t) brightness * 100)  ;      // a random generator

  MStarLight  data(fadc->GetFadcSlicesPerNanosec(), fadc->GetResponseSlicesFadc());
  // create  instance of the MStarLight 

  //  Shall I write the root file???

  int write_root;

  write_root= get_write_root();
  
  Float_t   trigresp[RESPONSE_SLICES_TRIG];

  //  Get information from Trigger instance!!!
  trigger->GetResponse(trigresp); 
  data.SetTrigResponse(trigresp); 
  
  data.SetAmplTrig ( trigger->GetAmplitude() ); 
  data.SetFwhmTrig ( trigger->GetFwhm() ); 
  
  Float_t  *fadcresp = new Float_t[fadc->GetResponseSlicesFadc()]; 

  //  Get information from FADC instance !!!!!
  fadc->GetResponse(fadcresp); 
  data.SetFadcResponse(fadcresp); 

  data.SetShapeFadc ( fadc->GetShape() ); 
  data.SetIntegFadc ( fadc->GetIntegral() ); 
  data.SetFwhmFadc ( fadc->GetFwhm() ); 
 
  //  start with the loop over random events
  // 
  
  Float_t a     = 0.;   // the amplitude of the signal 
  Float_t time  = 0.;   // the time of the phe

  for (Int_t i = 0; i < (Int_t) (brightness * TIMERANGE) ; i++)
    {
      a = trigger->FillStar( 500, 10.) ;   // random the amplitude 
      time=Zufall.Rndm() * TIMERANGE ;     // random the time

      data.FillResponse(a, time ) ;        // fill the response function     
    }

  if(brightness<=1.0)
    sprintf(filename, "%sBrightness%.2f.slt", path, brightness) ; 
  else
    sprintf(filename, "%sBrightness%.1f.slt", path, brightness) ; 

  data.WriteBinary( filename );

  if(write_root)
    {
      if(brightness<=1.0)
	sprintf(filename, "%sBrightness%.2f.root", path, brightness);
      else
	sprintf(filename, "%sBrightness%.1f.root", path, brightness);

      cout << " the file will be written in " << filename << endl;

      data.StoreHisto( filename );
    }

  data.Reset(); 

  return(0); 

}
// ======================================================================
// ======================================================================
// ======================================================================
// ======================================================================
// ======================================================================
// ======================================================================
int main (int argc, char **argv )
{
  cout << " Start with the StarResponse " << endl ; 

  //      first of all initalize ROOT
  
  TROOT starrespo("starrespo", "The response of MAGIC to Starlight");

  //   Variables that define the StarLight which is  going to be generated.

  float nphe_min=0.0, nphe_max=10.0, nphe_pre=0.1;

  float trig_fwhm,trig_ampl;
  float fadc_fwhm,fadc_integral;
  float fadc_slices_per_ns;
  Int_t fadc_shape, trig_shape;

  // 
  char path[256] ; 
  char parfilename[256];
  sprintf (path, "./") ; 

  //  Instance of MFadc and MTrigger needed inside BuildStarLight

  MTrigger *trigger;
  MFadc *fadc;

  if(argc == 1){
    sprintf(parfilename, "starresponse.par");
  }
  else{ // a filename was given
    sprintf(parfilename, "%s", argv[1]);
  }

  //  Reading parameters from input card

  readparam(parfilename);

  //  Setting the parameters read from teh input card
  strcpy( path,get_database_path());

  get_simulated_phe(&nphe_min, &nphe_max, &nphe_pre);

  get_trig_properties(&trig_shape, &trig_ampl, &trig_fwhm);
  trigger = new MTrigger(1,0.,0.,trig_ampl,trig_fwhm);

  get_fadc_properties(&fadc_shape, &fadc_integral, &fadc_fwhm, &fadc_slices_per_ns);

  fadc = new MFadc(1, fadc_shape, fadc_integral, fadc_fwhm,
		   fadc_shape, fadc_integral, fadc_fwhm, 0., fadc_slices_per_ns);

  // loop over Brightness

  // Limit precision (for speed reasons). Below 1 phe/ns/pixel we build the database
  // files in steps of 0.01 (minimum). Above 1 phe/ns/pixel the steps are of 0.1 at least. 
  // These values can be made larger through the input card of starresponse

  nphe_pre = nphe_pre < 0.01? 0.01 : nphe_pre;
  for (Float_t b = nphe_min; b <= 1.0; b += nphe_pre )
    BuildStarLight (b, path, trigger, fadc);  

  nphe_pre = nphe_pre < 0.1? 0.1 : nphe_pre;
  for (Float_t b = 1.0+nphe_pre; b <= nphe_max; b += nphe_pre )
    BuildStarLight (b, path, trigger, fadc);  

  delete(trigger);
  delete(fadc);

  return 0;
}

