-- =============================================================================
-- Component Lua API Examples
-- =============================================================================
-- This file demonstrates how to add, remove, query, and manipulate ECS
-- components from Lua using the ecs.* Lua API.
--
-- Components are data attached to entities. They define what an entity IS
-- and what it CAN DO. For example, a Transform component gives an entity
-- a position in the world, while a Renderable component makes it visible.
-- =============================================================================

-- =============================================================================
-- Checking for Components
-- =============================================================================

-- Create an entity and check what components it has:
local entity = ecs.create_entity()
ecs.set_entity_name(entity, "TestObject")

-- Check if an entity has a specific component:
if ecs.has_component(entity, "Transform") then
    print("Entity has Transform component")
end

-- New entities typically have EditorMarker by default:
if ecs.has_component(entity, "EditorMarker") then
    print("Entity has EditorMarker (default for new entities)")
end

-- =============================================================================
-- Adding and Removing Components
-- =============================================================================

-- Add a tag component (a component with no data):
ecs.add_component(entity, "InWater")
print("Added InWater tag")

-- Check it was added:
if ecs.has_component(entity, "InWater") then
    print("Entity is now in water")
end

-- Remove a tag component:
ecs.remove_component(entity, "InWater")
if not ecs.has_component(entity, "InWater") then
    print("Entity is no longer in water")
end

-- =============================================================================
-- Setting and Getting Components with Data
-- =============================================================================

-- Set a component with data (creates or replaces it):
ecs.set_component(entity, "Transform", {
    position = { 10, 20, 30 },
    rotation = { 1, 0, 0, 0 },  -- quaternion w, x, y, z
    scale = { 2, 2, 2 }
})

-- Get the component back:
local transform = ecs.get_component(entity, "Transform")
if transform then
    print("Position: " .. transform.position[1] .. ", "
                .. transform.position[2] .. ", "
                .. transform.position[3])
    print("Scale: " .. transform.scale[1] .. ", "
                .. transform.scale[2] .. ", "
                .. transform.scale[3])
end

-- =============================================================================
-- Individual Field Access
-- =============================================================================

-- Get a single field from a component:
local pos_x = ecs.get_field(entity, "Transform", "position")
print("Position X from get_field: " .. pos_x[1])

-- Set a single field:
ecs.set_field(entity, "Transform", "position", { 0, 0, 0 })
local new_pos = ecs.get_field(entity, "Transform", "position")
print("New position: " .. new_pos[1] .. ", " .. new_pos[2] .. ", " .. new_pos[3])

-- =============================================================================
-- Practical Examples: Common Components
-- =============================================================================

-- Create a player character:
function create_player(name, x, y, z)
    local player = ecs.create_entity()
    ecs.set_entity_name(player, name)

    -- Transform (position in the world):
    ecs.set_component(player, "Transform", {
        position = { x, y, z },
        rotation = { 1, 0, 0, 0 },
        scale = { 1, 1, 1 }
    })

    -- Renderable (visible mesh):
    ecs.set_component(player, "Renderable", {
        meshName = "character.mesh",
        visible = true
    })

    -- Character (physics capsule for movement):
    ecs.set_component(player, "Character", {
        radius = 0.4,
        height = 1.8,
        offset = { 0, 0.9, 0 },
        enabled = true,
        useGravity = true
    })

    -- PlayerController (camera and input):
    ecs.set_component(player, "PlayerController", {
        cameraMode = 1,
        tpsDistance = 5.0,
        tpsHeight = 2.0,
        mouseSensitivity = 0.5
    })

    -- Inventory:
    ecs.set_component(player, "Inventory", {
        maxSlots = 20,
        maxWeight = 50.0,
        isContainer = true
    })

    print("Created player: " .. name)
    return player
end

local hero = create_player("Hero", 0, 0, 0)

-- Create a light source:
function create_light(name, x, y, z, light_type)
    local light = ecs.create_entity()
    ecs.set_entity_name(light, name)

    ecs.set_component(light, "Transform", {
        position = { x, y, z },
        rotation = { 1, 0, 0, 0 },
        scale = { 1, 1, 1 }
    })

    ecs.set_component(light, "Light", {
        lightType = light_type or 0,  -- 0=point, 1=directional, 2=spot
        diffuseColor = { 1, 1, 1, 1 },
        intensity = 1.5,
        range = 100,
        castShadows = true
    })

    print("Created light: " .. name)
    return light
end

local sun = create_light("Sun", 0, 100, 0, 1)  -- directional light

-- Create a building with smart object interaction:
function create_building(name, x, z)
    local building = ecs.create_entity()
    ecs.set_entity_name(building, name)

    ecs.set_component(building, "Transform", {
        position = { x, 0, z },
        rotation = { 1, 0, 0, 0 },
        scale = { 1, 1, 1 }
    })

    ecs.set_component(building, "Renderable", {
        meshName = "building.mesh",
        visible = true
    })

    ecs.set_component(building, "SmartObject", {
        radius = 2.0,
        height = 3.0,
        actionNames = { "enter", "exit" }
    })

    -- RigidBody for physics:
    ecs.set_component(building, "RigidBody", {
        bodyType = 0,  -- 0=static
        mass = 0,
        friction = 0.5,
        restitution = 0.1,
        enabled = true
    })

    print("Created building: " .. name)
    return building
end

local house = create_building("House", 10, 10)

-- Create an item:
function create_item(name, item_id, x, y, z)
    local item = ecs.create_entity()
    ecs.set_entity_name(item, name)

    ecs.set_component(item, "Transform", {
        position = { x, y, z },
        rotation = { 1, 0, 0, 0 },
        scale = { 0.5, 0.5, 0.5 }
    })

    ecs.set_component(item, "Renderable", {
        meshName = "potion.mesh",
        visible = true
    })

    ecs.set_component(item, "Item", {
        itemName = name,
        itemType = "consumable",
        itemId = item_id,
        stackSize = 1,
        maxStackSize = 10,
        weight = 0.5,
        value = 50,
        useActionName = "drink_potion"
    })

    print("Created item: " .. name)
    return item
end

local potion = create_item("Health Potion", "potion_health", 5, 0.5, 5)

-- Create a NavMesh area:
function create_navmesh_area(name)
    local nav = ecs.create_entity()
    ecs.set_entity_name(nav, name)

    ecs.set_component(nav, "NavMesh", {
        cellSize = 0.3,
        cellHeight = 0.2,
        agentHeight = 2.0,
        agentRadius = 0.5,
        agentMaxClimb = 0.5,
        agentMaxSlope = 45.0,
        enabled = true
    })

    print("Created NavMesh: " .. name)
    return nav
end

local navmesh = create_navmesh_area("MainNavMesh")

-- =============================================================================
-- Working with Tag Components
-- =============================================================================

-- Tag components are boolean markers with no data fields.
-- Common tags include:
--   EditorMarker     - marks entities visible in the editor
--   InWater          - entity is currently in water
--   GeneratedPhysicsTag - physics was auto-generated
--   ParentComponent  - entity is a parent in a hierarchy
--   NavMeshGeometrySource - entity contributes to navmesh generation

-- Example: Mark entities for different purposes:
local marker1 = ecs.create_entity()
ecs.add_component(marker1, "GeneratedPhysicsTag")

local marker2 = ecs.create_entity()
ecs.add_component(marker2, "NavMeshGeometrySource")

-- =============================================================================
-- Working with GOAP Components
-- =============================================================================

-- Create an NPC with GOAP AI:
function create_npc(name, x, z)
    local npc = ecs.create_entity()
    ecs.set_entity_name(npc, name)

    ecs.set_component(npc, "Transform", {
        position = { x, 0, z },
        rotation = { 1, 0, 0, 0 },
        scale = { 1, 1, 1 }
    })

    ecs.set_component(npc, "Character", {
        radius = 0.4,
        height = 1.8,
        offset = { 0, 0.9, 0 },
        enabled = true,
        useGravity = true
    })

    -- GOAP blackboard (character's knowledge about the world):
    ecs.set_component(npc, "GoapBlackboard", {
        values = {
            health = 100,
            stamina = 100,
            hunger = 0,
            wood_count = 0
        },
        floatValues = {
            hunger = 0.0
        },
        stringValues = {
            state = "idle"
        }
    })

    -- GOAP planner (plans actions to achieve goals):
    ecs.set_component(npc, "GoapPlanner", {
        enabled = true,
        maxIterations = 100
    })

    -- GOAP runner (executes the plan):
    ecs.set_component(npc, "GoapRunner", {
        enabled = true,
        currentAction = "idle"
    })

    -- Behavior tree for idle behavior:
    ecs.set_component(npc, "BehaviorTree", {
        treeName = "idle_behavior",
        enabled = true
    })

    -- Path following for movement:
    ecs.set_component(npc, "PathFollowing", {
        enabled = true,
        speed = 1.5
    })

    -- NavMesh agent for navigation:
    ecs.set_component(npc, "NavMeshAgent", {
        enabled = true,
        radius = 0.5,
        height = 2.0
    })

    print("Created NPC: " .. name)
    return npc
end

local npc = create_npc("Villager_01", -10, -10)

-- =============================================================================
-- Working with Event Handler Components
-- =============================================================================

-- Add event handlers to entities:
ecs.set_component(npc, "EventHandler", {
    eventName = "collision",
    actionName = "handle_collision",
    enabled = true
})

-- =============================================================================
-- Working with Dialogue Components
-- =============================================================================

-- Add dialogue to an NPC:
ecs.set_component(npc, "Dialogue", {
    text = "Hello there, traveler!",
    speaker = "Villager_01",
    enabled = true
})

-- =============================================================================
-- Working with Water Components
-- =============================================================================

-- Create a water plane:
function create_water(name, y)
    local water = ecs.create_entity()
    ecs.set_entity_name(water, name)

    ecs.set_component(water, "WaterPlane", {
        enabled = true,
        waterSurfaceY = y or 0.0,
        planeSize = 1000,
        reflectivity = 0.5,
        waveSpeed = 1.0
    })

    ecs.set_component(water, "WaterPhysics", {
        enabled = true,
        waveHeight = 0.5
    })

    print("Created water: " .. name)
    return water
end

local ocean = create_water("Ocean", 0.0)

-- =============================================================================
-- Working with Sky and Sun Components
-- =============================================================================

-- Create a skybox:
function create_sky(name)
    local sky = ecs.create_entity()
    ecs.set_entity_name(sky, name)

    ecs.set_component(sky, "Skybox", {
        enabled = true,
        size = 500,
        starsEnabled = true
    })

    print("Created sky: " .. name)
    return sky
end

local skybox = create_sky("Skybox")

-- Update sun properties:
ecs.set_component(sun, "Sun", {
    enabled = true,
    timeOfDay = 12.0,
    timeSpeed = 1.0,
    intensity = 1.0,
    castShadows = true
})

-- =============================================================================
-- Working with Camera Components
-- =============================================================================

-- Create a camera:
function create_camera(name)
    local cam = ecs.create_entity()
    ecs.set_entity_name(cam, name)

    ecs.set_component(cam, "Camera", {
        fovY = 60,
        nearClip = 0.1,
        farClip = 1000,
        orthographic = false
    })

    print("Created camera: " .. name)
    return cam
end

local camera = create_camera("MainCamera")

-- =============================================================================
-- Working with Prefab Components
-- =============================================================================

-- Mark an entity as a prefab instance:
ecs.set_component(house, "PrefabInstance", {
    prefabPath = "prefabs/house.json",
    instantiated = true
})

-- =============================================================================
-- Working with CellGrid Components
-- =============================================================================

-- Create a cell grid for spatial partitioning:
function create_cell_grid(name, width, height, depth)
    local grid = ecs.create_entity()
    ecs.set_entity_name(grid, name)

    ecs.set_component(grid, "CellGrid", {
        width = width or 10,
        height = height or 5,
        depth = depth or 10,
        cellSize = 1.0,
        cellHeight = 0.5
    })

    print("Created cell grid: " .. name)
    return grid
end

local grid = create_cell_grid("WorldGrid", 20, 10, 20)

-- =============================================================================
-- Working with Town/District/Lot/Room Components
-- =============================================================================

-- Create a town with districts, lots, and rooms:
function create_town(name)
    local town = ecs.create_entity()
    ecs.set_entity_name(town, name)

    ecs.set_component(town, "Town", {
        townName = name,
        population = 500
    })

    -- Create a district:
    local district = ecs.create_entity()
    ecs.set_entity_name(district, "Market District")
    ecs.set_component(district, "District", {
        districtName = "Market District",
        districtType = "commercial"
    })

    -- Create a lot:
    local lot = ecs.create_entity()
    ecs.set_entity_name(lot, "Residential Lot 1")
    ecs.set_component(lot, "Lot", {
        lotName = "Residential Lot 1",
        lotType = "residential",
        width = 20,
        depth = 30
    })

    -- Create a room:
    local room = ecs.create_entity()
    ecs.set_entity_name(room, "Kitchen")
    ecs.set_component(room, "Room", {
        roomName = "Kitchen",
        roomType = "kitchen",
        floor = 0
    })

    print("Created town: " .. name)
    return town
end

local rivendell = create_town("Rivendell")

-- =============================================================================
-- Working with Furniture Components
-- =============================================================================

-- Create a furniture template:
function create_furniture(name, mesh, category)
    local furniture = ecs.create_entity()
    ecs.set_entity_name(furniture, name)

    ecs.set_component(furniture, "FurnitureTemplate", {
        templateName = name,
        meshName = mesh or "chair.mesh",
        category = category or "seating"
    })

    print("Created furniture: " .. name)
    return furniture
end

local chair = create_furniture("Wooden Chair", "chair.mesh", "seating")

-- =============================================================================
-- Working with Animation Components
-- =============================================================================

-- Add animation tree to a character:
ecs.set_component(npc, "AnimationTree", {
    treeName = "humanoid",
    enabled = true
})

ecs.set_component(npc, "AnimationTreeTemplate", {
    templateName = "humanoid_base",
    blendTime = 0.2
})

-- =============================================================================
-- Working with Physics Components
-- =============================================================================

-- Add a physics collider to an entity:
ecs.set_component(house, "PhysicsCollider", {
    shapeType = "box",
    size = { 5, 3, 5 },
    enabled = true
})

-- Add buoyancy info for water physics:
ecs.set_component(house, "BuoyancyInfo", {
    enabled = true,
    buoyancy = 1.0,
    linearDrag = 0.5,
    angularDrag = 0.3
})

-- =============================================================================
-- Working with LOD Components
-- =============================================================================

-- Add LOD settings:
ecs.set_component(entity, "Lod", {
    lodLevel = 0,
    distance = 100.0
})

ecs.set_component(entity, "LodSettings", {
    enabled = true,
    lodBias = 1.0
})

-- =============================================================================
-- Working with Static Geometry Components
-- =============================================================================

-- Batch entities into static geometry:
ecs.set_component(entity, "StaticGeometry", {
    batchName = "forest_batch",
    enabled = true
})

ecs.set_component(entity, "StaticGeometryMember", {
    parentBatch = "forest_batch",
    enabled = true
})

-- =============================================================================
-- Working with Procedural Components
-- =============================================================================

-- Create procedural textures and materials:
ecs.set_component(entity, "ProceduralTexture", {
    textureName = "grass",
    width = 512,
    height = 512
})

ecs.set_component(entity, "ProceduralMaterial", {
    materialName = "ground_mat",
    baseColor = { 0.5, 0.5, 0.5, 1.0 }
})

-- =============================================================================
-- Working with Primitive Components
-- =============================================================================

-- Create a primitive shape:
ecs.set_component(entity, "Primitive", {
    primitiveType = "box",
    size = { 1, 2, 1 }
})

-- =============================================================================
-- Working with Triangle Buffer Components
-- =============================================================================

ecs.set_component(entity, "TriangleBuffer", {
    enabled = true,
    vertexCount = 100
})

-- =============================================================================
-- Working with Character Slots
-- =============================================================================

ecs.set_component(entity, "CharacterSlots", {
    slotCount = 8
})

-- =============================================================================
-- Working with Roof Components
-- =============================================================================

ecs.set_component(entity, "Roof", {
    roofType = "gable",
    height = 2.5,
    enabled = true
})

-- =============================================================================
-- Working with ClearArea Components
-- =============================================================================

ecs.set_component(entity, "ClearArea", {
    radius = 5.0,
    enabled = true
})

-- =============================================================================
-- Working with Action Database Components
-- =============================================================================

ecs.set_component(entity, "ActionDatabase", {
    enabled = true
})

ecs.set_component(entity, "ActionDebug", {
    enabled = true,
    showDebugInfo = true
})

-- =============================================================================
-- Working with Startup Menu Components
-- =============================================================================

ecs.set_component(entity, "StartupMenu", {
    enabled = true,
    showOnStart = true
})

-- =============================================================================
-- Component Lifecycle Summary
-- =============================================================================

-- Components can be:
-- 1. Added:   ecs.add_component(entity, "ComponentName")
-- 2. Removed: ecs.remove_component(entity, "ComponentName")
-- 3. Checked: ecs.has_component(entity, "ComponentName")
-- 4. Get:     ecs.get_component(entity, "ComponentName")
-- 5. Set:     ecs.set_component(entity, "ComponentName", { fields... })
-- 6. Field:   ecs.get_field(entity, "ComponentName", "fieldName")
-- 7. Field:   ecs.set_field(entity, "ComponentName", "fieldName", value)

print("Component API examples completed successfully!")
