#ifndef LAYER_HH
#define LAYER_HH

#include "AdvModel.hh"
#include <gsl/gsl_complex.h>
#include <gsl/gsl_matrix_complex_double.h>

class AdvModel;
class AdvModelParam;

/**
    AdvModelLayer
      単一の層を表現するクラス
*/
class AdvModelLayer {

public:
    AdvModelLayer(AdvModel* mdl);
    ~AdvModelLayer();

    //  厚み
    void SetWidth(Double v); //! 層の厚みを設定する (単位：Å)
    Double GetWidth();       //! 層の厚みを取得する (単位：Å)

    //  原子散乱長密度
    void SetSLDreal(Double v);  //! 散乱長密度(SLD)の実部を設定する (単位：Å^(-2))
    void SetSLDimag(Double v);  //! 散乱長密度(SLD)の虚部を設定する (単位：Å^(-2))
    Double GetSLDreal();        //! 散乱長密度(SLD)の実部を取得する (単位：Å^(-2))
    Double GetSLDimag();        //! 散乱長密度(SLD)の虚部を取得する (単位：Å^(-2))
    Complex GetSLD();           //! 散乱長密度(SLD)を複素数として取得する (単位：Å^(-2))

    //  磁気散乱長密度
    void SetSLD_mag_real(Double v); //! 磁気散乱長密度(SLD)の実部を設定する (単位：Å^(-2))
    void SetSLD_mag_imag(Double v); //! 磁気散乱長密度(SLD)の虚部を設定する (単位：Å^(-2))
    Double GetSLD_mag_real();       //! 磁気散乱長密度(SLD)の実部を取得する (単位：Å^(-2))
    Double GetSLD_mag_imag();       //! 磁気散乱長密度(SLD)の虚部を取得する (単位：Å^(-2))
    Complex GetSLD_mag();           //! 磁気散乱長密度(SLD)を複素数として取得する (単位：Å^(-2))

    //  角度
    void SetAngle(Double v);  //!  磁気モーメントと量子化軸の角度を設定する (単位：°)
    Double GetAngle();        //!  磁気モーメントと量子化軸の角度を取得する (単位：°)

    void GetWavenumber(Double kz, Complex& kplus, Complex& kminus);  //!  層内の波数を計算する
    void GetMatrix(Double kz, gsl_matrix_complex *mat);  //!  反射率計算のための行列を計算する

    AdvModelParam* GetParamWidth() { return m_width; }
    AdvModelParam* GetParamSLDr()  { return m_SLD_real; }
    AdvModelParam* GetParamSLDi()  { return m_SLD_imag; }
    AdvModelParam* GetParamSLDMr() { return m_SLD_mag_real; }
    AdvModelParam* GetParamSLDMi() { return m_SLD_mag_imag; }
    AdvModelParam* GetParamAngle() { return m_angle; }

private:
    AdvModel* m_mdl;
    AdvModelParam* m_width;        //! 層の厚み (単位：Å)
    AdvModelParam* m_SLD_real;     //! 散乱長密度(SLD)の実部 (単位：Å^(-2))
    AdvModelParam* m_SLD_imag;     //! 散乱長密度(SLD)の虚部 (単位：Å^(-2))
    AdvModelParam* m_SLD_mag_real; //! 磁気散乱長密度(SLD)の実部 (単位：Å^(-2))
    AdvModelParam* m_SLD_mag_imag; //! 磁気散乱長密度(SLD)の虚部 (単位：Å^(-2))
    AdvModelParam* m_angle;        //! 磁気モーメントと量子化軸の角度 (単位：度 (°))

    gsl_complex Complex2gsl(Complex c);
};

#endif
