mod asset_browser;
mod camera;
#[cfg(not(target_arch = "wasm32"))]
mod chat;
mod materials;
mod scene_browser;
mod web;

pub use asset_browser::*;
pub use camera::*;
#[cfg(not(target_arch = "wasm32"))]
pub use chat::*;
pub use materials::*;
pub use scene_browser::*;
pub use web::*;

use crate::mosaic::{Widget, WidgetContext, WidgetEntry};
use nightshade::prelude::serde::{Deserialize, Serialize};
use nightshade::prelude::*;

pub fn sorted_camera_entities(world: &World) -> Vec<Entity> {
    let mut cameras: Vec<Entity> = world.core.query_entities(CAMERA).collect();
    cameras.sort_by_key(|entity| entity.id);
    cameras
}

use crate::app_context::AppContext;
use crate::messages::EditorMessage;

#[derive(Clone, Serialize, Deserialize)]
#[serde(crate = "nightshade::prelude::serde")]
pub enum EditorWidget {
    Camera(CameraWidget),
    Materials(MaterialsWidget),
    Web(WebWidget),
    AssetBrowser(AssetBrowserWidget),
    SceneBrowser(SceneBrowserWidget),
    #[cfg(not(target_arch = "wasm32"))]
    Chat(ChatWidget),
}

impl Widget<AppContext, EditorMessage> for EditorWidget {
    fn title(&self) -> String {
        match self {
            EditorWidget::Camera(widget) => format!("Camera {}", widget.camera_index + 1),
            EditorWidget::Materials(_) => "Materials".to_string(),
            EditorWidget::Web(_) => "Web".to_string(),
            EditorWidget::AssetBrowser(_) => "Asset Browser".to_string(),
            EditorWidget::SceneBrowser(_) => "Scene Browser".to_string(),
            #[cfg(not(target_arch = "wasm32"))]
            EditorWidget::Chat(_) => "Chat".to_string(),
        }
    }

    fn ui(&mut self, ui: &mut egui::Ui, context: &mut WidgetContext<AppContext, EditorMessage>) {
        match self {
            EditorWidget::Camera(widget) => widget.render(ui, context),
            EditorWidget::Materials(widget) => widget.render(ui, context),
            EditorWidget::Web(widget) => widget.render(ui, context),
            EditorWidget::AssetBrowser(widget) => widget.render(ui, context),
            EditorWidget::SceneBrowser(widget) => widget.render(ui, context),
            #[cfg(not(target_arch = "wasm32"))]
            EditorWidget::Chat(widget) => widget.render(ui, context),
        }
    }

    fn required_camera(&self, cached_cameras: &[Entity]) -> Option<Entity> {
        match self {
            EditorWidget::Camera(widget) => cached_cameras.get(widget.camera_index).copied(),
            _ => None,
        }
    }

    fn catalog() -> Vec<WidgetEntry<Self>> {
        #[cfg_attr(target_arch = "wasm32", allow(unused_mut))]
        let mut entries = vec![
            WidgetEntry {
                name: "Camera".to_string(),
                create: || EditorWidget::Camera(CameraWidget::default()),
            },
            WidgetEntry {
                name: "Materials".to_string(),
                create: || EditorWidget::Materials(MaterialsWidget::default()),
            },
            WidgetEntry {
                name: "Web".to_string(),
                create: || EditorWidget::Web(WebWidget::default()),
            },
            WidgetEntry {
                name: "Asset Browser".to_string(),
                create: || EditorWidget::AssetBrowser(AssetBrowserWidget::default()),
            },
            WidgetEntry {
                name: "Scene Browser".to_string(),
                create: || EditorWidget::SceneBrowser(SceneBrowserWidget::default()),
            },
        ];

        #[cfg(not(target_arch = "wasm32"))]
        entries.push(WidgetEntry {
            name: "Chat".to_string(),
            create: || EditorWidget::Chat(ChatWidget::default()),
        });

        entries
    }
}
