package canvas.scene3d;

import java.lang.reflect.Array;

import script.Vector3;
import simphy.script.Matrix4;
import simphy.script.Quaternion;

/**
 * A scene node. Can be used directly to create invisible group nodes or can be extended to implement other node types.
 *
 * @author Mahesh Kurmi
 */
public class SceneNode3D {
	
	/**Object's parent in the scene graph. An object can have at most one parent.*/
	public SceneNode3D parent;
	
	/**An object that can be used to store custom data about the Object3D.*/
	public Object userData =null;
	
	
	/**When this is set, it calculates the matrix of position, (rotation or quaternion) and scale every frame and also recalculates the matrixWorld property. 
	 * Default is true.*/
	public boolean matrixAutoUpdate=true;
	/**
	 * The default up direction for objects, also used as the default position for DirectionalLight, HemisphereLight and Spotlight (which creates lights shining from the top down).
Set to ( 0, 1, 0 ) by default.
	 */
	public static Vector3 DefaultUp = new Vector3( 0, 1, 0 );
	/**
	 * The default setting for matrixAutoUpdate for newly created Object3Ds.
	 */
	public static  boolean DefaultMatrixAutoUpdate = true;
	
	

	/**
	 * sets identifier name of node
	 * @param name
	 */
	public void setName(String name) {

	}

	/**
	 * returns identifier name of this node
	 * @return
	 */
	public String getName() {
		return null;
	}

	/**
	 * Returns true if node is visible
	 */
	public boolean isVisible(){
		return true;
	}
	
	/**
	 * Sets node visible or hides it
	 * @param visible
	 */
	public void setVisible(boolean visible){

	}
	/**
	 * Returns the parent node. If the node has no root node yet then null is returned.
	 *
	 * @return The parent node or null if there is none
	 */
	public final SceneNode3D getParentNode() {
		return null;
	}

	/**
	 * Checks if this node has child nodes.
	 *
	 * @return True if this node has child nodes, false if not
	 */
	public final boolean hasChildNodes() {
		return true;
	}

	/**
	 * Returns array of children of this node if any else returns null
	 * 
	 * @return {Array} array of nodes
	 */
	public SceneNode3D[] getChildern() {
		return null;
	}

	/**
	 *Adds object as child of this object. An arbitrary number of objects may be added. Any current parent on an object passed in here will be removed, since an object can have at most one parent.
	 * @param child:
	 *            The node to add as a child of this node.
	 */
	public void addChild(SceneNode3D child) {
		
	};

	/**
	 * Adds object as a child of this, while maintaining the object's world transform.
	 * @param child:
	 *            The node to add as a child of this node.
	 * @return
	 */
	public void attachChild(SceneNode3D child) {
		
	}

	/**
	 * Remove a child from the node the function is invoked on if it is a child of this node.
	 * 
	 * @param child:
	 *            The node to remove as a child of this node.
	 */
	public void removeChild(SceneNode3D child) {
		
	}

	/**
	 * Remove a child from the node the function is invoked on if it is a child of this node.
	 * 
	 * @param child:
	 *            The node to remove as a child of this node.
	 */
	public void removeAllChildren() {
	       
	}

	/**
	 * Adds a light so it illuminates this node and all child nodes (not the parent nodes).
	 * Note that light is not added as child to the node, it just illuminates this node and its descendents
	 * @param light
	 *            The light to add
	 */
	public void addLight(final Light light) {
		
	}

	/**
	 * Removes a light so it no longer illuminates this node and its child nodes.
	 *
	 * @param light
	 *            The light to remove
	 */
	public void removeLight(final Light light) {

	}

	 /**
     * Returns the physics of this scene node. <br> 
     * Note that calling this method guarantees non null object
     * @return The physics object of the node which can later be modified to control this node
     */
    public Physics getPhysics()
    {
       return null;
    }
    
    /**
     * Sets the physics of this scene node.
     *
     * @return The physics object , can be null to disable physics for the node
     * @see #getPhysics()
     */
    public void setPhysics(Physics physics)
    {

    }
    
	
	/**
	 * Returns scale
	 * @return {Vector3}: Vector3 having three components of scale
	 */
	public Vector3 getScale() {
		return null;
	}
	
	/**

	/**
	 * Sets the current absolute scale
	 * 
	 * @param scale
	 *            {Vector3}: a vector determining the scale in x, y, z directions
	 */
	public void setScale(Vector3 scale) {
		
	};

	/**
	 * Sets the current absolute scale
	 *
	 * @param sx
	 *            The X scale factor
	 * @param sy
	 *            The Y scale factor
	 * @param sz
	 *            The Z scale factor
	 */
	public void setScale(double sx, double sy, double sz) {
		
	};

	/**
	 * Scale the node.E.g. make the node twice as large: scale = [2,2,2].
	 * 
	 * @param scale
	 *            {Vector3}
	 */
	public void scale(Vector3 scale) {
		
	};

	/**
	 * Scales the node by the specified factors.
	 *
	 * @param sx
	 *            The X scale factor
	 * @param sy
	 *            The Y scale factor
	 * @param sz
	 *            The Z scale factor
	 */
	public void scale(double sx, double sy, double sz) {
		
	};

	/**
	 * Returns position according relative to the parent's position
	 * @return {vector3}
	 */
	public Vector3 getPosition() {
		return null;
	};

	
	/**
	 * Set position according relative to the parent's position
	 * @param position:
	 *            a new position
	 */
	public void setPosition(Vector3 position) {
		
	};

	/**
	 * Set position according relative to the parent's local coordinates
	 * @param x
	 * @param y
	 * @param z
	 */
	public void setPosition(double x, double y, double z) {
		
	};

	/**
	 * Translate the node.
	 * @param translation
	 *            {Vector3} translation in parent's local space
	 */
	public void translate(Vector3 translation) {
		
	};

	/**
	 * Translates the node relative to the parent's local coordinates
	 * @param x
	 * @param y
	 * @param z
	 */
	public void translate(double x, double y, double z) {

	};

	/**
	 * Returns rotation angles in radians in parent space
	 * @return {Vector3}: Vector3 having three euler angles in radians as its components
	 */
	public Vector3 getRotation(){
		return null;
	}
	
	/**
	 * Sets Rotation of the node about its local axis by the specified angle around the coordinate axes.
	 * @param xRotation
	 *            angle in radians
	 * @param yRotation
	 *            angle in radians
	 * @param zRotation
	 *            angle in radians
	 */
	public void setRotation(double xRotation, double yRotation, double zRotation) {
		
	}

	/**
	 * Sets Rotation of the node about its local axis by the specified angle around the coordinate axes.
	 * 
	 * @param angles
	 *            {Vector3}: Vector3 having three euler angles in radians as its components
	 */
	public void setRotation(Vector3 angles) {

	};

	/**
	 * Rotates the current transformation matrix by the specified angle around the local coordinates axes.
	 */
	public void rotate(double xRotation, double yRotation, double zRotation) {
		
	}

	/**
	 * Rotate the node relative to it's parent.
	 * 
	 * @param angles
	 *            {Vector3}: Vector3 having three euler angles in radians as its components
	 */
	public void rotate(Vector3 angles) {
		
	}
	
	
	/**
	 * Rotates the object to face a point (target) in world space.
	 * @param target {Vector3}  A vector representing target position in world space.
	 */
	public void lookat(Vector3 target){
		
	}

	/**
	 * Rotates the object to face a point in world space.
	 * Params are the x, y and z components of the world space position.
	 * @param x
	 * @param y
	 * @param z
	 */
	public void lookat(double x, double y,double z){
		
	}
	
	/**
	 * Returns a vector representing the position of the object in world space.
	 * @return {vector3}
	 */
	public Vector3 getWorldPosition() {
		return null;
	};
	
	/**
	 * Returns a vector of the scaling factors applied to the object for each axis in world space.
	 * @return {vector3}
	 */
	public Vector3 getWorldScale() {
		return null;
	};
	
	/**
	 * Returns a vector representing the direction of object's positive z-axis in world space.
	 * @return {vector3}
	 */
	public Vector3 getWorldDirection() {
		return null;
	};
	
	/**
	 * Returns a Vector3 representing the euler rotation of the object in world space.
	 * @return {vector3}
	 */
	public Vector3 getWorldRotation () {
		return null;
	};
	
	
	
	/**
	 * Sets Material of the node, its children automatically inherit the material from this node
	 * 
	 * @param material
	 */
	public void setMaterial(Material material) {
		
	}

	/**
	 * returns current Material of the node
	 * 
	 * @return
	 */
	public Material getMaterial() {
		return null;
	}

	/**
	 * Represents String representation of scene tree starting from this node as root
	 */
	public String toString() {
		return null;
	}


	public SceneNode3D clone() {
		return null;
	}
	
	/**
	 * Applies the matrix transform to the object and updates the object's position, rotation and scale in local space.
	 * @param matrix {Matrix4} 
	 */
	public void applyMatrix4(Matrix4 matrix ) {
		
	}

	/**
	 * Applies the rotation represented by the quaternion to this object.
	 * @param q {Quaternion}
	*/
	public void applyQuaternion(Quaternion q) {

	}
	
	/**
	 * Converts the vector from local space to world space.
	 * @param vector
	 * @return
	 */
	public Vector3 localToWorld(Vector3 localVector ) {
		return null;
	}

	/**
	 * Converts the vector from world space to local space.
	 * @param vector
	 * @return
	 */
	public Vector3 worldToLocal (Vector3 worldVector ) {
		return null;
	}
	
	/**
	 * Removes the model from it's parent
	 */
	
	public void remove() {
		
	}
	
	/**
	 * Usefd to implement all the action
	 * @param delta : decides the rate of action implementation
	 */
	
	public void act (double delta) {

	}
	
	/**
	 * Adds the action to the model
	 * @param action3d
	 * @throws CloneNotSupportedException 
	 */
	
	public void addAction3d (Action3D action3d) {
		
	}
	
	/**
	 * Removes the action from the model
	 * @param action
	 */

	public void removeAction3d (Action3D action) {

	}
	
	/**
	 * Returns all the actions applied on the model
	 * @return
	 */

	public Array<Action3D> getActions3d () {
		return null;
	}

	/**
	 * Removes all actions from the model
	 */
	public void clearActions3d () {
		
	}

	/**
	 * Called in the render() function in the Scene.java
	 * Applies all the actions to the model and it's childs
	 * @param delta
	 */
	
	public void actAll(double delta) {
		
	}
	
}
