#![warn(rust_2018_idioms)]
#![deny(clippy::wildcard_imports)]
#![forbid(elided_lifetimes_in_paths, unsafe_code)]

mod assets {
	include!(env!("ASSETS_RS"));
}

mod activities;
mod game;
mod ui;

use self::{
	activities::{house::HouseState, overworld::worldgen::Overworld, Activity},
	game::Ghost
};
use comfy::{
	etagere::euclid::default, init_game_config, pollster, run_comfy_main_async,
	DevConfig, EngineContext, EngineState, GameConfig, GameLoop, HashMap, IVec2
};

const GAME_NAME: &str = "Powercreep";

#[derive(Debug, Default)]
struct State {
	setup_called: bool,
	activity: Activity,
	ghost: Ghost,
	overworld: Overworld,
	houses: HashMap<IVec2, HouseState>,
	score: f32
}

impl State {
	fn get_house_pos(&self) -> Option<IVec2> {
		match self.activity {
			Activity::House(pos) => Some(pos),
			_ => None
		}
	}

	fn house(&self) -> Option<&HouseState> {
		self.houses.get(&self.get_house_pos()?)
	}

	fn house_mut(&mut self, ctx: &mut EngineContext<'_>) -> &mut HouseState {
		self.houses
			.entry(self.get_house_pos().unwrap())
			.or_insert_with(|| HouseState::generate_new_house(ctx))
	}
}

impl GameLoop for State {
	fn new(_c: &mut EngineState) -> Self {
		Self::default()
	}

	fn update(&mut self, ctx: &mut EngineContext<'_>) {
		if !self.setup_called {
			game::setup(self, ctx);
			self.setup_called = true;
		}

		game::update(self, ctx);
		game::draw(self, ctx);
	}
}

fn config(config: GameConfig) -> GameConfig {
	let dev = DevConfig {
		#[cfg(debug_assertions)]
		show_fps: true,
		..Default::default()
	};
	GameConfig {
		tonemapping_enabled: true,
		dev,
		target_framerate: 165,
		..config
	}
}

async fn run() {
	init_game_config(GAME_NAME.to_string(), env!("CARGO_PKG_VERSION"), config);
	let mut engine = EngineState::new();
	let game = State::new(&mut engine);
	run_comfy_main_async(game, engine).await;
}

fn main() {
	pollster::block_on(run());
}
