#ifndef _EVAS_3D_NODE_EO_H_
#define _EVAS_3D_NODE_EO_H_

#ifndef _EVAS_3D_NODE_EO_CLASS_TYPE
#define _EVAS_3D_NODE_EO_CLASS_TYPE

typedef Eo Evas_3D_Node;

#endif

#ifndef _EVAS_3D_NODE_EO_TYPES
#define _EVAS_3D_NODE_EO_TYPES


#endif
#define EVAS_3D_NODE_CLASS evas_3d_node_class_get()

const Eo_Class *evas_3d_node_class_get(void) EINA_CONST;

/**
 *
 * Set the position inheritance flag of the given node.
 *
 * @param node    The given node.
 * @param inherit Whether to inherit parent position @c EINA_TRUE or not @c EINA_FALSE.
 *
 * When inheritance is enabled, a node's world space position is determined by
 * adding the parent node's world position and the node's position, otherwise,
 * the node's position will be the world space position.
 *
 * @ingroup Evas_3D_Node_Transform
 *
 * @param[in] inherit Whether to inherit parent position
 *
 */
EOAPI void  evas_3d_node_position_inherit_set(Eina_Bool inherit);

/**
 *
 * Get the position inheritance flag of the given node.
 *
 * @param node    The given node.
 * @return        @c EINA_TRUE if inheritance is enabled, or @c EINA_FALSE if not.
 *
 * @see evas_3d_node_position_inherit_set()
 *
 * @ingroup Evas_3D_Node_Transform
 *
 *
 */
EOAPI Eina_Bool  evas_3d_node_position_inherit_get(void);

/**
 *
 * Set the orientation inheritance flag of the given node.
 *
 * @param node    The given node.
 * @param inherit Whether to inherit parent orientation @c EINA_TRUE or not @c EINA_FALSE.
 *
 * When inheritance is enabled, a node's world space orientation is determined
 * by multiplying the parent node's world orientation and the node's
 * orientation, otherwise, the node's orientation will be the world space
 * orientation.
 *
 * @ingroup Evas_3D_Node_Transform
 *
 * @param[in] inherit Whether to inherit parent orientation
 *
 */
EOAPI void  evas_3d_node_orientation_inherit_set(Eina_Bool inherit);

/**
 *
 * Get the orientation inheritance flag of the given node.
 *
 * @param node    The given node.
 * @return        @c EINA_TRUE if inheritance is enabled, or @c EINA_FALSE if not.
 *
 * @see evas_3d_node_orientation_inherit_set()
 *
 * @ingroup Evas_3D_Node_Transform
 *
 *
 */
EOAPI Eina_Bool  evas_3d_node_orientation_inherit_get(void);

/**
 *
 * Set the scale inheritance flag of the given node.
 *
 * @param node    The given node.
 * @param inherit Whether to inherit parent scale @c EINA_TRUE or not @c EINA_FALSE.
 *
 * When inheritance is enabled, a node's world space scale is determined by
 * multiplying the parent node's world scale and the node's scale, otherwise,
 * the node's scale will be the world space scale.
 *
 * @ingroup Evas_3D_Node_Transform
 *
 * @param[in] inherit Whether to inherit parent scale
 *
 */
EOAPI void  evas_3d_node_scale_inherit_set(Eina_Bool inherit);

/**
 *
 * Get the scale inheritance flag of the given node.
 *
 * @param node    The given node.
 * @return        @c EINA_TRUE if inheritance is enabled, or @c EINA_FALSE if not.
 *
 * @see evas_3d_node_scale_inherit_set()
 *
 * @ingroup Evas_3D_Node_Transform
 *
 *
 */
EOAPI Eina_Bool  evas_3d_node_scale_inherit_get(void);

/**
 *
 * Set a camera to the given node.
 *
 * @param node          The given node.
 * @param camera        The camera to be set.
 *
 * If the node is not of type EVAS_3D_NODE_TYPE_CAMERA, error message will be
 * generated and nothing happens.
 *
 * @see evas_3d_node_add()
 *
 * @ingroup Evas_3D_Node
 *
 * @param[in] camera The camera
 *
 */
EOAPI void  evas_3d_node_camera_set(Evas_3D_Camera *camera);

/**
 *
 * Get the camera of the given node.
 *
 * @param node          The given node.
 * @return              The camera of the given node if any, or @c NULL if there're none.
 *
 * @see evas_3d_node_camera_set()
 *
 * @ingroup Evas_3D_Node
 *
 *
 */
EOAPI Evas_3D_Camera * evas_3d_node_camera_get(void);

/**
 *
 * Set the light of the given node.
 *
 * @param node          The given node.
 * @param light         The light to be set.
 *
 * If the node is not of type EVAS_3D_NODE_TYPE_LIGHT, error message will be
 * generated and nothing happens.
 *
 * @see evas_3d_node_add()
 *
 * @ingroup Evas_3D_Node
 *
 * @param[in] light The light
 *
 */
EOAPI void  evas_3d_node_light_set(Evas_3D_Light *light);

/**
 *
 * Get the light of the given node.
 *
 * @param node          The given node.
 * @return              The light of the given node if any, or @c NULL if there're none.
 *
 * @see evas_3d_node_light_set()
 *
 * @ingroup Evas_3D_Node
 *
 *
 */
EOAPI Evas_3D_Light * evas_3d_node_light_get(void);

/**
 *
 * Set the animation frame number of the given node for the given mesh.
 *
 * @param node          The given node.
 * @param mesh          The given mesh.
 * @param frame         The animation frame number.
 *
 * If the node is not of type EVAS_3D_NODE_TYPE_MESH or the given mesh does not
 * belong to the given mesh error mesh will be generated and nothing happens.
 *
 * Default mesh frame is 0.
 *
 * @see evas_3d_node_mesh_add()
 *
 * @ingroup Evas_3D_Node
 *
 * @param[in] mesh The given mesh.
 * @param[in] frame The animation frame number.
 *
 */
EOAPI void  evas_3d_node_mesh_frame_set(Evas_3D_Mesh * mesh, int frame);

/**
 *
 * Set the animation frame number of the given node for the given mesh.
 *
 * @param node          The given node.
 * @param mesh          The given mesh.
 * @param frame         The animation frame number.
 *
 * If the node is not of type EVAS_3D_NODE_TYPE_MESH or the given mesh does not
 * belong to the given mesh error mesh will be generated and nothing happens.
 *
 * @see evas_3d_node_mesh_add()
 *
 * @ingroup Evas_3D_Node
 *
 * @param[in] mesh The given mesh.
 *
 */
EOAPI int  evas_3d_node_mesh_frame_get(Evas_3D_Mesh * mesh);

/**
 *
 * Constructor.
 * 
 *
 * @param[in] type No description supplied.
 *
 */
EOAPI void  evas_3d_node_constructor(Evas_3D_Node_Type type);

/**
 *
 * Get the type of the given node.
 *
 * @return     The type of the given node.
 *
 * @see evas_3d_node_add()
 *
 * @ingroup Evas_3D_Node
 * 
 *
 *
 */
EOAPI Evas_3D_Node_Type  evas_3d_node_type_get(void);

/**
 *
 * Add a member node to the given node.
 *
 * Nodes can be constructed into N-ary tree structure like other ordinary scene
 * graph. Basically a node inherit transforms from its parent.
 *
 * @see evas_3d_node_parent_get()
 *
 * @ingroup Evas_3D_Node
 * 
 *
 * @param[in] member Node object to be added.
 *
 */
EOAPI void  evas_3d_node_member_add(Evas_3D_Node *member);

/**
 *
 * Delete a member node from the given node.
 *
 * @see evas_3d_node_member_add()
 *
 * @ingroup Evas_3D_Node
 * 
 *
 * @param[in] member Member node to be deleted from the given node.
 *
 */
EOAPI void  evas_3d_node_member_del(Evas_3D_Node *member);

/**
 *
 * Get the parent node of the given node.
 *
 * @return        The parent node of the given node.
 *
 * @see evas_3d_node_member_add()
 *
 * @ingroup Evas_3D_Node
 * 
 *
 *
 */
EOAPI Evas_3D_Node * evas_3d_node_parent_get(void);

/**
 *
 * Get the list of member nodes of the given node.
 *
 * @return        The list of member nodes if any or @c NULL if there are none.
 *
 * @see evas_3d_node_member_add()
 *
 * @ingroup Evas_3D_Node
 * 
 *
 *
 */
EOAPI const Eina_List * evas_3d_node_member_list_get(void);

/**
 *
 * Set the position of the given node.
 *
 * According to the inheritance flag, (x, y, z) can be a world space position or
 * parent space position.
 *
 * Default position is (0.0, 0.0, 0.0).
 *
 * @see evas_3d_node_position_inherit_set()
 *
 * @ingroup Evas_3D_Node_Transform
 * 
 *
 * @param[in] x X coordinate of the position.
 * @param[in] y Y coordinate of the position.
 * @param[in] z Z coordinate of the position.
 *
 */
EOAPI void  evas_3d_node_position_set(Evas_Real x, Evas_Real y, Evas_Real z);

/**
 *
 * Set the orientation of the given node using quaternion.
 *
 * According the the inheritance flag, (w, x, y, z) can be a world space
 * orientation or parent space orientation.
 *
 * Default orientation is (1.0, 0.0, 0.0, 0.0) (identity quaternion).
 *
 * @see evas_3d_node_orientation_inherit_set()
 *
 * @ingroup Evas_3D_Node_Transform
 * 
 *
 * @param[in] x X term of the orientation quaternion (w, x, y, z)
 * @param[in] y Y term of the orientation quaternion (w, x, y, z)
 * @param[in] z Z term of the orientation quaternion (w, x, y, z)
 * @param[in] w W term of the orientation quaternion (w, x, y, z)
 *
 */
EOAPI void  evas_3d_node_orientation_set(Evas_Real x, Evas_Real y, Evas_Real z, Evas_Real w);

/**
 *
 * Set the orientation of the given node using axis-angle.
 *
 * @param node    The given node.
 * @param angle   Rotation angle.
 * @param x       X term of the rotation axis.
 * @param y       Y term of the rotation axis.
 * @param z       Z term of the rotation axis.
 *
 * @see evas_3d_node_orientation_set()
 *
 * @ingroup Evas_3D_Node_Transform
 * 
 *
 * @param[in] angle Rotation angle.
 * @param[in] x X term of the rotation axis.
 * @param[in] y Y term of the rotation axis.
 * @param[in] z Z term of the rotation axis.
 *
 */
EOAPI void  evas_3d_node_orientation_angle_axis_set(Evas_Real angle, Evas_Real x, Evas_Real y, Evas_Real z);

/**
 *
 * Set the scale of the given node.
 *
 * @param node    The given node.
 * @param x       Scale factor along X-axis.
 * @param y       Scale factor along Y-axis.
 * @param z       Scale factor along Z-axis.
 *
 * According to the inheritance flag, (x, y, z) can be a world space scale or
 * parent space scale. Be careful when using non-uniform scale factor with
 * inheritance, each transform attributes are not affected by other attributes.
 *
 * Default scale is (1.0, 1.0, 1.0).
 *
 * @see evas_3d_node_scale_inherit_set()
 *
 * @ingroup Evas_3D_Node_Transform
 * 
 *
 * @param[in] x Scale factor along X-axis.
 * @param[in] y Scale factor along Y-axis.
 * @param[in] z Scale factor along Z-axis.
 *
 */
EOAPI void  evas_3d_node_scale_set(Evas_Real x, Evas_Real y, Evas_Real z);

/**
 *
 * Get the position of the given node.
 *
 * @param node    The given node.
 * @param x       Pointer to receive X coordinate of the position.
 * @param y       Pointer to receive Y coordinate of the position.
 * @param z       Pointer to receive Z coordinate of the position.
 *
 * @see evas_3d_node_position_set()
 *
 * @ingroup Evas_3D_Node_Transform
 * 
 *
 * @param[in] space 
 * @param[out] x Pointer to receive X coordinate of the position.
 * @param[out] y Pointer to receive Y coordinate of the position.
 * @param[out] z Pointer to receive Z coordinate of the position.
 *
 */
EOAPI void  evas_3d_node_position_get(Evas_3D_Space space, Evas_Real *x, Evas_Real *y, Evas_Real *z);

/**
 *
 * Get the orientation of the given node as quaternion.
 *
 * @param node    The given node.
 * @param x       Pointer to receive X term of the orientation quaternion.
 * @param y       Pointer to receive Y term of the orientation quaternion.
 * @param z       Pointer to receive Z term of the orientation quaternion.
 * @param w       Pointer to receive W term of the orientation quaternion.
 *
 * @see evas_3d_node_orientation_set()
 *
 * @ingroup Evas_3D_Node_Transform
 * 
 *
 * @param[in] space 
 * @param[out] x Pointer to receive X term of the orientation quaternion.
 * @param[out] y Pointer to receive Y term of the orientation quaternion.
 * @param[out] z Pointer to receive Z term of the orientation quaternion.
 * @param[out] w Pointer to receive W term of the orientation quaternion.
 *
 */
EOAPI void  evas_3d_node_orientation_get(Evas_3D_Space space, Evas_Real *x, Evas_Real *y, Evas_Real *z, Evas_Real *w);

/**
 *
 * Get the scale of the given node.
 *
 * @param node    The given node.
 * @param x       Pointer to receive Scale factor along X-axis.
 * @param y       Pointer to receive Scale factor along Y-axis.
 * @param z       Pointer to receive Scale factor along Z-axis.
 *
 * @see evas_3d_node_scale_get()
 *
 * @ingroup Evas_3D_Node_Transform
 * 
 *
 * @param[in] space 
 * @param[out] x Pointer to receive Scale factor along X-axis.
 * @param[out] y Pointer to receive Scale factor along X-axis.
 * @param[out] z Pointer to receive Scale factor along X-axis.
 *
 */
EOAPI void  evas_3d_node_scale_get(Evas_3D_Space space, Evas_Real *x, Evas_Real *y, Evas_Real *z);

/**
 *
 * Rotate the given node to look at desired position.
 *
 * @param node          The given node.
 * @param target_space  Space where the target position belongs to.
 * @param x             X coordinate of the target position.
 * @param y             Y coordinate of the target position.
 * @param z             Z coordinate of the target position.
 * @param up_space      Space where the up vector belongs to.
 * @param ux            X term of the up vector.
 * @param uy            Y term of the up vector.
 * @param uz            Z term of the up vector.
 *
 * This function rotate the given node so that its forward vector (negative
 * Z-axis) points to the desired position and the up vector coincide with the
 * given up vector.
 *
 * @see evas_3d_node_orientation_set()
 *
 * @ingroup Evas_3D_Node_Transform
 * 
 *
 * @param[in] target_space Space where the target position belongs to.
 * @param[in] x X coordinate of the target position.
 * @param[in] y Y coordinate of the target position.
 * @param[in] z Z coordinate of the target position.
 * @param[in] up_space Space where the up vector belongs to.
 * @param[in] ux X term of the up vector.
 * @param[in] uy Y term of the up vector.
 * @param[in] uz Z term of the up vector.
 *
 */
EOAPI void  evas_3d_node_look_at_set(Evas_3D_Space target_space, Evas_Real x, Evas_Real y, Evas_Real z, Evas_3D_Space up_space, Evas_Real ux, Evas_Real uy, Evas_Real uz);

/**
 *
 * Add a mesh to the given node.
 *
 * @param node          The given node.
 * @param mesh          The mesh to be added.
 *
 * If the node is not of type EVAS_3D_NODE_TYPE_MESH, error message will be
 * generated and nothing happens.
 *
 * @see evas_3d_node_add()
 *
 * @ingroup Evas_3D_Node
 * 
 *
 * @param[in] mesh The mesh to be added.
 *
 */
EOAPI void  evas_3d_node_mesh_add(Evas_3D_Mesh *mesh);

/**
 *
 * Delete a mesh from the given node.
 *
 * @param node          The given node.
 * @param mesh          The mesh to be deleted.
 *
 * If the node is not of type EVAS_3D_NODE_TYPE_MESH or the given mesh does not
 * belong to the given node, error message will be gnerated and nothing happens.
 *
 * @see evas_3d_node_mesh_add()
 *
 * @ingroup Evas_3D_Node
 * 
 *
 * @param[in] mesh The mesh to be deleted.
 *
 */
EOAPI void  evas_3d_node_mesh_del(Evas_3D_Mesh *mesh);

/**
 *
 * Get the list of meshes of the given node.
 *
 * @param node          The given node.
 * @return              The list of meshes if any, or @c NULL if there're none.
 *
 * If the node is not of type EVAS_3D_NODE_TYPE_MESH, error message will be
 * generated and @c NULL will be returned. If there're no meshes in the given
 * node, @c NULL will be returned.
 *
 * @see evas_3d_node_mesh_add()
 *
 * @ingroup Evas_3D_Node
 * 
 *
 *
 */
EOAPI const Eina_List * evas_3d_node_mesh_list_get(void);

/**
 *
 * No description supplied.
 *
 * @param[in] x Coordinates of vector.
 * @param[in] y No description supplied.
 * @param[in] z No description supplied.
 * @param[in] x2 No description supplied.
 * @param[in] y2 No description supplied.
 * @param[in] z2 No description supplied.
 *
 */
EOAPI void  evas_3d_node_bounding_box_get(Evas_Real *x, Evas_Real *y, Evas_Real *z, Evas_Real *x2, Evas_Real *y2, Evas_Real *z2);

/**
 *
 * No description supplied.
 *
 * @param[in] x Coordinates of vector.
 * @param[in] y No description supplied.
 * @param[in] z No description supplied.
 * @param[in] r No description supplied.
 *
 */
EOAPI void  evas_3d_node_bounding_sphere_get(Evas_Real *x, Evas_Real *y, Evas_Real *z, Evas_Real *r);


#endif
