#pragma once

#include "xtr/ui/BuffRichEdit.h"
#include "xtr/viewmodel/vmTextEdit.h"
#include "xtr/doc/RSFacade.h"

namespace xtr::ui {

//! Referenced text editor control
class TextEdit : public BuffRichEdit, public viewmodel::ITextEdit {
  xtr::viewmodel::vmTextEdit presenter;

  BOOL resolveRefs{ FALSE };
  BOOL ignoreReturn{ FALSE };

  doc::RSFacade* editor{ nullptr };

public:
  TextEdit();

  void Initialize(CString refStr, doc::RSFacade& targetEditor, BOOL advancedRefs, BOOL wantReturn = TRUE);

public:
  void SetRefStr(CString refStr);
  [[nodiscard]] CString GetRefStr();

private:
  [[nodiscard]] CString GetText() const override;
  void SetText(CString text) override;
  void ReplaceRange(StrRange range, CString replacement) override;

  void Highlight(viewmodel::HighlightItem item) override;
  [[nodiscard]] std::optional<viewmodel::HighlightItem> NextHighlighted(StrPos start) override;

private:
  void PreSubclassWindow() override;
  BOOL PreTranslateMessage(MSG* pMsg) override;

  void UnFreezeUI() override;
  CString GenerateToolTipText() override;

DECLARE_MESSAGE_MAP()
  afx_msg BOOL OnTextChange();
  afx_msg BOOL OnSelChange(NMHDR* pNotifyStruct, LRESULT* result);
  afx_msg void OnKeyDown(uint32_t key, uint32_t nRepCnt, uint32_t nFlags);

  [[nodiscard]] BOOL ProcessKeyDown(uint32_t key, uint32_t nRepCnt, uint32_t nFlags);
  [[nodiscard]] BOOL PreProcessKey(uint32_t key);
  [[nodiscard]] BOOL ProcessKeyConst(uint32_t key);
  [[nodiscard]] BOOL ProcessKeyEdit(uint32_t key);

private:
  void UpdateLock();

  BOOL RunAddTerminRef();
  BOOL RunAddDependWord();
  [[nodiscard]] RECT GetWordDlgPos();

  void CopyWithReferences(StrRange range);
  StrRange ShrinkSelection();

  void ResetHighlight(StrRange hlRange);

  [[nodiscard]] BOOL IsBorderHL(StrPos position, BOOL oneSide = FALSE);
  [[nodiscard]] std::optional<viewmodel::HighlightItem> ScanHighlight(StrPos start);
};

} // namespace xtr::ui