use super::EditorContext;
use super::{
    inspector_animation::*, inspector_camera::*, inspector_light::*, inspector_lines::*,
    inspector_material::*, inspector_mesh::*, inspector_name::*, inspector_navmesh::*,
    inspector_render_layer::*, inspector_script::*, inspector_text::*, inspector_transform::*,
    inspector_water::*,
};
use nightshade::prelude::*;

pub trait ComponentInspector {
    fn name(&self) -> &str;
    fn has_component(&self, world: &World, entity: Entity) -> bool;
    fn add_component(&self, world: &mut World, entity: Entity);
    fn remove_component(&self, world: &mut World, entity: Entity);
    fn ui(
        &mut self,
        world: &mut World,
        entity: Entity,
        ui: &mut egui::Ui,
        editor: &mut EditorContext,
    );
}

pub struct ComponentInspectorUi {
    inspectors: Vec<Box<dyn ComponentInspector>>,
}

impl Default for ComponentInspectorUi {
    fn default() -> Self {
        Self {
            inspectors: vec![
                Box::new(NameInspector),
                Box::new(TransformInspector::default()),
                Box::new(CameraInspector),
                Box::new(LightInspector),
                Box::new(LinesInspector),
                Box::new(MeshInspector),
                Box::new(MaterialInspector::default()),
                Box::new(WaterInspector),
                Box::new(TextInspector),
                Box::new(RenderLayerInspector),
                Box::new(AnimationInspector),
                Box::new(ScriptInspector::default()),
            ],
        }
    }
}

impl ComponentInspectorUi {
    pub fn ui(&mut self, editor: &mut EditorContext, world: &mut World, ui: &mut egui::Ui) {
        if let Some(entity) = editor.selected_entity {
            ui.group(|ui| {
                ui.horizontal(|ui| {
                    ui.label("Add Component:");
                    egui::ComboBox::new("add_component", "").show_ui(ui, |ui| {
                        for inspector in self.inspectors.iter() {
                            if !inspector.has_component(world, entity)
                                && ui.button(inspector.name()).clicked()
                            {
                                inspector.add_component(world, entity);
                            }
                        }
                    });
                });
            });

            ui.separator();

            for inspector in self.inspectors.iter_mut() {
                if inspector.has_component(world, entity) {
                    ui.group(|ui| {
                        inspector.ui(world, entity, ui, editor);
                        if ui.button("Remove Component").clicked() {
                            inspector.remove_component(world, entity);
                        }
                    });
                    ui.separator();
                }
            }

            navmesh_section_ui(editor, world, ui);
            colliders_section_ui(editor, world, ui);
        } else {
            ui.vertical_centered(|ui| {
                ui.add_space(8.0);
                ui.label(
                    egui::RichText::new("No entity selected").color(egui::Color32::from_gray(128)),
                );
                ui.add_space(8.0);
            });
        }
    }
}
