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

#pragma once

#include <ox/claw/claw.hpp>

#include <keel/media.hpp>
#include <turbine/context.hpp>

#include "context.hpp"

namespace studio {

class ItemMaker {
	public:
		const ox::String name;
		const ox::String parentDir;
		const ox::String fileExt;
		constexpr explicit ItemMaker(ox::StringView pName, ox::StringView pParentDir, ox::CRStringView pFileExt) noexcept:
			name(pName),
			parentDir(pParentDir),
			fileExt(pFileExt) {
		}
		virtual ~ItemMaker() noexcept = default;
		virtual ox::Error write(turbine::Context &ctx, ox::CRStringView pName) const noexcept = 0;
};

template<typename T>
class ItemMakerT: public ItemMaker {
	private:
		const T item;
		const ox::ClawFormat fmt;
	public:
		constexpr ItemMakerT(
				ox::StringView pDisplayName,
				ox::StringView pParentDir,
				ox::StringView fileExt,
				ox::ClawFormat pFmt = ox::ClawFormat::Metal) noexcept:
			ItemMaker(pDisplayName, pParentDir, fileExt),
			fmt(pFmt) {
		}
		constexpr ItemMakerT(
				ox::StringView pDisplayName,
				ox::StringView pParentDir,
				ox::StringView fileExt,
				T pItem,
				ox::ClawFormat pFmt) noexcept:
			ItemMaker(pDisplayName, pParentDir, fileExt),
			item(pItem),
			fmt(pFmt) {
		}
		constexpr ItemMakerT(
				ox::StringView pDisplayName,
				ox::StringView pParentDir,
				ox::StringView fileExt,
				T &&pItem,
				ox::ClawFormat pFmt) noexcept:
			 ItemMaker(pDisplayName, pParentDir, fileExt),
			 item(std::move(pItem)),
			 fmt(pFmt) {
		}
		ox::Error write(turbine::Context &ctx, ox::CRStringView pName) const noexcept override {
			const auto path = ox::sfmt("/{}/{}.{}", parentDir, pName, fileExt);
			auto sctx = turbine::applicationData<studio::StudioContext>(ctx);
			keel::createUuidMapping(keelCtx(ctx), path, ox::UUID::generate().unwrap());
			return sctx->project->writeObj(path, item, fmt);
		}
};

}
