//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/View/View/SimulationView.h
//! @brief     Defines class SimulationView.
//!
//! @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_GUI_VIEW_VIEW_SIMULATIONVIEW_H
#define BORNAGAIN_GUI_VIEW_VIEW_SIMULATIONVIEW_H

#include <QCheckBox>
#include <QComboBox>
#include <QLabel>
#include <QPushButton>
#include <QRadioButton>
#include <QSpinBox>

class DatafileItem;
class InstrumentItem;
class SampleItem;
class SimulationOptionsItem;

//! Widget to define a simulation.
//! Contains:
//! * Elements to select instrument, sample and real data.
//! * Elements to set options like number of threads.
//! * Buttons to run simulation or to export as a Python script
class SimulationView : public QWidget {
    Q_OBJECT
public:
    SimulationView();

    void simulate();

private:
    void exportPythonScript();

    void showEvent(QShowEvent*) override;
    void hideEvent(QHideEvent*) override;

    //! Read the entries in the UI and modify document.
    void updateStateFromUI();

    //! Read the entries in the UI and store in OptionsItem.
    void readOptionsFromUI();

    //! Write entries in OptionsItem to UI
    void writeOptionsToUI();

    //! Update enabling of elements depending on other elements.
    void updateEnabling();

    //! Updates selection combo with string list while preserving previous selection.
    //! If allowNone == true, additional "None" item will be added to the combo.
    void updateSelection(QComboBox* comboBox, QStringList itemList, int currentIndex,
                         bool allowNone = false);

    //! Checks whether selection is correct for running a simulation.
    //! Returns empty string if valid, otherwise the error text.
    QString validateSimulationSetup(bool validateRealData) const;

    QLabel* m_instrument_label;

    QRadioButton* m_analytical_radio;
    QRadioButton* m_monte_carlo_radio;
    QSpinBox* m_number_of_monte_carlo_points;

    QRadioButton* m_real_sum;
    QRadioButton* m_fourier_sum;
    QDoubleSpinBox* m_meso_radius_factor;

    QRadioButton* m_ambient_layer_radio;
    QRadioButton* m_average_layer_radio;

    QCheckBox* m_include_specular_check;

    QRadioButton* m_run_policy_immediately_radio;
    QRadioButton* m_run_policy_background_radio;
    QComboBox* m_number_of_threads_combo;

    QPushButton* m_simulate_button;
    QPushButton* m_export_to_py_script_button;

    // Convenience method for easier access
    SimulationOptionsItem* optionsItem() const;
};

#endif // BORNAGAIN_GUI_VIEW_VIEW_SIMULATIONVIEW_H
