use loading::LoadingState;
use wgpu::RenderPass;

use crate::engine::{self, Engine, EngineState, UpdateContext};

mod anm;
mod loading;
mod title;

pub struct Game {
  anm_manager: anm::Manager,
  loading: LoadingState,
}

struct GameInitContext<'a> {
  anm_manager: &'a mut anm::Manager,
  engine: engine::InitContext<'a>,
}

struct GameUpdateContext<'a> {
  engine: &'a UpdateContext<'a>,
  anm_manager: &'a mut anm::Manager,
}

trait GameState {
  fn update(&mut self, _context: &GameUpdateContext) {}
}

impl EngineState for Game {
  fn new(context: crate::engine::InitContext) -> Self
  where
    Self: Sized,
  {
    let mut anm_manager = anm::Manager::new(&context);

    let mut context = GameInitContext {
      anm_manager: &mut anm_manager,
      engine: context,
    };

    Self {
      loading: LoadingState::new(&mut context),
      anm_manager,
    }
  }

  fn update(&mut self, _context: &UpdateContext) {
    self.loading.update(&GameUpdateContext {
      engine: _context,
      anm_manager: &mut self.anm_manager,
    });
    self.anm_manager.update();
  }

  fn render(&self, engine: &crate::engine::Engine, surface: &wgpu::Texture, encoder: &mut wgpu::CommandEncoder) {
    self.anm_manager.render(&engine, surface, encoder)
  }
}
