/*
Trouble in Terror Town: Community Edition
Copyright (C) 2024 Mikolaj Wojciech Gorski

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#![allow(clippy::type_complexity)]

#[cfg(debug_assertions)]
use bevy::diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin};
use bevy::prelude::*;
use bevy_editor_pls::prelude::*;
use bevy_xpbd_3d::prelude::*;
mod charcacter_controller;
use charcacter_controller::*;

pub struct GamePlugin;

impl Plugin for GamePlugin {
    fn build(&self, app: &mut App) {
        app.add_plugins((PhysicsPlugins::default(), CharacterControllerPlugin))
            .add_systems(Startup, setup)
            .add_systems(Update, spawn_map);

        #[cfg(debug_assertions)]
        {
            app.add_plugins((
                FrameTimeDiagnosticsPlugin,
                EditorPlugin::default(),
                LogDiagnosticsPlugin::default(),
            ));
        }

        app.world.init_resource::<IsMapSpawned>();
    }
}

#[derive(Resource, Default, Debug)]
struct IsMapSpawned(bool);

/// set up a simple 3D scene
fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    //player
    commands.spawn((
        CharacterControllerBundle::new(Collider::capsule(1.0, 0.5), CharacterController::default()),
        PbrBundle {
            mesh: meshes.add(Capsule3d::new(0.5, 1.0)),
            material: materials.add(Color::rgb_u8(124, 144, 255)),
            transform: Transform::from_xyz(0.0, 5.0, 0.0),
            ..default()
        },
    ));
    // light
    commands.spawn(PointLightBundle {
        point_light: PointLight {
            shadows_enabled: true,
            ..default()
        },
        transform: Transform::from_xyz(4.0, 8.0, 4.0),
        ..default()
    });
    // camera
    commands.spawn(Camera3dBundle {
        transform: Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
        ..default()
    });
}

fn spawn_map(
    asset_server: Res<AssetServer>,
    mut is_map_spawned: ResMut<IsMapSpawned>,
    mut commands: Commands,
) {
    if is_map_spawned.0 {
        return;
    }

    let scene = asset_server.load("test_map.gltf#Scene0");

    commands.spawn((
        SceneBundle {
            scene: scene.clone(),
            transform: Transform::from_xyz(0.0, 0.0, 0.0),
            ..default()
        },
        AsyncSceneCollider::new(Some(ComputedCollider::TriMesh)),
        RigidBody::Static,
    ));

    println!("map spawned!");

    is_map_spawned.0 = true
}
