#ifndef DELTACONV_H
#define DELTACONV_H 1

#include "AdvFuncConv.hh"


#include "AdvFuncBase.hh"
#include "Header.hh"
#include "OperatorBase.hh"
#include "ElementContainer.hh"
#include "ElementContainerArray.hh"
#include "ElementContainerMatrix.hh"
#include "HeaderBase.hh"
#include "StringTools.hh"



#define NumberOfParamForDeltaConv 2U

/**
 *  Delta function
 */
class AdvDeltaConv : public AdvFuncBase, public AdvFuncConv{

    private:

        UInt4 counter;
#ifdef USE_POINTER
        Double DeltaFunc(const Double x, const Double *p);
        Double AdvDeltaConvFunc(const Double x, const Double *p);
#endif // USE_POINTER
#ifdef USE_VECTOR
        Double DeltaFunc(const Double x, const std::vector<Double> &p);
        Double AdvDeltaConvFunc(const Double x, const std::vector<Double> &p);
#endif // USE_VECTOR


#ifdef USE_SETTER_GETTER
    private:
        /** height at peak */
        Double h;
        /** center of the peak */
        Double c;
        /** half width at half maximum */
        Double w;
#endif
    public:
        /** default constructor */
        AdvDeltaConv() ;
        /** copy constructor */
        AdvDeltaConv(const AdvDeltaConv &obj);

        /** destructor */
        ~AdvDeltaConv() ;


#ifdef HAVE_DIFFERENTIAL_MEMBER
        /** evaluate the value of the 1st. differential coefficient */
        Double der1st(const Double x, const Double h, const Double c, const Double w);
        /** evaluate the value of the 2nd. differential coefficient */
        Double der2nd(const Double x, const Double h, const Double c, const Double w);
        /** evaluate the value of differential coefficient for w*/
        Double derW(const Double x, const Double h, const Double c, const Double w);
#endif

#ifdef USE_POINTER
        /** evaluate the value of the function */
        Double eval(const Double x, const Double *p);
#ifdef HAVE_DIFFERENTIAL_MEMBER
        /** evaluate the value of the 1st. differential coefficient */
        Double der1st(const Double x, const Double *p);
        /** evaluate the value of the 2nd. differential coefficient */
        Double der2nd(const Double x, const Double *p);
        /** evaluate the gradient of the function for parameters */
        Double *gradient(const Double x, const Double *p);
#endif // HAVE_DIFFERENTIAL_MEMBER
#endif // USE_POINTER


#ifdef USE_VECTOR
        /** evaluate the value of the function */
        Double eval(const Double x, const std::vector<Double> &p);
#ifdef HAVE_DIFFERENTIAL_MEMBER
        /** evaluate the value of the 1st derivative function */
        Double der1st(const Double x, const std::vector<Double> &p);
        /** evaluate the value of the 2nd derivative function */
        Double der2nd(const Double x, const std::vector<Double> &p);
        /** evaluate the gradient of the function for parameters */
        std::vector<Double> gradient(const Double x, const std::vector<Double> &p);
#endif // HAVE_DIFFERENTIAL_MEMBER
#endif // USE_VECTOR
};

#ifdef USE_SETTER_GETTER
        void    setParam(const Double h, const Double c, const Double w);
        Double  eval(const Double x);
        Double  der1st(const Double x);
        Double  der2nd(const Double x);

#endif // USE_SETTER_GETTER

#endif // DeltaCONV_H
