#ifndef SCENE_H
#define SCENE_H

#include "stddef.h"
#include "scene_node_entity.h"
#include "utils/list.h"
#include "utils/typeclass_helpers.h"
typedef struct SceneNodeEntity SceneNodeEntity;
typedef struct Transformable Transformable;
typedef struct CameraNode CameraNode;

typedef struct Scene Scene;
typedef struct SceneNode SceneNode;

struct SceneNode {
    SceneNode *parent; //!< The parent of this node in a scene hierarchy, or NULL if this is the root node.
    Scene *scene; //!< The scene this node is a part of
    List children; //!< list of child SceneNodes
    SceneNodeEntity entity; //!< scene node entity that defines the functionality for this node. HAS TO be defined before adding to a scene.
};

struct Scene {
    SceneNode *root; //!< The root node of this scene.
    List nodes; //!< An unordered list of all nodes in the hierarchy.
    CameraNode *main_camera; //!< The current main camera node
};

//! Instantiate a new scene node.
extern SceneNode *CreateSceneNode(SceneNodeEntity entity);
//! Recursively destroy a scene node and all children, starting from the bottom.
extern void DestroySceneNode(SceneNode *self);
//! Get a child from a scene node.
extern SceneNode *SceneNodeGetChild(SceneNode *self, size_t idx);
//! Attach a child to a node
extern void SceneNodeAddChild(SceneNode *self, SceneNode *child);
//! Detach a child from a node, removing it from the scene
extern void SceneNodeRemoveChild(SceneNode *self, SceneNode *child);

//! Attach an entity to a scene node
extern void SceneNodeAttachEntity(SceneNode *self, SceneNodeEntity entity);
//! Detach an entity from a scene node
extern SceneNodeEntity SceneNodeDetachEntity(SceneNode *self);

//! Instantiate a new scene with a root node.
extern Scene *CreateScene(SceneNode *root);
//! Destroy a node and it's scene tree.
extern void DestroyScene(Scene *self);
//! Tick a scene and all entities
extern void SceneTick(Scene *self, double delta_time);

#endif // !SCENE_H
