#pragma once

namespace xtr::view {

//! OSS drawing manager
class OSSLayout  {
  enum class IconID : uint8_t {
    OSSI_PICT_BASIS = 0,
    OSSI_PICT_UNDEFINED = 1,
    OSSI_PICT_DEFINED = 2,
    OSSI_PICT_DONE = 3,
    OSSI_PICT_REDO = 4,
    OSSI_PICT_BROKEN = 5,
    OSSI_PICT_HASFILE = 6,
  };

  struct Buffer {
    CRect rect{};
    CBitmap bmp{};
    CBitmap* oldBitmap{ nullptr };
    CDC context{};
  };

public:
  mutable CImageList icons{};

  float zoom;

  int32_t charHeight;
  int32_t charWidth;

  int32_t cellWidth;
  int32_t cellHeight;

  int32_t pictWidth;
  int32_t pictHeight;

  mutable int32_t legendYBase{ 0 };

private:
  const ccl::oss::OSSchema* oss;

  BOOL saveImage{ FALSE };
  CDC* drawDC{ nullptr };
  float drawScale{ 1 };
  std::unique_ptr<Buffer> buffer{};

public:
  explicit OSSLayout(const ccl::oss::OSSchema& oss);

public:
  void InitImageList();

  [[nodiscard]] int32_t GetClientHeight() const;
  [[nodiscard]] int32_t GetClientWidth() const;

  [[nodiscard]] CRect PictRect(ccl::oss::PictID pid, float scale = 1) const;
  [[nodiscard]] CRect CellRect(ccl::oss::GridPosition pos, float scale = 1) const noexcept;

  [[nodiscard]] ccl::oss::PictPtr PictFromPoint(CPoint point) const;

  void Draw(CDC* pDC, std::optional<ccl::oss::PictID> active = std::nullopt);
   CImage GetImage();

private:
  std::optional<ccl::oss::GridPosition> PositionFromPoint(CPoint point) const noexcept;

  CRect DetermineDrawArea();
  void PrepareBuffer(CDC* pDC, CRect clientArea);
  void DrawBackground(CRect bgRect);
  void DrawGrid();
  void DrawCell(ccl::oss::GridPosition pos);
  void DrawPictConnections(const ccl::oss::Pict& pict);
  void DrawPict(const ccl::oss::Pict& pict, bool isActive);
  void DrawLegend();
  void DrawLegendItem(IconID icon, CString text);
  void LoadFromBuffer(CDC* pDC);

  void DrawActiveRect(CRect rect);
  void DrawInactiveRect(CRect rect);
  void DrawPictStatus(CRect rect, ccl::oss::PictID pid);
  void DrawPictText(CRect rect, const ccl::oss::Pict & pict);

  void DrawStatusIcon(CPoint topLeft, ccl::oss::PictID pid) const;

  IconID GetIconID(ccl::oss::PictID pid) const;
};

} // namespace xtr::view