/*
 * Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
 */

#pragma once

#include <ox/std/vec.hpp>

#include <glutils/glutils.hpp>
#include <studio/editor.hpp>
#include <studio/filepickerpopup.hpp>

#include "tilesheetpixels.hpp"
#include "tilesheeteditorview.hpp"

namespace nostalgia::gfx {

class TileSheetEditorImGui: public studio::Editor {

	private:
		class SubSheetEditor {
			private:
				ox::IString<100> m_name;
				int m_cols = 0;
				int m_rows = 0;
				bool m_show = false;
			public:
				ox::Signal<ox::Error(ox::StringViewCR name, int cols, int rows)> inputSubmitted;
				void show(ox::StringViewCR name, int cols, int rows) noexcept;
				void draw() noexcept;
				void close() noexcept;
				[[nodiscard]]
				constexpr bool isOpen() const noexcept { return m_show; }
		};
		class ExportMenu {
			private:
				 int m_scale = 0;
				 bool m_show = false;
			public:
				ox::Signal<ox::Error(int scale)> inputSubmitted;
				void show() noexcept;
				void draw() noexcept;
				void close() noexcept;
				[[nodiscard]]
				constexpr bool isOpen() const noexcept { return m_show; }
		};
		static constexpr float s_palViewWidth = 335;
		studio::Context &m_sctx;
		turbine::Context &m_tctx;
		ox::Vector<ox::String> m_paletteList;
		SubSheetEditor m_subsheetEditor;
		ExportMenu m_exportMenu;
		studio::FilePickerPopup m_palPicker;
		glutils::FrameBuffer m_framebuffer;
		TileSheetEditorView m_view;
		TileSheetEditorModel &m_model;
		ox::Vec2 m_prevMouseDownPos;
		TileSheetTool m_tool = TileSheetTool::Draw;
		bool m_palPathFocused{};

	public:
		TileSheetEditorImGui(studio::Context &sctx, ox::StringParam path);

		~TileSheetEditorImGui() override = default;

		void exportFile() override;

		void cut() override;

		void copy() override;

		void paste() override;

		[[nodiscard]]
		bool acceptsClipboardPayload() const noexcept override;

		void keyStateChanged(turbine::Key key, bool down) override;

		void draw(studio::Context&) noexcept override;

		void drawSubsheetSelector(TileSheet::SubSheet&, TileSheet::SubSheetIdx &path);

		[[nodiscard]]
		static ox::Vec2 clickPos(ImVec2 const &winPos, ox::Vec2 clickPos) noexcept;

	protected:
		ox::Error saveItem() noexcept override;

		void navigateTo(ox::StringViewCR arg) noexcept override;

	private:
		void showSubsheetEditor() noexcept;

		ox::Error exportSubsheetToPng(int scale) const noexcept;

		void drawTileSheet(ox::Vec2 const &fbSize) noexcept;

		void drawPaletteMenu() noexcept;

		ox::Error updateActiveSubsheet(ox::StringViewCR name, int cols, int rows) noexcept;

		void setActiveSubsheet(TileSheet::SubSheetIdx path) noexcept;

};

}
