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

#include <algorithm>

#include <imgui.h>

#include <studio/imguiuitl.hpp>

#include "newmenu.hpp"

namespace studio {

NewMenu::NewMenu() noexcept {
	setTitle(ox::String("New Item"));
	setSize({230, 140});
}

void NewMenu::open() noexcept {
	m_stage = Stage::Opening;
	m_selectedType = 0;
}

void NewMenu::close() noexcept {
	m_stage = Stage::Closed;
	m_open = false;
}

bool NewMenu::isOpen() const noexcept {
	return m_open;
}

void NewMenu::draw(turbine::Context &ctx) noexcept {
	switch (m_stage) {
		case Stage::Opening:
			ImGui::OpenPopup(title().c_str());
			m_stage = Stage::NewItemType;
			m_open = true;
			[[fallthrough]];
		case Stage::NewItemType:
			drawNewItemType(ctx);
			break;
		case Stage::NewItemName:
			drawNewItemName(ctx);
			break;
		case Stage::Closed:
			m_open = false;
			break;
	}
}

void NewMenu::addItemMaker(ox::UniquePtr<studio::ItemMaker> im) noexcept {
	m_types.emplace_back(std::move(im));
	std::sort(
			m_types.begin(), m_types.end(),
			[](ox::UPtr<ItemMaker> const&im1, ox::UPtr<ItemMaker> const&im2) {
				 return im1->name < im2->name;
			});
}

void NewMenu::drawNewItemType(turbine::Context &ctx) noexcept {
	drawWindow(ctx, &m_open, [this] {
		auto items = ox_malloca(m_types.size() * sizeof(const char*), const char*, nullptr);
		for (auto i = 0u; const auto &im : m_types) {
			items.get()[i] = im->name.c_str();
			++i;
		}
		ImGui::ListBox("Item Type", &m_selectedType, items.get(), static_cast<int>(m_types.size()));
		drawFirstPageButtons();
	});
}

void NewMenu::drawNewItemName(turbine::Context &ctx) noexcept {
	drawWindow(ctx, &m_open, [this, &ctx] {
		const auto typeIdx = static_cast<std::size_t>(m_selectedType);
		if (typeIdx < m_types.size()) {
			ImGui::InputText("Name", m_itemName.data(), m_itemName.cap());
		}
		drawLastPageButtons(ctx);
	});
}

void NewMenu::drawFirstPageButtons() noexcept {
	ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 130);
	ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetContentRegionAvail().y - 20);
	auto const btnSz = ImVec2(60, 20);
	if (ImGui::Button("Next", btnSz)) {
		m_stage = Stage::NewItemName;
	}
	ImGui::SameLine();
	if (ImGui::Button("Cancel", btnSz)) {
		ImGui::CloseCurrentPopup();
		m_stage = Stage::Closed;
	}
}

void NewMenu::drawLastPageButtons(turbine::Context &ctx) noexcept {
	ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 138);
	ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetContentRegionAvail().y - 20);
	if (ImGui::Button("Back")) {
		m_stage = Stage::NewItemType;
	}
	ImGui::SameLine();
	if (ImGui::Button("Finish")) {
		finish(ctx);
	}
	ImGui::SameLine();
	if (ImGui::Button("Quit")) {
		ImGui::CloseCurrentPopup();
		m_stage = Stage::Closed;
	}
}

void NewMenu::finish(turbine::Context &ctx) noexcept {
	const auto err = m_types[static_cast<std::size_t>(m_selectedType)]->write(ctx, m_itemName);
	if (err) {
		oxLogError(err);
		return;
	}
	finished.emit("");
	m_stage = Stage::Closed;
}

}
