use crate::config::SharedConfig;
use crate::games::{GameState, GameTimelineSearchAndFetch, draw_stats};
use eframe::egui::{self, Context, RichText, Ui, Vec2};
use open_timeline_core::HasIdAndName;
use open_timeline_games::GameManagement;
use open_timeline_games::order_entities::{GameVariant, OrderEntitiesGame};
use open_timeline_gui_core::{Draw, body_text_height};
#[derive(Debug)]
pub struct OrderEntitiesGameGui {
game: OrderEntitiesGame,
state: GameState,
game_timeline_search_and_fetch: GameTimelineSearchAndFetch,
}
impl OrderEntitiesGameGui {
pub fn new(shared_config: SharedConfig) -> Self {
Self {
game: OrderEntitiesGame::new(),
state: GameState::NotStarted,
game_timeline_search_and_fetch: GameTimelineSearchAndFetch::new(shared_config),
}
}
fn draw_question(&mut self, _ctx: &Context, ui: &mut Ui, enabled: bool) {
if let Some(current_question) = self.game.current_question.as_mut()
&& !current_question.is_empty()
{
ui.add_enabled_ui(enabled, |ui| {
let button_size =
Vec2::new(body_text_height(ui) * 2.0, body_text_height(ui) * 1.25);
let mut up: Option<usize> = None;
let mut down = None;
for (index, item) in current_question.iter().enumerate() {
ui.horizontal(|ui| {
let up_button =
ui.add_sized(button_size, egui::Button::new(RichText::new("⏶")));
let down_button =
ui.add_sized(button_size, egui::Button::new(RichText::new("⏷")));
ui.add(egui::Label::new(item.name().as_str()));
if up_button.clicked() && index > 0 {
up = Some(index);
}
if down_button.clicked() && index < current_question.len() {
down = Some(index);
}
});
}
if let Some(index) = up {
if index != 0 {
current_question.swap(index, index - 1);
}
}
if let Some(index) = down {
if index != current_question.len() - 1 {
current_question.swap(index, index + 1);
}
}
});
} else {
open_timeline_gui_core::Label::weak(ui, "No question");
self.draw_new_game_button(ui);
return;
}
if enabled {
if open_timeline_gui_core::Button::tall_full_width(ui, "Submit").clicked() {
let answer = self.game.current_question.clone().unwrap();
let _ = self.game.check_answer(answer);
self.state = GameState::WaitingForNextRound;
}
}
}
fn draw_new_game_button(&mut self, ui: &mut Ui) {
if open_timeline_gui_core::Button::tall_full_width(ui, "New Game").clicked() {
self.game.new_game();
self.state = GameState::NotStarted;
}
}
}
impl Draw for OrderEntitiesGameGui {
fn draw(&mut self, ctx: &Context, ui: &mut Ui) {
open_timeline_gui_core::Label::description(ui, &self.game.description());
ui.separator();
self.game_timeline_search_and_fetch
.draw_timeline_search_bar(ctx, ui, self.state);
ui.separator();
ui.horizontal(|ui| {
ui.add_enabled_ui(self.state == GameState::NotStarted, |ui| {
ui.radio_value(
&mut self.game.variant,
GameVariant::OrderByFirstStarted,
"Order by start date",
);
ui.radio_value(
&mut self.game.variant,
GameVariant::OrderByFirstEnded,
"Order by end date",
);
});
});
ui.separator();
if self.state.has_started() {
draw_stats(ctx, ui, self.game.stats);
ui.separator();
}
match self.state {
GameState::NotStarted => {
ui.add_enabled_ui(
self.game_timeline_search_and_fetch
.timeline_playing_with()
.is_some(),
|ui| {
if open_timeline_gui_core::Button::tall_full_width(ui, "Start").clicked() {
self.game.new_game();
self.game_timeline_search_and_fetch.request_fetch_timeline();
self.state = GameState::StartedWaitingForTimeline;
}
},
);
}
GameState::StartedWaitingForTimeline => {
self.game_timeline_search_and_fetch
.check_for_fetch_response();
if let Some(result) = self.game_timeline_search_and_fetch.timeline.as_ref() {
match result {
Ok(timeline) => {
if let Some(entities) = timeline.entities() {
self.game.set_entity_pool(entities.clone());
}
self.state = GameState::WaitingForAnswer;
let _ = self.game.setup_next_round();
}
Err(error) => {
panic!("{error}");
}
}
}
}
GameState::WaitingForAnswer => {
self.draw_question(ctx, ui, true);
}
GameState::WaitingForNextRound => {
self.draw_question(ctx, ui, false);
ui.separator();
if let Some(last_answer) = self.game.last_answer.as_ref() {
ui.horizontal(|ui| {
ui.label("Last Answer");
open_timeline_gui_core::Label::strong(ui, &format!("{last_answer:?}"));
});
ui.separator();
}
if open_timeline_gui_core::Button::tall_full_width(ui, "End").clicked() {
self.state = GameState::Finished;
}
if open_timeline_gui_core::Button::tall_full_width(ui, "Next Round").clicked() {
let _ = self.game.setup_next_round();
self.state = GameState::WaitingForAnswer;
}
}
GameState::Finished => {
self.draw_new_game_button(ui);
}
}
}
}