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

#include <ox/std/trace.hpp>

#include <nostalgia/core/core.hpp>

#include "lib/context.hpp"
#include "studioapp.hpp"

namespace nostalgia {

class StudioUIDrawer: public core::Drawer {
	private:
		StudioUI *m_ui = nullptr;
	public:
		explicit StudioUIDrawer(StudioUI *ui) noexcept: m_ui(ui) {
		}
	protected:
		void draw(core::Context*) noexcept final {
			m_ui->draw();
		}
};

static int updateHandler(core::Context *ctx) noexcept {
	auto sctx = core::applicationData<studio::StudioContext>(ctx);
	auto ui = dynamic_cast<StudioUI*>(sctx->ui);
	ui->update();
	return 16;
}

static void keyEventHandler(core::Context *ctx, core::Key key, bool down) noexcept {
	auto sctx = core::applicationData<studio::StudioContext>(ctx);
	auto ui = dynamic_cast<StudioUI*>(sctx->ui);
	ui->handleKeyEvent(key, down);
}

static ox::Error run(ox::UniquePtr<ox::FileSystem> fs) noexcept {
	oxRequireM(ctx, core::init(std::move(fs), "NostalgiaStudio"));
	core::setWindowTitle(ctx.get(), "Nostalgia Studio");
	core::setUpdateHandler(ctx.get(), updateHandler);
	core::setKeyEventHandler(ctx.get(), keyEventHandler);
	core::setConstantRefresh(ctx.get(), false);
	studio::StudioContext studioCtx;
	core::setApplicationData(ctx.get(), &studioCtx);
	StudioUI ui(ctx.get());
	studioCtx.ui = &ui;
	StudioUIDrawer drawer(&ui);
	ctx->drawers.emplace_back(&drawer);
	return core::run(ctx.get());
}

static ox::Error run(int argc, const char **argv) noexcept {
	ox::trace::init();
	if (argc >= 2) {
		const auto path = argv[1];
		oxRequireM(fs, core::loadRomFs(path));
		return run(std::move(fs));
	} else {
		return run(ox::UniquePtr<ox::FileSystem>(nullptr));
	}
}

}

int main(int argc, const char **argv) {
	const auto err = nostalgia::run(argc, argv);
	oxAssert(err, "Something went wrong...");
	return static_cast<int>(err);
}
