#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, const Eigen::Vector3f& playerPosition) {
	if (!runtime.isActive()) {
		for (TriggerZone& zone : triggerZones) {
			if (zone.once && zone.triggered) {
				continue;
			}

			const Eigen::Vector3f diff = playerPosition - zone.center;
			if (diff.norm() <= zone.radius) {
				if (startDialogue(zone.dialogueId)) {
					zone.triggered = true;
					break;
				}
			}
		}
	}

	runtime.update(deltaMs);
}

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

bool DialogueSystem::handleKeyDown(SDL_Keycode key) {
	if (!runtime.isActive()) {
		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;
	}
}

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

	int choiceIndex = -1;
	const PresentationModel& model = runtime.getPresentation();
	if (overlay.handlePointerReleased(x, y, model, choiceIndex)) {
		while (model.selectedChoice != choiceIndex) {
			runtime.moveSelection(1);
		}
		runtime.confirmAdvance();
		return true;
	}

	runtime.confirmAdvance();
	return true;
}

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

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

void DialogueSystem::addTriggerZone(const TriggerZone& zone) {
	triggerZones.push_back(zone);
}

void DialogueSystem::clearTriggerZones() {
	triggerZones.clear();
}

} // namespace ZL::Dialogue