#ifndef MULTISCATTERING
#define MULTISCATTERING

#include <vector>
//#include <string.h>

#include "Header.hh"

//#include "AdvScatAbsoBodyManagerDNA.hh"
#include "AdvScatAbsoBodyManagerMLF.hh"

//should be modified comment stated below
/**
 * ScatAbsoTestSample Class calculates absorption factor and desired value of the scattering
 * from the sample corrected for absorption, based on the following paper.
 *  H.H. Paalman and C.J. Pings :: J. Appl. Phys. 33, 2635 (1962).
 *
 * @author  skoike@advancesoft
 * @vertion 0.0
 * @sice    0.0
*/
//class AdvMultiScatteringDNA : public AdvScatAbsoBodyManagerDNA {
class AdvMultiScatteringDNA : public AdvScatAbsoBodyManagerMLF {
  private:

    UInt4 m; /**< m-th order Legendre polynomial */
    std::vector <Double>  xk; /**< k-th zero point of Pm(x) */
    std::vector <Double>  Hk; /**< weighted factor in Gauss-Legendre fomula */

    std::string filename; /**< filename of data for cell and sample */
    std::string filepath; /**< filename of data for cell and sample */

    struct ScatAbsoInfo sampleInfo; /**< data for sample */
    struct ScatAbsoInfo wallInfo; /**< data for cell */
//    struct coordinate scaPos; /** neutron scattering position */

//    Double sigmaCEi; /** total cross section of cell for incident neutron */
//    Double sigmaCEo; /** total cross section of cell for reflected neutron */
//    Double sigmaSEi; /** total cross section of sample for incident neutron */
//    Double sigmaSEo; /** total cross section of sample for reflected neutron */
    Double sigmaAbs;
    Double sigmaSca;
    Double sigmaTot;

    Double theta; /** reflected angle */
//    Double phi; /** reflected angle */
    Double incEnergy; /** incident neutron energy */
    Double outEnergy; /** reflected neutron energy */

    std::string shape;
    Double width;
    Double height;
    Double radius;
    Double radiusSmall; /** smaller radius of cylinder */
    Double radiusLarge; /** larger radius of cylinder */
//    Double volume; /** volume of cylinder */
//    UInt4 species; /** species of each absorption factor */

    Double epsilon; /** threshold value used for judgement of convergence of numerical integral */
    Double epsilonRatio; /** threshold value used for judgement of convergence of numerical integral */
    Double threZero; /** supplementary threshold value used for judgement of convergence of numerical integral */

    Double s1tilde;
    Double s2tilde;
    Double delta;
    Double bfunc;

    /**
     * return 3D integrated value
     *
     * @return value of 3D numerical integral
     */

    Double funcU(Double);
    Double funcE(Double);
    Double GetDelta(std::string, Double);
    Double funcEin(Double);
    Double funcI(Double, Double);
    Double funcI1(Double, Double, Double);
    Double funcI2(Double, Double, Double, Double, Double);
    Double funcJ(Double, Double);


  public:
    AdvMultiScatteringDNA(void);
    AdvMultiScatteringDNA(std::string);
    ~AdvMultiScatteringDNA(void);

    /**
     * return threshold value used for judgement of convergence in numerial integral
     *
     * @return epsilon
     */
    Double GetIntegThresholdValue(void) {return epsilon;};

    /**
     * return threshold value of ratio used for judgement of convergence in numerial integral
     *
     * @return epsilonRatio
     */
    Double GetIntegThresholdRatio(void) {return epsilonRatio;};

    /**
     * set threshold value used for judgement of convergence in numerial integral
     *
     * @set epsilon
     */
    void SetIntegThresholdValue(Double a) {epsilon=a;};

    /**
     * set threshold value Ratio used for judgement of convergence in numerial integral
     *
     * @set epsilonRatio
     */
    void SetIntegThresholdRatio(Double a) {epsilonRatio=a;};

    /**
     * calculate coefficient factor A_C_C
     * A_C_C is coefficent factor of sell scattered at cell.
     *
     * @return ACC
     */
    //Double GetACC(Double, Double, Double, Double);

    /**
     * calculate coefficient factor A_CS_S
     * A_CS_S is coefficent factor of sell+sample scattered at sample.
     *
     * @return ACSS
     */
    //Double GetACSS(Double, Double, Double, Double);

    /**
     * calculate coefficient factor A_CS_C
     * A_CS_C is coefficent factor of sell+sample scattered at sample.
     *
     * @return ACSS
     */
    //Double GetACSC(Double, Double, Double, Double);

    /**
     * calculate coefficient factor A_S_S
     * A_S_S is coefficent factor of sample scattered at sample.
     * only use in the case of column shape
     *
     * @return ASS
     */
    //Double GetASS(Double, Double, Double, Double);

    Double GetEffectMultiScatSlab(Double, Double, Double);
    Double GetEffectMultiScatSlab(Double, Double);
    Double GetEffectMultiScatColumn(Double, Double, Double);
    Double GetEffectMultiScatCylinder(Double, Double, Double, Double);

    Double GetDeltaForSlab(Double, Double, Double);
    Double GetDeltaForSlab(Double, Double);
    Double GetLargeDeltaForSlab(Double);

    Double GetDeltaForColumn(Double, Double, Double);
    Double GetLargeDeltaForColumn(Double);

    Double GetDeltaForCylinder(Double, Double, Double, Double);
    Double GetLargeDeltaForCylinder(Double);



    Double GetFracSingle(Double, Double);
    Double GetFracDouble(Double, Double);
    Double GetFracOverTriple(Double, Double);




/*
    Double GetEffectMultiScatSlab(Double, Double, Double[]);
    Double GetEffectMultiScatColumn(Double, Double, Double, Double[]);
    Double GetEffectMultiScatCylinder(Double, Double, Double, Double, Double[]);
*/


};

#endif


