//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/Model/Project/ProjectDocument.h
//! @brief     Defines class ProjectDocument.
//!
//! @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_MODEL_PROJECT_PROJECTDOCUMENT_H
#define BORNAGAIN_GUI_MODEL_PROJECT_PROJECTDOCUMENT_H

#include "Wrap/WinDllMacros.h"
#include <QObject>

class DatafilesSet;
class InstrumentsSet;
class JobsSet;
class QIODevice;
class SamplesSet;
class SimulationOptionsItem;

//! Project document class handles all data related to the opened project
//! (sample, job, project specific settings).
//!
//! It also provides signaling regarding changes in the current document data.
//!
//! e.g. if project file is /home/users/development/Untitled/Untitled.ba
//! projectName()     - 'Untitled'
//! projectDir()      - '/home/users/development/Untitled
//! projectFileName() - '/home/users/development/Untitled/Untitled.ba'
class ProjectDocument : public QObject {
    Q_OBJECT
public:
    ProjectDocument();
    ~ProjectDocument();

    void clear();

    void setProjectDir(const QString& text);
    void setProjectName(const QString& text);
    void setProjectFullPath(const QString& fullPath);
    void saveProjectFileWithData(const QString& projectPullPath);
    void loadProjectFileWithData(const QString& projectPullPath);

    void setModified();

    QString projectDir() const { return m_project_dir; }
    QString projectName() const { return m_project_name; }

    QString validProjectDir() const;
    QString projectFullPath() const;
    bool hasValidNameAndPath() const;

    bool isModified() const { return m_modified; }

    const InstrumentsSet* instruments() const { return m_instruments.get(); };
    const SamplesSet* samples() const { return m_samples.get(); };
    const DatafilesSet* datafiles() const { return m_datafiles.get(); };
    const SimulationOptionsItem* simulationOptionsItem() const { return m_options.get(); };
    const JobsSet* jobs() const { return m_jobs.get(); };

    InstrumentsSet* instrumentsRW() { return m_instruments.get(); };
    SamplesSet* samplesRW() { return m_samples.get(); };
    DatafilesSet* datafilesRW() { return m_datafiles.get(); };
    SimulationOptionsItem* simulationOptionsRW() { return m_options.get(); };
    JobsSet* jobsRW() { return m_jobs.get(); };

signals:
    void modifiedStateChanged();

private:
    void clearModified();

    void writeProject(QIODevice* device);
    void readProject(QIODevice* device);

    QString m_project_dir;
    QString m_project_name;
    bool m_modified;
    std::unique_ptr<InstrumentsSet> m_instruments;
    std::unique_ptr<SamplesSet> m_samples;
    std::unique_ptr<DatafilesSet> m_datafiles;
    std::unique_ptr<SimulationOptionsItem> m_options;
    std::unique_ptr<JobsSet> m_jobs;
};

BA_GUI_API_ extern std::unique_ptr<ProjectDocument> gDoc;

#endif // BORNAGAIN_GUI_MODEL_PROJECT_PROJECTDOCUMENT_H
