#include <cmath>
#include <algorithm>
#include <vector>
#include <RAT/TriggerPulse.hh>
#include <RAT/Log.hh>

namespace RAT {


TriggerPulse::TriggerPulse()
{
    fStartTime = 0.0;
    fPulseHeight = 1.0;
    fPulseWidth = 100.0;
}

TriggerPulse::~TriggerPulse()
{
}

double GenericTrigPulse::GetPulseHeight(double time)
{
    double height;
    if (time-fStartTime < fPulseWidth){
        height = fPulseHeight;
    }
    else {
        height = 0;
    }
    return height;
}

double SquareTrigPulse::GetPulseHeight(double time)
{
    double height;
    if (time-fStartTime < fPulseWidth){
        height = fPulseHeight;
    }
    else {
        height = 0;
    }
    return height;
}

double NHITTrigPulse::GetPulseHeight(const double time)
{
    double height = 0.0;
    const double delta_t = (time-fStartTime);
    if( delta_t <= fPulseWidth && delta_t >= 0.0 )
    {
        height = fPulseHeight;
        if( fRisetime!=0 )
        {
            const double expon = -delta_t / fRisetime;
            if( expon >= -86.2 ) //constant to get away from underflow
                height *= 1.0 - exp( expon );
        }
    }
    else if( delta_t > fPulseWidth && delta_t <= (fPulseWidth+5.0*fRisetime) && fRisetime!=0)
    {
        height = fPulseHeight;
        const double expon = ( fPulseWidth - delta_t ) / fRisetime;
        if( expon >= -86.2 ) //constant to get away from underflow
            height *= exp(expon);
        else
            height = 0.0;
    }
    else
        height = 0.0;

    return height;
}

double EsumTrigPulse::GetPulseHeight(const double time)
{
    const double delta_t = (time-fStartTime)-fEsumDelay;
    if( fabs( delta_t ) < 5.0 * fPulseWidth )
    {
        return fPulseHeight * exp( (-delta_t*delta_t) / (2*(fPulseWidth*fPulseWidth)) );
    }
    else
        return 0;
}

void EsumTrigPulse::SetPulseHeight(double charge)
{
    fPulseHeight = fmVperPE*(charge/fADCperPE);
}


} // namespace RAT