//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Sample/Aggregate/RadialParacrystal.h
//! @brief     Defines class RadialParacrystal.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#ifndef BORNAGAIN_SAMPLE_AGGREGATE_RADIALPARACRYSTAL_H
#define BORNAGAIN_SAMPLE_AGGREGATE_RADIALPARACRYSTAL_H

#include "Sample/Aggregate/Ordered2D.h"
#include <heinz/Complex.h>
#include <memory>

class Profile1D;

//! Interference function of radial paracrystal.

class RadialParacrystal : public Ordered2D {
public:
    RadialParacrystal(const IParticle& particle, double peak_distance, double damping_length);
    ~RadialParacrystal();

    void setKappa(double kappa);
    void setDomainSize(double size);
    void setProbabilityDistribution(const Profile1D& pdf);

    std::string className() const final { return "RadialParacrystal"; }

#ifndef SWIG
    RadialParacrystal* clone() const override;
    void validate() const override;

    double kappa() const { return m_kappa; }
    double domainSize() const { return m_domain_size; }

    complex_t FTPDF(double qpar) const;

    double peakDistance() const { return m_peak_distance; }
    double dampingLength() const { return m_damping_length; }
    const Profile1D* pdf() const { return m_pdf.get(); }
    double randomSample(int seed) const;

    double areaNumberDensity() const override { return m_particle_density; }

    double scalarScattering(const DiffuseElement& ele) const override;
    double polarizedScattering(const DiffuseElement& ele) const override;

private:
    double iff_without_dw(const R3& q) const override;

    double m_peak_distance;  //!< the distance to the first neighbor peak
    double m_damping_length; //!< damping length of paracrystal
    //! Fourier transformed probability distribution of the nearest particle
    std::unique_ptr<Profile1D> m_pdf;
    double m_kappa;       //!< Size-spacing coupling parameter
    double m_domain_size; //!< Size of coherence domain

    double m_particle_density;

#endif // SWIG
};

#endif // BORNAGAIN_SAMPLE_AGGREGATE_RADIALPARACRYSTAL_H
