#pragma once

#include "xtr/doc/DocumentManager.h"
#include "xtr/ExteorOptions.h"
#include "xtr/ui/ExteorFrame.h"
#include "xtr/ui/KeyboardHandler.h"
#include "xtr/dialog/StartPage.h"

namespace xtr {

//! Exteor Application
class ExteorApplication final : public CWinAppEx {
  // NOTE: no static objects allowed in Application class - otherwise app crashes in debug builds
public:
  struct Version {
    CString text{};
    CString copyright{};
    CString id{};
  };
  Version version;

  std::vector<ccl::semantic::ConceptRecord> cstClipboard{};

private:
  std::unique_ptr<doc::DocumentManager> docs;

  HANDLE mutex{};
  std::unique_ptr<dialog::ExtStartPage> startPage{ nullptr };

public:
  ExteorApplication();

private:
  BOOL InitInstance() override;
  int32_t ExitInstance() override;

  void LoadCustomState() override;
  void SaveCustomState() override;

public:
  static doc::DocumentManager& Docs() noexcept;
  static ui::ExteorFrame& MainFrame() noexcept;

  [[nodiscard]] CString GetModuleFolder() const;

  BOOL RemoveMRUItem(CString item);

private:
DECLARE_MESSAGE_MAP()
  afx_msg void OnAppAbout();
  afx_msg void OnStartPage();
  afx_msg void OpenHelp();
  afx_msg void OnBugReport();
  afx_msg void OnMailDevelopers();
  afx_msg void OnOpenOptions();

public:
  afx_msg void OnFileNew();
  afx_msg void OnFileOpen();

private:
  BOOL CheckIfAnotherExteorIsRunning() noexcept;
  void FeedCommandLineToAnotherExteor() noexcept;
  void DefaultInitApplication();
  BOOL InitVersion();
  BOOL InitVersionID();
  BOOL CreateMainFrame();
  BOOL InitControls();
  void CreateStartingLook();

  void LoadOptions();
};

// The one and only ExteorApplication object
extern ExteorApplication g_Exteor; // NOLINT

} // namespace xtr