//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Resample/Option/SimulationOptions.h
//! @brief     Defines class SimulationOptions.
//!
//! @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_RESAMPLE_OPTION_SIMULATIONOPTIONS_H
#define BORNAGAIN_RESAMPLE_OPTION_SIMULATIONOPTIONS_H

#include <cstddef>

using std::size_t;

//! Options to compute mesocrystal formfactors.

struct MesoOptions {
    bool use_reciprocal_sum{false}; //!< If true, use approximative but faster algorithm
    double radius_factor{2.1};      //!< Cutoff for fast (reciprocal-sum) algorithm
};

//! Collect the different options for simulation.
//! @ref SimulationOptions

class SimulationOptions {
public:
    SimulationOptions();

    //! Enables/disables MonteCarlo integration
    //! @param flag If true, MonteCarlo integration will be used, otherwise analytical calculations
    //! @param mc_points Number of points for MonteCarlo integrator
    void setMonteCarloIntegration(bool flag = true, size_t mc_points = 50);

    //! Sets number of threads to use during the simulation (0 - take default value from hardware)
    void setNumberOfThreads(int nthreads);

    //! Sets number of batches to split
    void setNumberOfBatches(int nbatches); // TODO: undocumented, probably useless

    void setIncludeSpecular(bool include_specular) { m_include_specular = include_specular; }

    void setUseAvgMaterials(bool use_avg_materials) { m_use_avg_materials = use_avg_materials; }

    void setMesoOptions(bool use_rec_sum, double rad_factor);

#ifndef SWIG

    bool isIntegrate() const;
    size_t getMcPoints() const
    {
        return m_mc_points;
    }
    unsigned getNumberOfThreads() const;
    unsigned getNumberOfBatches() const;
    unsigned getCurrentBatch() const;
    unsigned getHardwareConcurrency() const;
    bool includeSpecular() const
    {
        return m_include_specular;
    }
    bool useAvgMaterials() const
    {
        return m_use_avg_materials;
    }
    MesoOptions mesoOptions() const
    {
        return m_meso_options;
    }

private:
    bool m_mc_integration;
    bool m_include_specular;
    bool m_use_avg_materials;
    MesoOptions m_meso_options;
    size_t m_mc_points;
    unsigned m_n_threads{0};
    unsigned m_n_batches{1};
    unsigned m_current_batch{0};
#endif // SWIG
};

#endif // BORNAGAIN_RESAMPLE_OPTION_SIMULATIONOPTIONS_H
