use crate::utils::{FileLoc, ParameterDictionary};
use shared::core::camera::CameraTransform;
use shared::utils::{AnimatedTransform, Transform};
use std::sync::Arc;

#[derive(Clone, Debug)]
pub enum MaterialRef {
    Index(usize),
    Name(String),
    None,
}

#[derive(Clone, Default, Debug)]
pub struct SceneEntity {
    pub name: String,
    pub loc: FileLoc,
    pub parameters: ParameterDictionary,
}

#[derive(Clone, Debug)]
pub struct TransformedSceneEntity {
    pub base: SceneEntity,
    pub render_from_object: AnimatedTransform,
}

pub type MediumSceneEntity = TransformedSceneEntity;
pub type TextureSceneEntity = TransformedSceneEntity;

#[derive(Clone, Debug)]
pub struct CameraSceneEntity {
    pub base: SceneEntity,
    pub camera_transform: CameraTransform,
    pub medium: String,
}

#[derive(Clone, Debug)]
pub struct ShapeSceneEntity {
    pub base: SceneEntity,
    pub render_from_object: Arc<Transform>,
    pub object_from_render: Arc<Transform>,
    pub reverse_orientation: bool,
    pub material: MaterialRef,
    pub light_index: Option<usize>,

    pub inside_medium: String,
    pub outside_medium: String,
}

#[derive(Clone, Debug)]
pub struct AnimatedShapeSceneEntity {
    pub transformed_base: TransformedSceneEntity,

    pub identity: Arc<Transform>,
    pub reverse_orientation: bool,
    pub material: MaterialRef,
    pub light_index: Option<usize>,
    pub inside_medium: String,
    pub outside_medium: String,
}

#[derive(Clone, Debug)]
pub struct InstanceDefinitionSceneEntity {
    pub name: String,
    pub loc: FileLoc,
    pub shapes: Vec<ShapeSceneEntity>,
    pub animated_shapes: Vec<AnimatedShapeSceneEntity>,
}

#[derive(Clone, Debug)]
pub struct LightSceneEntity {
    pub transformed_base: TransformedSceneEntity,
    pub medium: String,
}

#[derive(Clone, Debug)]
pub enum InstanceTransform {
    Animated(AnimatedTransform),
    Static(Arc<Transform>),
}

#[derive(Clone, Debug)]
pub struct InstanceSceneEntity {
    pub name: String,
    pub loc: FileLoc,
    pub transform: InstanceTransform,
}
