// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
pub mod online;
pub mod local;
pub mod enter_address;
pub mod create_local;
pub mod story_mode;
mod common;
mod discovery;

use std::any::Any;

use glium::Frame as GliumFrame;
use winit::event::Event;

use crate::app::{App, config::action::ActionEvent, state::{GameState, GameStateId, Status}, gui::{GuiState, style::UiExt}};

pub struct PlaySelection {
	gui_state: GuiState,
}

impl PlaySelection {
	pub fn new() -> PlaySelection {
		PlaySelection { gui_state: GuiState::new() }
	}
}

impl GameState for PlaySelection {
	fn enable(&mut self, app: &mut App) {
		self.gui_state.enable(&mut app.gui);
	}

	fn push(&mut self, _app: &mut App, msg: Option<Box<dyn Any>>) {
		debug_assert!(msg.is_none());
	}

	fn disable(&mut self, _app: &mut App) {}

	fn action(&mut self, action: ActionEvent) {
		self.gui_state.action(action);
	}

	fn event(&mut self, app: &mut App, event: &Event<()>) {
		self.gui_state.event(app, event);
	}

	fn loop_iter(&mut self, app: &mut App, frame: &mut GliumFrame) -> Status {
		enum Action {
			Online,
			Local,
			EnterAddress,
			CreateLocal,
			StoryMode,
		}

		let mut action = None;

		let res = GuiState::update(&mut app.gui, "play-selection", &app.window, |_, ui| {
			ui.h1("Play").no_bottom_padding().add();
			ui.h2("Singleplayer").add();
			if ui.b2("Story Mode").clicked() {
				action = Some(Action::StoryMode);
			}

			ui.h2("Multiplayer").no_bottom_padding().add();
			ui.h3("Join").add();
			if ui.b2("Online").clicked() {
				action = Some(Action::Online);
			}

			ui.add_space(4.0);
			if ui.b2("Local").clicked() {
				action = Some(Action::Local);
			}

			ui.add_space(4.0);
			if ui.b2("Enter Address").clicked() {
				action = Some(Action::EnterAddress);
			}

			ui.h3("Create").no_bottom_padding().add();
			ui.add_space(4.0);
			ui.label("Create a server playable on the local network.");
			ui.add_space(8.0);
			if ui.b2("Local").clicked() {
				action = Some(Action::CreateLocal);
			}

			if ui.b_back().clicked() {
				self.gui_state.exit();
			}
		});
		self.gui_state.after_update(res);

		app.gui.render(&app.display, frame);

		match action {
			_ if self.gui_state.should_exit() => Status::PopState,
			Some(Action::Online) => Status::PushState(GameStateId::PsOnline, None),
			Some(Action::Local) => Status::PushState(GameStateId::PsLocal, None),
			Some(Action::EnterAddress) => Status::PushState(GameStateId::PsEnterAddress, None),
			Some(Action::CreateLocal) => Status::PushState(GameStateId::PsCreateLocal, None),
			Some(Action::StoryMode) => Status::PushState(GameStateId::PsStoryMode, None),
			None => Status::Ok,
		}
	}
}
