#include "dialogue/DialogueSystem.h"

namespace ZL::Dialogue {

bool DialogueSystem::init(Renderer& renderer, const std::string& zipFile) {
	runtime.setDatabase(&database);
	return overlay.init(renderer, zipFile);
}

bool DialogueSystem::loadDatabase(const std::string& path) {
	return database.loadFromFile(path);
}

void DialogueSystem::update(int deltaMs) {
	runtime.update(deltaMs);
	overlay.update(runtime.getPresentation(), deltaMs);
	if (overlay.consumeSkipRequested()) {
		runtime.skipCurrentCutscene();
	}
}

void DialogueSystem::draw(Renderer& renderer) {
	overlay.draw(renderer, runtime.getPresentation());
}

bool DialogueSystem::handleKeyDown(SDL_Keycode key) {
	if (!runtime.isActive()) {
		return false;
	}

	if (runtime.isPlayingCutscene()) {
		switch (key) {
		case SDLK_RETURN:
		case SDLK_SPACE:
		case SDLK_e:
		case SDLK_ESCAPE:
			return true;
		default:
			return false;
		}
	}

	switch (key) {
		case SDLK_RETURN:
		case SDLK_SPACE:
		case SDLK_e:
			runtime.confirmAdvance();
			return true;

		case SDLK_UP:
		case SDLK_w:
			runtime.moveSelection(-1);
			return true;

		case SDLK_DOWN:
		case SDLK_s:
			runtime.moveSelection(1);
			return true;

		case SDLK_ESCAPE:
			stopDialogue();
			return true;

		default:
			return false;
	}
}

void DialogueSystem::handlePointerDown(float x, float y) {
	if (!runtime.isActive()) {
		return;
	}
	overlay.handlePointerDown(x, y, runtime.getPresentation());
}

void DialogueSystem::handlePointerMoved(float x, float y) {
	if (!runtime.isActive()) {
		return;
	}
	overlay.handlePointerMoved(x, y, runtime.getPresentation());
}

bool DialogueSystem::handlePointerReleased(float x, float y) {
	if (!runtime.isActive()) {
		return false;
	}

	int choiceIndex = -1;
	bool advanceDialogue = false;
	const PresentationModel& model = runtime.getPresentation();
	if (!overlay.handlePointerReleased(x, y, model, choiceIndex, advanceDialogue)) {
		if (overlay.consumeSkipRequested()) {
			runtime.skipCurrentCutscene();
			return true;
		}
		return runtime.isPlayingCutscene();
	}

	if (choiceIndex >= 0) {
		runtime.selectChoice(choiceIndex);
		runtime.confirmAdvance();
		return true;
	}

	if (advanceDialogue) {
		runtime.confirmAdvance();
		return true;
	}

	if (overlay.consumeSkipRequested()) {
		runtime.skipCurrentCutscene();
		return true;
	}

	return true;
}

bool DialogueSystem::startDialogue(const std::string& dialogueId) {
	return runtime.startDialogue(dialogueId);
}

bool DialogueSystem::startCutscene(const std::string& cutsceneId) {
	return runtime.startStandaloneCutscene(cutsceneId);
}

void DialogueSystem::setOnCutsceneFinished(std::function<void(const std::string&)> cb) {
	runtime.setOnCutsceneFinished(std::move(cb));
}

void DialogueSystem::stopDialogue() {
	runtime.stop();
}

} // namespace ZL::Dialogue