#ifndef __SFPROCESSOR_HH
#define __SFPROCESSOR_HH

// This code borrows heavily from code by Kevin McKinny (UA)
// Currently the SF dependence is hard wired into the processing logic
// but this will soon contain file format independent abstractions of the
// processing logic.
// Yoshi Uchida 24 Jun 2002
//
// $Id: SFProcessor.hh,v 1.8 2002/07/23 23:21:22 kamland0 Exp $

#include "SFATWDBank.hh"
#include "SFHeaderBank.hh"

#include "WaveformAnalysis.hh"
#include "WaveformAnalysesAndTQs.hh"

// from AKat/waveform:
#include "KamPedestal.hh"
#include "KamSimpleWaveformTransform.hh"
#include "KamATWDSamplingFrequency.hh"
#include "KamPulseFinder.hh"

#include <algorithm>
#include <vector>

class TClonesArray;
class TKLTQ;
class TKLEventHeader;

const int kMaxPMTs = 2132;

class SFProcessor {

  public:
    SFProcessor();
    virtual ~SFProcessor();

    Bool_t CableNumberIsID(Int_t CableNumber){
      return (CableNumber <= kMaxIDCableNumber);
    }

    // uses pedestal events to set pedestal analyzer
    void SFProcessor::ProcessPedestalEvent(SFATWDBank *atwd,
      TKLEventHeader *ehead,
      TKLWaveformAnalysesAndTQs *analyses);
 
    void SFProcessor::ProcessPedestalEvent(SFATWDBank *atwd,
      TKLEventHeader *ehead,
      TKLVirtualPedestal *pedestalanalyzer0,
      TKLVirtualPedestal *pedestalanalyzer1 = 0,
      TKLVirtualPedestal *pedestalanalyzer2 = 0,
      TKLVirtualPedestal *pedestalanalyzer3 = 0,
      TKLVirtualPedestal *pedestalanalyzer4 = 0,
      TKLVirtualPedestal *pedestalanalyzer5 = 0,
      TKLVirtualPedestal *pedestalanalyzer6 = 0,
      TKLVirtualPedestal *pedestalanalyzer7 = 0,
      TKLVirtualPedestal *pedestalanalyzer8 = 0,
      TKLVirtualPedestal *pedestalanalyzer9 = 0,
      TKLVirtualPedestal *pedestalanalyzer10 = 0,
      TKLVirtualPedestal *pedestalanalyzer11 = 0,
      TKLVirtualPedestal *pedestalanalyzer12 = 0,
      TKLVirtualPedestal *pedestalanalyzer13 = 0,
      TKLVirtualPedestal *pedestalanalyzer14 = 0);

    // uses clock events to set clock analyzers
    void SFProcessor::ProcessClockEvent(SFATWDBank *atwd,
      TKLEventHeader *ehead,
      TKLWaveformAnalysesAndTQs *analyses);

    void SFProcessor::ProcessClockEvent(SFATWDBank *atwd,
      TKLEventHeader *ehead,
      TKLVirtualATWDSamplingFrequency *clockanalyzer0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer1 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer2 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer3 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer4 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer5 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer6 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer7 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer8 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer9 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer10 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer11 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer12 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer13 = 0,
      TKLVirtualATWDSamplingFrequency *clockanalyzer14 = 0);

    // process and output TQ for events using the pulsefinder, with the
    // TKLVirtualATWDSamplingFrequency and TKLVirtualPedestal used READ-ONLY to assign times
    // to the output, and the TKLVirtualSimpleWaveformTransform being applied in order
    // to the waveforms
    void ProcessEvent(SFATWDBank *atwd, TKLEventHeader *ehead,
      TKLWaveformAnalysesAndTQs *analyses);

    void ProcessEvent(SFATWDBank *atwd, TKLEventHeader *ehead,
      TClonesArray *arr0, TKLWaveformAnalysis *waveformanalysis0,
      TClonesArray *arr1 = 0, TKLWaveformAnalysis *waveformanalysis1 = 0,
      TClonesArray *arr2 = 0, TKLWaveformAnalysis *waveformanalysis2 = 0,
      TClonesArray *arr3 = 0, TKLWaveformAnalysis *waveformanalysis3 = 0,
      TClonesArray *arr4 = 0, TKLWaveformAnalysis *waveformanalysis4 = 0,
      TClonesArray *arr5 = 0, TKLWaveformAnalysis *waveformanalysis5 = 0,
      TClonesArray *arr6 = 0, TKLWaveformAnalysis *waveformanalysis6 = 0,
      TClonesArray *arr7 = 0, TKLWaveformAnalysis *waveformanalysis7 = 0,
      TClonesArray *arr8 = 0, TKLWaveformAnalysis *waveformanalysis8 = 0,
      TClonesArray *arr9 = 0, TKLWaveformAnalysis *waveformanalysis9 = 0,
      TClonesArray *arr10 = 0, TKLWaveformAnalysis *waveformanalysis10 = 0,
      TClonesArray *arr11 = 0, TKLWaveformAnalysis *waveformanalysis11 = 0,
      TClonesArray *arr12 = 0, TKLWaveformAnalysis *waveformanalysis12 = 0,
      TClonesArray *arr13 = 0, TKLWaveformAnalysis *waveformanalysis13 = 0,
      TClonesArray *arr14 = 0, TKLWaveformAnalysis *waveformanalysis14 = 0);

    void ProcessEvent(SFATWDBank *atwd, TKLEventHeader *ehead,
      TClonesArray *fArr,
      TKLVirtualPulseFinder* pulsefinder,
      TKLVirtualPedestal *pedestalanalyzer,
      TKLVirtualATWDSamplingFrequency *clockanalyzer,
      TKLVirtualSimpleWaveformTransform *transform1 = 0,
      TKLVirtualSimpleWaveformTransform *transform2 = 0,
      TKLVirtualSimpleWaveformTransform *transform3 = 0,
      TKLVirtualSimpleWaveformTransform *transform4 = 0,
      TKLVirtualSimpleWaveformTransform *transform5 = 0,
      TKLVirtualSimpleWaveformTransform *transform6 = 0,
      TKLVirtualSimpleWaveformTransform *transform7 = 0,
      TKLVirtualSimpleWaveformTransform *transform8 = 0,
      TKLVirtualSimpleWaveformTransform *transform9 = 0,
      TKLVirtualSimpleWaveformTransform *transform10 = 0,
      TKLVirtualSimpleWaveformTransform *transform11 = 0,
      TKLVirtualSimpleWaveformTransform *transform12 = 0);// pseudo variable
                                                  // argument list length

    static Int_t GetMaxWaveformAnalyses(){ return kMaxWaveformAnalyses; }
  protected:

    enum { kMaxWaveformAnalyses = 15,
           kMaxIDCableNumber = 1324};
    int CableNumber;
    int Gain;
    int AorB;
    int launchoffset;
    int lastevent;

    ClassDef(SFProcessor,1)                       // SFProcessor
};
#endif