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

#pragma once

#include <nostalgia/core/gfx.hpp>
#include <nostalgia/studio/studio.hpp>

namespace nostalgia::core {

enum class PaletteEditorCommandId {
	AddColor,
	RemoveColor,
	UpdateColor,
	MoveColor,
};


class AddColorCommand: public studio::UndoCommand {
	private:
		Palette *m_pal = nullptr;
		Color16 m_color = 0;
		int m_idx = -1;

	public:
		AddColorCommand(Palette *pal, Color16 color, int idx) noexcept;

		~AddColorCommand() noexcept override = default;

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

		void redo() noexcept override;

		void undo() noexcept override;

};

class RemoveColorCommand: public studio::UndoCommand {
	private:
		Palette *m_pal = nullptr;
		Color16 m_color = 0;
		int m_idx = -1;

	public:
		RemoveColorCommand(Palette *pal, Color16 color, int idx) noexcept;

		~RemoveColorCommand() noexcept override = default;

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

		void redo() noexcept override;

		void undo() noexcept override;

};

class UpdateColorCommand: public studio::UndoCommand {
	private:
		Palette *m_pal = nullptr;
		Color16 m_oldColor = 0;
		Color16 m_newColor = 0;
		int m_idx = -1;

	public:
		UpdateColorCommand(Palette *pal, int idx, Color16 oldColor, Color16 newColor) noexcept;

		~UpdateColorCommand() noexcept override = default;

		[[nodiscard]]
		bool mergeWith(const UndoCommand *cmd) noexcept final;

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

		void redo() noexcept final;

		void undo() noexcept final;

};

class MoveColorCommand: public studio::UndoCommand {
	private:
		Palette *m_pal = nullptr;
		std::size_t m_idx = 0;
		int m_offset = 0;

	public:
		MoveColorCommand(Palette *pal, std::size_t idx, int offset) noexcept;

		~MoveColorCommand() noexcept override = default;

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

	public:
		void redo() noexcept override;

		void undo() noexcept override;

	private:
		void moveColor(int idx, int offset) noexcept;
};

}