#ifndef TRANSMITTANCECORRECTION
#define TRANSMITTANCECORRECTION

#include "ManipulatorBase.hh"
#include "ElementContainerMatrix.hh"
#include "UtsusemiHeader.hh"

////////////////////////////////////////
// Transmittance correction for SAS
////////////////////////////////////////

//! Function to correct a transmittance
/*!
 *  This function corrects ECM by a transmittance.
 *
 */
class TransmittanceCorrection:
public ManipulatorBase<ElementContainerMatrix>{
private:
    std::string funcType;
    std::vector<Double> params, errors;
    ElementContainer ec_tr;
    bool calcErrorPropagation;
    bool useAngleDependence;
protected:
    const std::string MessageTag;
    virtual bool _Execute();
    virtual bool _ExecutePolyApproximation();

public:
    TransmittanceCorrection();
        //!< Constructor
        /*!<
         */
    TransmittanceCorrection(ElementContainerMatrix* ecm);
        //!< Constructor
        /*!<
         *  @param ecm ElementContainerMatrix for the target
         */
    virtual void SetParameters(std::vector<Double> params, std::vector<Double> errors, std::string funcType, bool _useAngDep=false);
        //!< Corrects ECM by an exponential function
        /*!<
         *  @param params parameters of a transmittance function
         *  @param errors errors of parameters
         *  @param funcType parameter a
         */
    virtual void SetErrorPropagation(bool errProp=false){this->calcErrorPropagation = errProp;};
        //!< Sets a flag to calculate error propagation
        /*!<
         *  @param errProp flag to calculate error propagation
         */
    virtual bool Execute();
        //!< Corrects ECM by an exponential function
        /*!<
         *  @param useAngleDependence (bool)
         */
    virtual void Exponential(Double lamb, Double *factor, Double *error);
        //!< Calculate factor and error for an exponential function
        /*!<
         *
         */
    virtual void Polynomial3(Double lamb, Double *factor, Double *error);
        //!< Calculate factor and error for a degree 3 polynomial function
        /*!<
         *
         */
    virtual void PolynominalApproximation(Double lamb, Double *factor, Double *error, Double thick);
        //!< Calculate factor and error using a Polynominal Approximation method
        /*!<
         *
         */
    static const std::string TRANSMIT_TYPE_EXP;
    static const std::string TRANSMIT_TYPE_POLY3;
    static const std::string TRANSMIT_TYPE_POLYAPPROX;
    bool DumpFactorIntoContainer(ElementContainerMatrix *ecm);
        //!< Dump factor and error calculated by a Polynominal Approximation method with angle dependency into ElementContainerMatrix as the intensity and error
        /*!<
         *
         */
};
#endif
