use wgpu::BindGroupLayout;
use crate::errors::AleaticoResult;
use crate::renderer::ctx::Gpu;
use crate::renderer::render_item::RenderItemStore;
use crate::renderer::resources::builtin::BuiltinPipelines;
use crate::renderer::resources::material::MaterialStore;
use crate::renderer::resources::mesh::MeshStore;
use crate::renderer::resources::pipelines::PipelineStore;
use crate::renderer::resources::texture::TextureStore;

/// Mesh material
pub mod material;
/// Mesh
pub mod mesh;
/// Rendering pipeline
pub mod pipelines;
/// Texture
pub mod texture;
pub(crate) mod builtin;

/// Storage of all resources possible
#[derive(Default)]
pub(crate) struct ResourceStore {
    /// pipelines storage
    pub(crate) pipeline_store: PipelineStore,
    /// mesh storage
    pub(crate) mesh_store: MeshStore,
    /// material storage
    pub(crate) material_store: MaterialStore,
    /// render item storage
    pub(crate) render_item_store: RenderItemStore,
    /// textures storage
    pub(crate) texture_store: TextureStore,
    pub(crate) builtin_pipelines: BuiltinPipelines
}

impl ResourceStore {
    pub(crate) fn new(
        gpu: &mut Gpu,
        surface_format: wgpu::TextureFormat,
        camera_layout: &BindGroupLayout
    ) -> AleaticoResult<Self> {
        let mut pipeline_store = PipelineStore::new();

        let builtin_pipelines = BuiltinPipelines::create(
            gpu,
            &mut pipeline_store,
            surface_format,
            camera_layout,
        )?;

        Ok(Self {
            pipeline_store,
            mesh_store: MeshStore::new(),
            texture_store: TextureStore::new(),
            material_store: MaterialStore::new(),
            render_item_store: RenderItemStore::new(),
            builtin_pipelines,
        })
    }

    pub(crate) fn builtin_pipelines(&self) -> BuiltinPipelines {
        self.builtin_pipelines
    }
}

