use super::{LightSceneEntity, SceneEntity, TextureSceneEntity};
use crate::core::image::Image;
use crate::core::texture::{FloatTexture, SpectrumTexture};
use crate::utils::parallel::AsyncJob;
use anyhow::Result;
use shared::core::medium::Medium;
use std::collections::{HashMap, HashSet};
use std::sync::Arc;

#[derive(Debug, Default)]
pub struct TextureState {
    pub serial_float_textures: Vec<(String, TextureSceneEntity)>,
    pub serial_spectrum_textures: Vec<(String, TextureSceneEntity)>,
    pub async_spectrum_textures: Vec<(String, TextureSceneEntity)>,
    pub loading_texture_filenames: HashSet<String>,
    pub float_texture_jobs: HashMap<String, AsyncJob<Arc<FloatTexture>>>,
    pub spectrum_texture_jobs: HashMap<String, AsyncJob<Arc<SpectrumTexture>>>,
    pub n_missing_textures: usize,
}

#[derive(Debug, Default)]
pub struct MaterialState {
    pub named_materials: Vec<(String, SceneEntity)>,
    pub materials: Vec<SceneEntity>,
    pub normal_map_jobs: HashMap<String, AsyncJob<Arc<Image>>>,
    pub normal_maps: HashMap<String, Arc<Image>>,
}

#[derive(Debug, Default)]
pub struct LightState {
    pub lights: Vec<LightSceneEntity>,
    pub area_lights: Vec<SceneEntity>,
}

#[derive(Debug, Default)]
pub struct MediaState {
    pub jobs: HashMap<String, AsyncJob<Medium>>,
    pub map: HashMap<String, Arc<Medium>>,
}

#[derive(Debug)]
pub struct SingletonState<T> {
    pub result: Option<Arc<T>>,
    pub job: Option<AsyncJob<Result<T>>>,
}

impl<T> Default for SingletonState<T> {
    fn default() -> Self {
        Self {
            result: None,
            job: None,
        }
    }
}
