#ifndef SPECULARMULTI_H
#define SPECULARMULTI_H

#include "Header.hh"
#include "AdvFuncBase.hh"

//#include "AdvParamSet.hh"
//#include "ElementContainer.hh"

class AdvModelSpecular;

/**
 *  specular reflection for MultiDataFitting
 */
class AdvModelSpecularMul : public AdvFuncBase {

    public:
      enum mode {
        UnPol2UnPol,
        UpPol2UpPol,
        UpPol2DownPol,
        UpPol2UnPol,
        DownPol2DownPol,
        DownPol2UpPol,
        DownPol2UnPol,
      };


        /** default constructor */
        AdvModelSpecularMul(AdvModelSpecular* m, enum mode i);
        /** destructor */
        ~AdvModelSpecularMul() {}


#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 derivative function */
        Double der1st(const Double x, const Double *p) ;
        /** evaluate the value of the 2nd derivative function */
        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 vector<Double> &p);
#ifdef HAVE_DIFFERENTIAL_MEMBER
        /** evaluate the value of the 1st derivative function */
        Double der1st(const Double x, const vector<Double> &p);
        /** evaluate the value of the 2nd derivative function */
        Double der2nd(const Double x, const vector<Double> &p);
        /** evaluate the gradient of the function for parameters */
        vector<Double> gradient(const Double x, const vector<Double> &p);
#endif //HAVE_DIFFERENTIAL_MEMBER
#endif //USE_VECTOR

    private:

        AdvModelSpecular*  model;
        vector<Double> p_save;
        vector<Double> x_save;
        vector< vector<Double> > r_save;

        enum mode  imode;

};

#endif
