#ifndef UTSUSEMIFILTERTRIGNETDNA
#define UTSUSEMIFILTERTRIGNETDNA

#include "Header.hh"
//#include "UtsusemiFilterBase.hh"
#include "UtsusemiFilterTrignet.hh"
//#include "UtsusemiCaseInfoReaderTrignet.hh"
#include "UtsusemiChopCondInfoReaderTrignet.hh"
#include "UtsusemiTrignetDictionary.hh"
#include "UtsusemiTrignetEventDecoderBase.hh"
#include "UtsusemiFilterTrignetConditionDNA.hh"
#include "T0TreatToolsNeunet.hh"
#include "StringTools.hh"
#include <boost/filesystem.hpp>
#include <limits>
#ifdef MULTH
    #include <omp.h>
#endif

//////////////////////////////////
// UtsusemiFilterTrignetDNA
/////////////////////////////////

//!
/*!
 *
 */

class UtsusemiFilterTrignetDNA:
    public UtsusemiFilterTrignet,public UtsusemiFilterTrignetConditionDNA
{
protected:

    std::vector< std::vector< std::vector<UInt4>* >* >* _filterChopCaseTables; /**< Case Table <index><frame><values> */

    std::vector< std::vector<UInt8>* >* _filterChopPulseIdLists;          /**< List of PulseId <index><frame> */

    std::vector< std::vector<Double>* >* _filterChopInstClockLists;       /**< List of InstrumentClock <index><frame> [clock]  */

    void ClearChopCaseTables( UInt4 index, bool makeNew=false );

    void ClearChopPIDLists( UInt4 index, bool makeNew=false );

    void ClearChopICLists( UInt4 index, bool makeNew=false );

    void ClearMulthChopCaseTable(UInt4 index, UInt4 multh_num, bool makeNew);

    void ClearMulthChopPIDLists( UInt4 index, UInt4 multh_num, bool makeNew );

    void ClearMulthChopICLists( UInt4 index, UInt4 multh_num, bool makeNew );

    std::vector< std::vector< std::vector< std::vector<UInt4>* >* >* >* MulthChopCaseTable; /**< case table with MULTH <index><MULTH><frame><values>  */

    std::vector< std::vector< std::vector<UInt8>* >* >* MulthChopPulseIdLists;         /**< pulseId list with MULTH <index><MULTH><frame>  */

    std::vector< std::vector< std::vector<Double>* >* >* MulthChopInstClockLists;      /**< InstrumentClock list with MULTH <index><MULTH><frame> [clock] */
private:
    std::string MessageTag;

    UInt4 _eventSize;

    //void ReadTrigEvent( std::vector<std::string> trig_event_files, std::vector<std::string> trig_t0_files, UInt4 index );

    void ChopClear();

    void MergeCaseTable();

    void MergeCaseTableTest();

    void CaseExtractionFromCaseTable(std::vector<std::vector<UInt4> > &ChopperCaseTables1,std::vector<std::vector<UInt4> > &ChopperCaseTables2);

    UInt4 numOfChopCases;

    UInt4 fastChopperModeTag;

    std::vector<Double> _tofL2L3;
public:
    UtsusemiFilterTrignetDNA();

    ~UtsusemiFilterTrignetDNA();

    void SetTOFL2L3(std::vector <Double> pixelTOFL2L3);

    void ClearAllChopTables( UInt4 index, bool makeNew=false );

    void ClearAllMulthChopTables( UInt4 index, UInt4 multh_num, bool makeNew=false );

    Int4 LoadTrignetChopEventFile( UInt4 index, std::vector<std::string> evt_files, std::vector<std::string> t0b_files );

    void SetChopCondFile(std::string w_file, std::string d_file,std::string cc_file);

    void SetLambdaParam(Double lambdaCenter,Double deltaLambda);

    void SetTOFOffset(Double offset);

    void SetTOFResolver(Double offset);

    void SetTOFResolver(Double offset1,Double offset2);

    void SetTimeParamAtSource(Double tofSourceMin, Double tofSourceMax);

    //void SetInstrumentPosition(Double lchopper, Double lband, Double l1);

    UtsusemiChopCondInfoReaderTrignet* _UCRC;

    void ReadTrignetChopEvent( std::vector<std::string> trig_event_files, std::vector<std::string> trig_t0_files, UInt4 index );

    void ChopCondSorting( const UChar* data, UInt4 size, UInt4 index, UInt4 ThNum );

    void PreChopCondSorting( const UChar* data, std::vector<UInt4> T0Table, UInt4 index );

    void MakeChopCondTable();

    bool isChopCondInfoReady;

    bool isChopTrigTableReady;

    bool isFilterChopReady;  /**< true if all setting are finished */

    std::vector< std::vector<UInt4>* >* filterChopCaseTable; /**< Case Table for filter */

    std::vector<UInt8> filterChopPulseIdList;           /**< PulseId list for filter */

    std::vector<Double> filterChopInstClockList;

    Int4 ReadCaseEvent( UInt4 index, std::vector<std::string> evt_files, std::vector<std::string> t0b_files );

    void ReadTrigEvent( std::vector<std::string> trig_event_files, std::vector<std::string> trig_t0_files, UInt4 index );

    void MakeCaseTable();

    void DumpCaseTable(std::vector<std::vector<UInt4> > ChopperCaseTables1, std::vector<std::vector<Double> > ChopperCaseTables2);

    void DumpCaseTable(std::vector<std::vector<Double> > ChopperCaseTables1,std::string tag);

    void DumpCaseTable(std::vector<Double> ChopperCaseTables1,std::string tag);

    void DumpCaseTable(std::vector<Double> ChopperCaseTables1,std::string tag,Double offset);

    void DumpCaseTable(std::vector<std::vector<UInt4> > ChopperCaseTables1,std::string tag);

    void DumpCaseTable(std::vector< std::vector<UInt4>* >* ChopperCaseTables1,std::string tag);

    UInt4 GetCaseFromTof( const UInt4 pixelId, Double* tof, std::vector<UInt4>* caseVec );

};
#endif
