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

#pragma once

#include <turbine/clipboard.hpp>

#include "commands.hpp"

namespace nostalgia::gfx {

OX_MODEL_FWD_DECL(class TileSheetClipboard);

class TileSheetClipboard: public turbine::ClipboardObject<TileSheetClipboard> {
	public:
		static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.studio.TileSheetClipboard";
		static constexpr auto TypeVersion = 1;

		OX_MODEL_FRIEND(TileSheetClipboard);

		struct Pixel {
			static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.studio.TileSheetClipboard.Pixel";
			static constexpr auto TypeVersion = 1;
			uint8_t colorIdx = 0;
			ox::Point pt;
			Pixel(uint8_t pColorIdx, ox::Point pPt) noexcept;
		};
	protected:
		ox::Vector<Pixel> m_pixels;

	public:
		void addPixel(ox::Point const &pt, uint8_t colorIdx) noexcept;

		[[nodiscard]]
		ox::Vector<Pixel> const &pixels() const noexcept;
};

OX_MODEL_BEGIN(TileSheetClipboard::Pixel)
	OX_MODEL_FIELD(colorIdx)
	OX_MODEL_FIELD(pt)
OX_MODEL_END()

OX_MODEL_BEGIN(TileSheetClipboard)
	OX_MODEL_FIELD_RENAME(m_pixels, pixels)
OX_MODEL_END()

class CutPasteCommand: public TileSheetCommand {
	private:
		struct Change {
			uint32_t idx = 0;
			uint8_t palIdx = 0;
			constexpr Change(uint32_t const pIdx, uint8_t const pPalIdx) noexcept {
				idx = pIdx;
				palIdx = pPalIdx;
			}
		};
		CommandId m_commandId;
		TileSheet &m_img;
		TileSheet::SubSheetIdx m_subSheetIdx;
		ox::Vector<Change> m_changes;

	public:
		CutPasteCommand(
				CommandId commandId,
				TileSheet &img,
				TileSheet::SubSheetIdx subSheetIdx,
				ox::Point const &dstStart,
				ox::Point dstEnd,
				TileSheetClipboard const &cb);

		ox::Error redo() noexcept final;

		ox::Error undo() noexcept final;

		[[nodiscard]]
		int commandId() const noexcept final;

		[[nodiscard]]
		TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;

	private:
		void swap() noexcept;

};

}
