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

#include <algorithm>

#include <imgui.h>

#include <studio/imguiutil.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;
	m_itemName = "";
	m_typeName = "";
}

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

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

void NewMenu::draw(studio::StudioContext &sctx) noexcept {
	switch (m_stage) {
		case Stage::Opening:
			ImGui::OpenPopup(title().c_str());
			m_stage = Stage::NewItemType;
			m_open = true;
			[[fallthrough]];
		case Stage::NewItemType:
			drawNewItemType(sctx);
			break;
		case Stage::NewItemName:
			drawNewItemName(sctx);
			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->typeName < im2->typeName;
			});
}

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

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

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(studio::StudioContext &sctx) 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(sctx);
	}
	ImGui::SameLine();
	if (ImGui::Button("Quit")) {
		ImGui::CloseCurrentPopup();
		m_stage = Stage::Closed;
	}
}

void NewMenu::finish(studio::StudioContext &sctx) noexcept {
	if (m_itemName.len() == 0) {
		return;
	}
	auto const&typeMaker = *m_types[static_cast<std::size_t>(m_selectedType)];
	if (sctx.project->exists(typeMaker.itemPath(m_itemName))) {
		oxLogError(OxError(1, "New file error: File already exists"));
		return;
	}
	auto const [path, err] = typeMaker.write(sctx, m_itemName);
	if (err) {
		oxLogError(err);
		return;
	}
	finished.emit(path);
	m_stage = Stage::Closed;
}

}
