#pragma once

#include <filesystem>
#include <wx/dataview.h>
#include <wx/wx.h>

namespace gui
{
//--------------------------------------------------------------
struct RequirementData
{
  std::string uuid;
  std::string id;
  std::string title;

  RequirementData                              *parent;
  std::vector<std::unique_ptr<RequirementData>> children;

  RequirementData(std::string uuid_, std::string id_, std::string title_)
    : uuid(std::move(uuid_))
    , id(std::move(id_))
    , title(std::move(title_))
  {
  }

  // Adds a child requirement
  RequirementData *AddChild(std::unique_ptr<RequirementData> child)
  {
    child->parent = this;
    children.push_back(std::move(child));
    return children.back().get();
  }
};
//--------------------------------------------------------------

/* --- */

//--------------------------------------------------------------
class RequirementTreeModel : public wxDataViewModel
{
  public:
  RequirementTreeModel();                                                             // Default constructor
  virtual ~RequirementTreeModel()                                      = default;     // Default destructor
  RequirementTreeModel(const RequirementTreeModel &obj)                = delete;      // Copy constructor
  RequirementTreeModel(RequirementTreeModel &&obj) noexcept            = delete;      // Move constructor
  RequirementTreeModel &operator=(const RequirementTreeModel &obj)     = delete;      // Copy assignment operator
  RequirementTreeModel &operator=(RequirementTreeModel &&obj) noexcept = delete;      // Move assignment operator

  // wxDataViewModel overrides methods
  unsigned GetColumnCount() const override;
  wxString GetColumnType(unsigned) const override;

  void GetValue(wxVariant &variant, const wxDataViewItem &item, unsigned col) const override;
  bool SetValue(const wxVariant &variant, const wxDataViewItem &item, unsigned col) override;

  wxDataViewItem GetParent(const wxDataViewItem &item) const override;
  bool           IsContainer(const wxDataViewItem &item) const override;
  bool           HasContainerColumns(const wxDataViewItem &) const override;

  unsigned GetChildren(const wxDataViewItem &item, wxDataViewItemArray &children) const override;

  // Tree data model specific methods
  RequirementData *AddRootRequirement(std::unique_ptr<RequirementData> requirementData);                               // Add a root requirement to the tree
  RequirementData *AddChildRequirement(RequirementData *parent, std::unique_ptr<RequirementData> requirementData);     // Add a child requirement to a parent requirement
  void             clear();
  RequirementData *GetRequirementData(const wxDataViewItem &item) const;     // Get the requirement data associated with a given item

  protected:
  std::vector<std::unique_ptr<RequirementData>> m_rootRequirement;
};
//--------------------------------------------------------------
}     // namespace gui
