#pragma once

#include "OSSLayout.h"
#include "xtr/doc/OSSDoc.h"

namespace xtr::view {

//! View: OSS
class OSSView final : public CScrollView {
  friend class OSSLayout;
  DECLARE_DYNCREATE(OSSView)

  doc::OSSDoc* document{ nullptr };
  ccl::oss::OSSchema* oss{ nullptr };
  std::unique_ptr<OSSLayout> layout{ nullptr };

  CToolTipCtrl tooltips;

  HCURSOR  cursorHyperlink{};
  HCURSOR  cursorMarkOperation{};
  BOOL newOperationMode{ FALSE };

  std::optional<ccl::oss::PictID> pictUnderCursor{};

private:
  OSSView() = default;

private:
  void DoDataExchange(CDataExchange* pDX) override;
  void OnInitialUpdate() override;
  void InitCursor();
  void InitTooltips();

private:
  BOOL PreTranslateMessage(MSG* pMsg) override;
  void OnDraw(CDC* pDC) override;
  void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override;
  BOOL OnScrollBy(CSize sizeScroll, BOOL bDoScroll) override;

DECLARE_MESSAGE_MAP()
  afx_msg BOOL OnCommandRun(uint32_t command);
  afx_msg void OnUpdateCommandUI(CCmdUI* pCmdUI);

  afx_msg BOOL OnMouseWheel(uint32_t fFlags, short zDelta, CPoint pt);
  afx_msg BOOL OnSetCursor(CWnd* pWnd, uint32_t nHitTest, uint32_t message);
  afx_msg void OnMouseMove(uint32_t nFlags, CPoint point);
  afx_msg void OnMouseHover(uint32_t nFlags, CPoint point);
  afx_msg void OnLButtonUp(uint32_t nFlags, CPoint point);
  afx_msg void OnRButtonUp(uint32_t nFlags, CPoint point);
  afx_msg void OnLButtonDblClk(uint32_t nFlags, CPoint point);
  afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
  afx_msg void OnSetFocus(CWnd* pOldWnd);

private:
  void StartHoverTimer() noexcept;

  void UpdateScrollSize();
  void UpdateCursor(ccl::oss::PictPtr pict = nullptr) const;
  void ScrollToSelected();

  [[nodiscard]] BOOL IsCommandActive(uint32_t command) const;

  void DocToClient(CRect& rect);
  void DocToClient(CPoint& point);
  void ClientToDoc(CPoint& point);
  void ClientToDoc(CRect& rect);
};

} // namespace xtr::view