use bevy::camera::ScalingMode;
use bevy::prelude::*;
use micro_banimate::definitions::{create_directional_animation, AnimationSet, AnimationStatus};
use micro_banimate::directionality::{Directionality, Horizontal};

fn main() {
	App::new()
		.add_plugins(DefaultPlugins)
		.add_plugins(micro_banimate::BanimatePluginGroup)
		.add_systems(Startup, load_assets)
		.add_systems(PostStartup, spawn_assets)
		.add_systems(Update, process_input)
		.run();
}

#[derive(Default, Resource)]
struct ExampleAssets {
	atlas: Handle<TextureAtlasLayout>,
	sprites: Handle<Image>,
	animations: Handle<AnimationSet>,
}

fn load_assets(
	mut commands: Commands,
	assets: Res<AssetServer>,
	mut atlas: ResMut<Assets<TextureAtlasLayout>>,
) {
	let sprites = assets.load("character.png");
	let atlas = atlas.add(TextureAtlasLayout::from_grid(
		UVec2::new(48, 48),
		10,
		6,
		None,
		None,
	));
	let anim_handle = assets.load("character.anim.json");

	commands.insert_resource(ExampleAssets {
		sprites,
		atlas,
		animations: anim_handle,
	});
}

fn spawn_assets(mut commands: Commands, assets: Res<ExampleAssets>) {
	const WIDTH: f32 = 480.0;
	const HEIGHT: f32 = 320.0;

	commands.spawn((
		Sprite::from_atlas_image(
			assets.sprites.clone(),
			TextureAtlas {
				layout: assets.atlas.clone(),
				index: 0,
			},
		),
		create_directional_animation(assets.animations.clone(), "idle"),
		Directionality::Right,
	));

	commands.spawn((
		Camera2d::default(),
		Projection::Orthographic(OrthographicProjection {
			area: Rect::new(-(WIDTH / 2.0), -(HEIGHT / 2.0), WIDTH / 2.0, HEIGHT / 2.0),
			scaling_mode: ScalingMode::AutoMin {
				min_height: HEIGHT,
				min_width: WIDTH,
			},
			far: 1000.,
			near: -1000.,
			..OrthographicProjection::default_2d()
		}),
	));
}

fn process_input(
	input: Res<ButtonInput<KeyCode>>,
	mut status_query: Query<(&mut AnimationStatus, &mut Directionality)>,
) {
	for (mut status, mut direction) in &mut status_query {
		if input.just_released(KeyCode::ArrowLeft) {
			direction.with_horizontal(Horizontal::Left);
		}

		if input.just_released(KeyCode::ArrowRight) {
			direction.with_horizontal(Horizontal::Right);
		}

		if input.just_released(KeyCode::Digit1) {
			status.start_or_continue("idle");
		}

		if input.just_released(KeyCode::Digit2) {
			status.start_or_continue("run");
		}
	}
}
