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

#pragma once

#include <ox/model/def.hpp>

#include <nostalgia/geo/vec.hpp>
#include <nostalgia/glutils/glutils.hpp>
#include <nostalgia/studio/studio.hpp>

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

namespace nostalgia::core {

enum class Tool {
	None,
	Draw,
	Fill,
	Select,
};

class TileSheetEditorImGui: public studio::BaseEditor {

	private:
		class SubSheetEditor {
			ox::BString<100> m_name;
			int m_cols = 0;
			int m_rows = 0;
			bool m_show = false;
			public:
				ox::Signal<ox::Error(const ox::String &name, int cols, int rows)> inputSubmitted;
				constexpr void show(const ox::String &name, int cols, int rows) noexcept {
					m_show = true;
					m_name = name.c_str();
					m_cols = cols;
					m_rows = rows;
				}
				void draw() noexcept;
		};
		std::size_t m_selectedPaletteIdx = 0;
		Context *m_ctx = nullptr;
		ox::Vector<ox::String> m_paletteList{};
		SubSheetEditor m_subsheetEditor;
		ox::String m_itemPath;
		ox::String m_itemName;
		glutils::FrameBuffer m_framebuffer;
		TileSheetEditorView m_tileSheetEditor;
		float m_palViewWidth = 300;
		geo::Vec2 m_prevMouseDownPos;
		Tool m_tool = Tool::Draw;

	public:
		TileSheetEditorImGui(Context *ctx, const ox::String &path);

		~TileSheetEditorImGui() override = default;

		const ox::String &itemName() const noexcept override;

		const ox::String &itemDisplayName() const noexcept override;

		void exportFile() override;

		void cut() override;

		void copy() override;

		void paste() override;

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

		void draw(core::Context*) noexcept override;

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

		studio::UndoStack *undoStack() noexcept final;

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

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

	private:
		void showSubsheetEditor() noexcept;

		void exportSubhseetToPng() noexcept;

		[[nodiscard]]
		constexpr auto model() const noexcept {
			return m_tileSheetEditor.model();
		}

		[[nodiscard]]
		constexpr auto model() noexcept {
			return m_tileSheetEditor.model();
		}

		void setPalette();

		void saveState();

		void restoreState();

		[[nodiscard]]
		ox::String paletteName(const ox::String &palettePath) const;

		[[nodiscard]]
		ox::String palettePath(const ox::String &palettePath) const;

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

		void drawPaletteSelector() noexcept;

		ox::Error updateActiveSubsheet(const ox::String &name, int cols, int rows) noexcept;

	// slots
	private:
		ox::Error updateAfterClicked() noexcept;

		ox::Error markUnsavedChanges(const studio::UndoCommand*) noexcept;

};

}
