#pragma once

#include "xtr/doc/RSFormDoc.h"
#include "xtr/ui/ElementShell.h"

namespace xtr::dialog {

//! Synthesis options dialog
class SynthesUI : public CPropertySheet {
  class OperandsPage;
  class OptionsPage;
  class ConfirmPage;

public:
  BOOL ossModeOn;
  ccl::ops::Type opType;

  CString title{};
  CString alias{};

  ccl::ops::EquationOptions equations{};
  const ccl::semantic::RSForm* operand1{ nullptr };
  const ccl::semantic::RSForm* operand2{ nullptr };

private:
  std::unique_ptr<OperandsPage> operandsPage;
  std::unique_ptr<OptionsPage> optionsPage;
  std::unique_ptr<ConfirmPage> confirmationPage;

public:
  explicit SynthesUI(ccl::ops::Type type, BOOL fromOSS = FALSE, CWnd* pWndParent = nullptr);

public:
  [[nodiscard]] BOOL IsCorrect() const;

private:
  BOOL PreTranslateMessage(MSG* pMsg) override;
};

//! DialogPage: Choose operands
class SynthesUI::OperandsPage final : public CPropertyPage {
  struct OperandsHeader;

  SynthesUI& parentSht;

  ui::RSListCtrl firstOperandList{};
  ui::RSListCtrl secondOperandList{};

  CString firstOperand{};
  CString secondOperand{};

public:
  explicit OperandsPage(SynthesUI& parent);

private:
  void DoDataExchange(CDataExchange* pDX) override;
  BOOL OnInitDialog() override;
  void InitControls();
  void InitHeaders();
  void InputData();

private:
  BOOL OnSetActive() override;
  LRESULT OnWizardNext() override;

  DECLARE_MESSAGE_MAP()
  afx_msg void OnChangeOperands(NMHDR* pNMHDR, LRESULT* pResult);

private:
  [[nodiscard]] static int32_t TypeToRadio(ccl::ops::Type type) noexcept;
  [[nodiscard]] static ccl::ops::Type RadioToType(int32_t radio) noexcept;

  void DDVNextBtn(int32_t nItem1, int32_t nItem2);

  [[nodiscard]] static doc::RSFormDoc* GetTRSDocFromCList(const ui::RSListCtrl& lc);
  static void UpdateDocList(ui::RSListCtrl& lc, 
                            const doc::RSFormDoc* docExclude = nullptr);
};

//! DialogPage: Setup equation options
class SynthesUI::OptionsPage final : public CPropertyPage {
  struct ArgHeader;

  CButton  operand1Btn{};
  CButton  operand2Btn{};
  CButton  equalsBtn{};

  ui::RSListCtrl operand2List{};
  ui::RSListCtrl operand1List{};

  ui::EquationsRSLC  equationsCtrl{};

  BOOL basic1Flag{ TRUE };
  BOOL structure1Flag{ TRUE };
  BOOL term1Flag{ TRUE };
  BOOL basic2Flag{ TRUE };
  BOOL structure2Flag{ TRUE };
  BOOL term2Flag{ TRUE };

  SynthesUI& parentSht;

public:
  explicit OptionsPage(SynthesUI& parent);

private:
  void DoDataExchange(CDataExchange* pDX) override;
  BOOL OnInitDialog() override;
  void InitHeaders();

private:
  BOOL OnSetActive() override;
  LRESULT OnWizardNext() override;

  DECLARE_MESSAGE_MAP()
  afx_msg void OnIn1();
  afx_msg void OnIn2();
  afx_msg void OnIn3();
  afx_msg void OnChange();
  afx_msg void OnDblClickList(NMHDR* pNMHDR, LRESULT* pResult);

private:
  static CString AskForTerm(CString initial);

  void DDV_Buttons();

  void AddPair(ccl::ops::Equation::Mode type);
  void RemovePair();

  void UpdateCstLists();
  void FillCstOfType(int32_t list1Or2, ccl::semantic::CstType type, const SetOfEntities& ignoreList);
  static void FillCstInCL(ui::RSListCtrl& lc, const ccl::semantic::RSForm& schema, 
                   int32_t nameCol, int32_t termCol,
                   ccl::semantic::CstType type, const SetOfEntities& ignoreList);
};

//! DialogPage: Confirm options
class SynthesUI::ConfirmPage : public CPropertyPage {
public:
  CString operation{};
  CString firstOperand{};
  CString secondOperand{};

private:
  ui::EquationsRSLC  equationsCtrl;
  ui::CstPicker shortNameCtrl;
  ui::CstPicker fullNameCtrl;

  SynthesUI& parentSht;

public:
  explicit ConfirmPage(SynthesUI& parent);

private:
  void DoDataExchange(CDataExchange* pDX) override;
  BOOL OnInitDialog() override;
  void InitControls();

private:
  BOOL OnSetActive() override;

  DECLARE_MESSAGE_MAP()
  afx_msg void OnChange();
  afx_msg void OnComboChanged();

private:
  void DDV_Names();
};

} // namespace xtr::dialog