//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Sample/Aggregate/Ordered2D.h
//! @brief     Defines and implements the interface class Ordered2D.
//!
//! @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_ORDERED2D_H
#define BORNAGAIN_SAMPLE_AGGREGATE_ORDERED2D_H

#include "Sample/Aggregate/Struct2D.h"
#include <heinz/Vectors3D.h>

//! Abstract base class of interference functions.
class Ordered2D : public Struct2D {
protected:
    Ordered2D(const IParticle& particle);

public:
    ~Ordered2D() override;

#ifndef SWIG
    Ordered2D* clone() const override = 0;

    std::string className() const override { return "Ordered2D"; }

    //! StructureFactors the Debye-Waller factor for a given wavevector transfer.
    //! Can be < 1 here only with out-of-plane particle position variance.
    virtual double DWfactor(R3) const { return 1.; }

    //! The structure factor for a given wavevector transfer (overrides Struct2D)
    double structureFactor(const R3& q) const override;

    //! The interference function for a given wavevector transfer with outer interference
    virtual double structureFactorWithOuter(const R3& q, double outer_iff = 1.0) const;

protected:
    void instructClone(Ordered2D* dest) const;

    //! Indicates if this interference function can be used with a sample (DWBA mode)
    virtual bool supportsMultilayer() const { return true; }

    //! Calculates the structure factor in the absence of extra inner structure
    double iff_no_inner(const R3& q, double outer_iff) const;

    //! Calculates the structure factor without Debye-Waller factor
    virtual double iff_without_dw(const R3& q) const = 0;

#endif // SWIG
};

#endif // BORNAGAIN_SAMPLE_AGGREGATE_ORDERED2D_H
