use super::{ComponentInspector, EditorContext};
use nightshade::prelude::*;

pub struct TransformInspector {
    uniform_scaling: bool,
}

impl Default for TransformInspector {
    fn default() -> Self {
        Self {
            uniform_scaling: true,
        }
    }
}

impl ComponentInspector for TransformInspector {
    fn name(&self) -> &str {
        "Transform"
    }

    fn has_component(&self, world: &World, entity: Entity) -> bool {
        world.entity_has_local_transform(entity)
    }

    fn add_component(&self, world: &mut World, entity: Entity) {
        world.set_local_transform(entity, LocalTransform::default());
        world.set_global_transform(entity, GlobalTransform::default());
        mark_local_transform_dirty(world, entity);
    }

    fn remove_component(&self, world: &mut World, entity: Entity) {
        world.remove_local_transform(entity);
        world.remove_global_transform(entity);
    }

    fn ui(
        &mut self,
        world: &mut World,
        entity: Entity,
        ui: &mut egui::Ui,
        _editor: &mut EditorContext,
    ) {
        if let Some(global_transform) = world.get_global_transform(entity) {
            let global_position = global_transform.translation();
            ui.label("Global Position (Read-only):");
            ui.horizontal(|ui| {
                ui.label(format!("X: {:.2}", global_position.x));
                ui.label(format!("Y: {:.2}", global_position.y));
                ui.label(format!("Z: {:.2}", global_position.z));
            });
            ui.separator();
        }

        if let Some(local_transform) = world.get_local_transform_mut(entity) {
            let mut changed = false;

            ui.label("Local Position:");
            ui.horizontal(|ui| {
                ui.label("X:");
                changed |= ui
                    .add(egui::DragValue::new(&mut local_transform.translation.x).speed(0.1))
                    .changed();
                ui.label("Y:");
                changed |= ui
                    .add(egui::DragValue::new(&mut local_transform.translation.y).speed(0.1))
                    .changed();
                ui.label("Z:");
                changed |= ui
                    .add(egui::DragValue::new(&mut local_transform.translation.z).speed(0.1))
                    .changed();
            });

            ui.label("Local Scale:");
            ui.horizontal(|ui| {
                if self.uniform_scaling {
                    ui.label("XYZ:");
                    let mut uniform_scale = local_transform.scale.x;
                    if ui
                        .add(egui::DragValue::new(&mut uniform_scale).speed(0.01))
                        .changed()
                    {
                        local_transform.scale =
                            Vec3::new(uniform_scale, uniform_scale, uniform_scale);
                        changed = true;
                    }
                } else {
                    ui.label("X:");
                    changed |= ui
                        .add(egui::DragValue::new(&mut local_transform.scale.x).speed(0.01))
                        .changed();
                    ui.label("Y:");
                    changed |= ui
                        .add(egui::DragValue::new(&mut local_transform.scale.y).speed(0.01))
                        .changed();
                    ui.label("Z:");
                    changed |= ui
                        .add(egui::DragValue::new(&mut local_transform.scale.z).speed(0.01))
                        .changed();
                }
                ui.checkbox(&mut self.uniform_scaling, "Uniform");
            });

            if changed {
                let _ = local_transform;
                mark_local_transform_dirty(world, entity);
            }
        }
    }
}
