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

#include <nfd.hpp>

#include <ox/std/error.hpp>
#include <ox/std/string.hpp>

#include <studio/filedialog.hpp>

namespace studio {

FDFilterItem::FDFilterItem(ox::StringViewCR pName, ox::StringViewCR pSpec) noexcept {
	OX_ALLOW_UNSAFE_BUFFERS_BEGIN
	name.resize(pName.size() + 1);
	ox::strncpy(name.data(), pName.data(), pName.size());
	spec.resize(pSpec.size() + 1);
	ox::strncpy(spec.data(), pSpec.data(), pSpec.size());
	OX_ALLOW_UNSAFE_BUFFERS_END
}

static ox::Result<ox::String> toResult(nfdresult_t r, NFD::UniquePathN const &path) noexcept {
	switch (r) {
		case NFD_OKAY: {
			ox::String out;
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
			for (auto i = 0u; path.get()[i]; ++i) {
				auto const c = static_cast<char>(path.get()[i]);
				std::ignore = out.append(&c, 1);
			}
OX_ALLOW_UNSAFE_BUFFERS_END
			return out;
		}
		case NFD_CANCEL:
			return ox::Error(1, "Operation cancelled");
		default:
			return ox::Error(2, NFD::GetError());
	}
}

ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const &exts) noexcept {
	NFD::Guard const guard;
	NFD::UniquePathN path;
	ox::Vector<nfdnfilteritem_t, 5> filterItems(exts.size());
	for (auto i = 0u; auto const &f : exts) {
		filterItems[i].name = f.name.data();
		filterItems[i].spec = f.spec.data();
		++i;
	}
	auto const filterItemsCnt = static_cast<nfdfiltersize_t>(filterItems.size());
	return toResult(NFD::SaveDialog(path, filterItems.data(), filterItemsCnt), path);
}

ox::Result<ox::String> chooseDirectory() noexcept {
	const NFD::Guard guard;
	NFD::UniquePathN path;
	return toResult(NFD::PickFolder(path), path);
}

}
