//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Sim/Scan/PhysicalScan.h
//! @brief     Declares interface PhysicalScan.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2023
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#ifndef BORNAGAIN_SIM_SCAN_PHYSICALSCAN_H
#define BORNAGAIN_SIM_SCAN_PHYSICALSCAN_H

#include "Sim/Scan/BeamScan.h"
#include <memory>

class IDistribution1D;
struct ParameterSample;

//! Abstract base class for alpha and lambda scans.

class PhysicalScan : public BeamScan {
public:
    PhysicalScan(Scale* axis);
    ~PhysicalScan() override;

    PhysicalScan* clone() const override = 0;
    std::vector<const INode*> nodeChildren() const override;

    void setWavelength(double lambda);
    void setWavelengthAt(size_t i, double lambda);
    //! Distribution with absolute width, **complementing** wavelength values
    void setWavelengthDistribution(const IDistribution1D& distr);

    void setInclination(double alpha);
    void setInclinationAt(size_t i, double alpha);
    //! Distribution with absolute width, **complementing** inclination values
    void setAngleDistribution(const IDistribution1D& distr);

#ifndef SWIG
    double wavelength() const;
    double wavelengthAt(size_t i) const;

    double inclinationAt(size_t i) const;

    // needed for export
    const IDistribution1D* wavelengthDistribution() const
    {
        return m_lambda_distrib.get();
    }
    const IDistribution1D* alphaDistribution() const
    {
        return m_alpha_distrib.get();
    }
    size_t nDistributionSamples() const override;

protected:
    void copyPhysicalScan(PhysicalScan* dest) const;

    std::unique_ptr<IDistribution1D> m_lambda_distrib;
    std::unique_ptr<IDistribution1D> m_alpha_distrib;

private:
    bool isCommonWavelength() const;

#endif // SWIG
};

#endif // BORNAGAIN_SIM_SCAN_PHYSICALSCAN_H
