//! Godot scene type definitions
//!
//! Structures representing Godot .tscn scene format components.

use std::collections::HashMap;

/// Represents a complete Godot scene
#[derive(Debug, Clone)]
pub struct GodotScene {
    pub format_version: u32,
    pub load_steps: u32,
    pub uid: Option<String>,
    pub ext_resources: Vec<ExtResource>,
    pub sub_resources: Vec<SubResource>,
    pub nodes: Vec<SceneNode>,
}

/// External resource (scene, script, texture, etc.)
#[derive(Debug, Clone)]
pub struct ExtResource {
    pub id: String,
    pub resource_type: String,
    pub path: String,
}

/// Sub-resource (embedded in scene)
#[derive(Debug, Clone)]
pub struct SubResource {
    pub id: String,
    pub resource_type: String,
    pub properties: HashMap<String, String>,
}

/// Scene node in hierarchy
#[derive(Debug, Clone)]
pub struct SceneNode {
    pub name: String,
    pub node_type: String,
    pub parent: Option<String>,
    pub instance: Option<String>, // ExtResource ID if instanced
    pub script: Option<String>,   // ExtResource ID if scripted
    pub properties: HashMap<String, String>,
}

impl GodotScene {
    /// Create new empty scene
    pub fn new() -> Self {
        Self {
            format_version: 3,
            load_steps: 1,
            uid: None,
            ext_resources: Vec::new(),
            sub_resources: Vec::new(),
            nodes: Vec::new(),
        }
    }
}

impl SceneNode {
    /// Create new node
    pub fn new(name: &str, node_type: &str) -> Self {
        Self {
            name: name.to_string(),
            node_type: node_type.to_string(),
            parent: None,
            instance: None,
            script: None,
            properties: HashMap::new(),
        }
    }

    /// Create instanced node (from PackedScene)
    pub fn instance(name: &str, ext_resource_id: &str) -> Self {
        Self {
            name: name.to_string(),
            node_type: String::new(), // Type determined by instance
            parent: None,
            instance: Some(ext_resource_id.to_string()),
            script: None,
            properties: HashMap::new(),
        }
    }

    /// Set parent path
    pub fn with_parent(mut self, parent: &str) -> Self {
        self.parent = Some(parent.to_string());
        self
    }

    /// Set property
    pub fn set_property(&mut self, key: &str, value: &str) {
        self.properties.insert(key.to_string(), value.to_string());
    }

    /// Get property
    pub fn get_property(&self, key: &str) -> Option<&String> {
        self.properties.get(key)
    }
}
