#include "EmakiReadout1dEventDecoder.hh"
//////////////////////////////////////////////////////////
EmakiReadout1dEventDecoder::
//EmakiReadout1dEventDecoder():
//UtsusemiReadoutEventDecoderTemplate()
EmakiReadout1dEventDecoder()
{
    Initialize();
}
//////////////////////////////////////////////////////////
EmakiReadout1dEventDecoder::
~EmakiReadout1dEventDecoder(){
    Clear();
}
//////////////////////////////////////////////////////////
void EmakiReadout1dEventDecoder::
Initialize(){
    //UtsusemiReadoutEventDecoderTemplate::Initialize();
    UtsusemiReadoutEventDecoderTemplate<WiringInfoEditorReadout,EmakiDetectorInfoEditorReadout>::Initialize();

    _EventSize = (UInt4)8;
    _HeaderT0Event      = (UChar)0xb7;
    _HeaderClockEvent   = (UChar)0xb9;
    _HeaderNeutronEvent = (UChar)0xb5;

    _MessageTag="EmakiReadout1dEventDecoder >> ";
    _isRequiredPosiInfo=false;
}

//////////////////////////////////////////////////////////
UInt4 EmakiReadout1dEventDecoder::
DecodeEventData( UInt4 daqId, UInt4 moduleNo, const UChar *data, UInt4 *pixel_id, double *tof, std::vector<Double>* Clock, UInt4 ThNum ){

    UInt4 ret = 0;

    // if given event is neutron event;
    if (*data == _HeaderNeutronEvent){
        if (_prevT0Event[_EventSize*ThNum+0]!=0x00){
            // decode neutron event
            *tof = (Double)( (UInt4)( *(data+1) ) +
                ((UInt4)( *(data+2) ) << 8) +
                ((UInt4)( *(data+3) ) << 16) );// [micro-sec]

            //[inamura 180329]-->
            // frame treatment : minus clock means this frame must be ignored.
            /*
            if ( (_wirInfo->FrameBoundaryInfo.first)>1 ){
                if ( *tof < (_wirInfo->FrameBoundaryInfo.second) ){
                    if (Clock->at( _wirInfo->FrameBoundaryInfo.first -1 )<0) return ret;
                    *tof += Clock->at( _wirInfo->FrameBoundaryInfo.first -1 );
                }else{
                    if (Clock->at( _wirInfo->FrameBoundaryInfo.first -2 )<0) return ret;
                    *tof += Clock->at( _wirInfo->FrameBoundaryInfo.first -2 );
                }
            }
            */
            if (_isSetFrameBoundary){
                UInt4 fno = _wirDict->FrameBoundaryInfoList[(*pixel_id)]->first;
                Double boundary = _wirDict->FrameBoundaryInfoList[(*pixel_id)]->second;
                // if no clocks for TOF shifting, return -1 to ignore this frame.
                if ( *tof < boundary){
                    if (Clock->at( fno -1 )<0) return -1;
                    *tof += Clock->at( fno -1 );
                }else{
                    if (Clock->at( fno -2 )<0) return -1;
                    *tof += Clock->at( fno -2 );
                }
            }
            //<--[inamura 180329]


            std::vector<Int4> *pixel_info = NULL;
            try{
                pixel_info = _wirInfo->PixelInfoStore->at(0)->at(0)->at(0);
            }catch(...){
                return ret;
            }
            *pixel_id =  (UInt4)( *(data+5) ) * (pixel_info->at(3)) + (UInt4)( *(data+6) );
            if ((*pixel_id)<=_wirInfo->MaxPixelId) ret = _isNeutronEvent;
        }
    }else if (*data == _HeaderT0Event){
        for (UInt4 i=0;i<_EventSize;i++) (*(_prevT0Event+(_EventSize*ThNum)+i))=(*(data+i));
        ret = _isT0Event;
    }else if (*data == _HeaderClockEvent){
        ret = _isClockEvent;
    }
    return ret;

}
