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

#include <imgui.h>

#include <ox/std/memory.hpp>

#include <keel/media.hpp>

#include <nostalgia/core/gfx.hpp>

#include "paletteeditor.hpp"
#include "paletteeditor-imgui.hpp"

namespace nostalgia::core {

PaletteEditorImGui::PaletteEditorImGui(turbine::Context &ctx, ox::CRStringView path):
	Editor(path),
	m_ctx(ctx),
	m_pal(*keel::readObj<Palette>(keelCtx(m_ctx), ox::FileAddress(itemPath())).unwrapThrow()) {
}

void PaletteEditorImGui::draw(turbine::Context&) noexcept {
	static constexpr auto flags = ImGuiTableFlags_RowBg;
	const auto paneSize = ImGui::GetContentRegionAvail();
	ImGui::BeginChild("Colors", ImVec2(paneSize.x - 208, paneSize.y), true);
	{
		const auto colorsSz = ImGui::GetContentRegionAvail();
		static constexpr auto toolbarHeight = 40;
		{
			const auto sz = ImVec2(70, 24);
			if (ImGui::Button("Add", sz)) {
				const auto colorSz = static_cast<int>(m_pal.colors.size());
				constexpr Color16 c = 0;
				undoStack()->push(ox::make_unique<AddColorCommand>(&m_pal, c, colorSz));
			}
			ImGui::SameLine();
			ImGui::BeginDisabled(m_selectedRow >= m_pal.colors.size());
			{
				if (ImGui::Button("Remove", sz)) {
					undoStack()->push(
							ox::make_unique<RemoveColorCommand>(
								&m_pal,
								m_pal.colors[static_cast<std::size_t>(m_selectedRow)],
								static_cast<int>(m_selectedRow)));
					m_selectedRow = ox::min(m_pal.colors.size() - 1, m_selectedRow);
				}
				ImGui::SameLine();
				ImGui::BeginDisabled(m_selectedRow <= 0);
				{
					if (ImGui::Button("Move Up", sz)) {
						undoStack()->push(ox::make_unique<MoveColorCommand>(&m_pal, m_selectedRow, -1));
						--m_selectedRow;
					}
				}
				ImGui::EndDisabled();
				ImGui::SameLine();
				ImGui::BeginDisabled(m_selectedRow >= m_pal.colors.size() - 1);
				{
					if (ImGui::Button("Move Down", sz)) {
						undoStack()->push(ox::make_unique<MoveColorCommand>(&m_pal, m_selectedRow, 1));
						++m_selectedRow;
					}
				}
				ImGui::EndDisabled();
			}
			ImGui::EndDisabled();
		}
		ImGui::BeginTable("Colors", 5, flags, ImVec2(colorsSz.x, colorsSz.y - (toolbarHeight + 5)));
		{
			ImGui::TableSetupColumn("Idx", ImGuiTableColumnFlags_WidthFixed, 25);
			ImGui::TableSetupColumn("Red", ImGuiTableColumnFlags_WidthFixed, 50);
			ImGui::TableSetupColumn("Green", ImGuiTableColumnFlags_WidthFixed, 50);
			ImGui::TableSetupColumn("Blue", ImGuiTableColumnFlags_WidthFixed, 50);
			ImGui::TableSetupColumn("Color Preview", ImGuiTableColumnFlags_NoHide);
			ImGui::TableHeadersRow();
			constexpr auto colVal = [] (unsigned num) {
				ox::Array<char, 4> numStr;
				ImGui::TableNextColumn();
				ox_itoa(num, numStr.data());
				ImGui::SetCursorPosX(
						ImGui::GetCursorPosX() + ImGui::GetColumnWidth() - ImGui::CalcTextSize(numStr.data()).x);
				ImGui::Text("%s", numStr.data());
			};
			for (auto i = 0u; const auto c : m_pal.colors) {
				ImGui::PushID(static_cast<int>(i));
				ImGui::TableNextRow();
				// Color No.
				colVal(i);
				// Red
				colVal(red16(c));
				// Green
				colVal(green16(c));
				// Blue
				colVal(blue16(c));
				// ColorPreview
				ImGui::TableNextColumn();
				const auto ic = ImGui::GetColorU32(ImVec4(redf(c), greenf(c), bluef(c), 1));
				ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ic);
				if (ImGui::Selectable("##ColorRow", i == m_selectedRow, ImGuiSelectableFlags_SpanAllColumns)) {
					m_selectedRow = i;
				}
				ImGui::PopID();
				++i;
			}
		}
		ImGui::EndTable();
	}
	ImGui::EndChild();
	if (m_selectedRow < m_pal.colors.size()) {
		ImGui::SameLine();
		ImGui::BeginChild("ColorEditor", ImVec2(200, paneSize.y), true);
		{
			const auto c = m_pal.colors[m_selectedRow];
			int r = red16(c);
			int g = green16(c);
			int b = blue16(c);
			int const a = alpha16(c);
			ImGui::InputInt("Red", &r, 1, 5);
			ImGui::InputInt("Green", &g, 1, 5);
			ImGui::InputInt("Blue", &b, 1, 5);
			const auto newColor = color16(r, g, b, a);
			if (c != newColor) {
				undoStack()->push(ox::make_unique<UpdateColorCommand>(&m_pal, static_cast<int>(m_selectedRow), c, newColor));
			}
		}
		ImGui::EndChild();
	}
}

ox::Error PaletteEditorImGui::saveItem() noexcept {
	const auto sctx = applicationData<studio::StudioContext>(m_ctx);
	return sctx->project->writeObj(itemPath(), m_pal);
}

}
