//for wave form analysis
//made by arita 2011.12.27
#ifndef _WAVEFORM_H
#define _WAVEFORM_H

#include <fstream>
#include <string>
#include <vector>
#include "TFile.h"
#include "TString.h"
#include "TTree.h"

class WaveForm{
private:
   bool b_acc ;

   int n_sample;
   std::vector<float> adc;
   std::vector<float> time2f;
   std::vector<float> adc2f;

   int n_xpoint[2];//number of xpoint temporaly , 0:fall , 1:rise
   std::vector<int> accum_xpoint;
   std::vector<int> accum_xpoint_fall;
   std::vector<int> accum_xpoint_rise;

   std::vector<float> period;
   std::vector<float> period_beggining_point , period_end_point;

   float fit_para[4] , fit_para_error[4];

   int p_nsample;
   std::vector<float> p_adc1;
   std::vector<float> p_adc2;
   std::vector<float> p_time1;
   std::vector<float> p_time2;
   float fl_p_adcsum;
   int i_p_cnt;

   float fl_adcsum[2];
   int i_cnt[2];

   int n_acc_period;
   float acc_period_sum; //for approximationa
   float acc_period_stock[10000]; //for approximationa
   int stck;

   //variable for plot
   int wf_m_type;
   int wf_l_col;
   float  wf_m_size;
   TString wf_title , wf_xtitle , wf_ytitle;
   
public:
   WaveForm();
   virtual ~WaveForm(){};

   //General
   void SetWaveform( float *wf );
   void SetWaveform( int id ,  float fl_adc );
   void SetWaveform( int id , float fl_time ,  float fl_adc );
   int ShiftWaveform( float time_shift = 0. , float adc_shift = 0. );

   //Get general values
   int GetWaveform( std::vector<float>*rt_time , std::vector<float>*rt_adc );
   float GetTime( int id );
   float GetAdc( int id );
   int GetNsample( void ); 
   float GetMeanADC( void ); 
   float GetRMSADC( void ); 
   float Integral( int start_id , int end_id );
   int SortTime( void );

   //Plotting
   int SetMarkerStyle( int m_style );
   int SetLineColor( int col );
   int SetMarkerSize( float m_size );
   int SetTitle( TString wf_t );
   int SetTitleX( TString wf_t );
   int SetTitleY( TString wf_t );

   int Draw( TString option = "apl" , int col = 1);
   void Clear( void );

   //Fitting
   int FitSineWave( void );
   int SetFitParameter( int id , float para );
   float GetFitParameter( int id );
   float GetFitParError( int id );

   //Accumulator of cross points
   int n_accumulate;
   int AccumulateXpoint( float baseline = 0. );
   int GetAccumContent( int sample , int mode = 0); //mode{ 0:all , -1: fall ,1:rise }
   float GetAccumMean( int mode = 0); 
   float GetAccumRMS( int mode = 0); 
   int GetXpoint( int mode = 0); //mode 0:fall , 1:rise

   //Accum Period
   int AccumulatePeriodX( float baseline = 0. );
   float GetPeriodMean( void ); 
   float GetPeriodError( void );
   //Simple Period
   int CalcPeriod( float baseline = 0. ); //return number of period
   float GetPeriod( int id );
   float GetPeriodCrossPoint( int id , int begin_or_end ); //Cross point for 0:begin 1:end

   //Phase shift finder
   //This is local version for 128samples of 2 window
   //This is considered window odd or even
   int SetPhaseADC128( int fwin = 0, float base = 0 );
   float GetPhaseDifference128( int id ); //win_id : even=0 , odd=1
   int ClearPhaseAdc128( void );

   //General finder of phase shift
   void SetPhaseWaveform( float wf1[][2] , float wf2[][2]  ); //set 2 waveform to calc phase difference
   void SetPhaseWaveform(  int even_odd , int id , float time , float adc  ); //set 2 waveform to calc phase difference
   float AccumPhaseDifference( float base = 0.); 
   float GetPhaseDifference( void ); 
   int DrawPhaseWaveform( void );
   int ClearPhaseWaveform( void );

};

#endif
