//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/View/Toplevel/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_TOPLEVEL_SIMULATIONVIEW_H
#define BORNAGAIN_GUI_VIEW_TOPLEVEL_SIMULATIONVIEW_H

#include <QComboBox>

class MainWindow;
class SampleItem;
class InstrumentItem;
class RealItem;
class SimulationOptionsItem;
class ProjectDocument;

namespace Ui {

class SimulationView;
}

//! 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(QWidget* parent, ProjectDocument* document);

    void simulate();
    void exportPythonScript();

private:
    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();

    //! Returns selected sample taking into account that there might be several
    //! samples with the same name.
    const SampleItem* selectedSampleItem() const;

    //! Returns selected InstrumentItem taking into account that there might be several
    //! instruments with the same name.
    const InstrumentItem* selectedInstrumentItem() const;

    //! Returns selected real data item taking into account that there might be several
    //! items with the same name.
    const RealItem* selectedRealItem() const;

    //! 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;

    //! Show/hide UI elements according to settings in current project
    void updateFunctionalityNarrowing();

private:
    Ui::SimulationView* m_ui;
    ProjectDocument* m_document;

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

#endif // BORNAGAIN_GUI_VIEW_TOPLEVEL_SIMULATIONVIEW_H
