package simphy.script;

import simphy.script.canvas.Transform;

public class Matrix4 {
	
	
	/**
	 * Returns a copy of this matrix. If a target matrix is specified then the
	 * matrix is copied into this target matrix. If it is null then a new
	 * fresh matrix is created.
	 * 
	 * @param {Matrix4} target
	 *            Optional target matrix, can be null
	 * @return {Matrix4} A copy of this matrix
	 */
	public Matrix4 clone(Matrix4 target) {
		return null;
	}
	
	
	/**
	 * creates identity matrix
	 * @param v array of length 16
	 * Note that matrix does't make copy of this array
	 */
	public Matrix4 setFromGLArray(float[] v) {
		return null;
	}
	
	/**
	 * Sets this matrix as copy of matrix in parameter
	 * @param mat
	 * @return this matrix for chaining
	 */
	public Matrix4 set(Matrix4 mat) {
		return null;
	}
	
	/**
	 * Sets Matrix to 4x4 Matrix in following form <pre>
	 *	|m11  m12  m13 m14|
	 *	|m21  m22  m23 m24|
	 *	|m31  m32  m33 m34|
	 *	|m41  m42  m43 m44|</b>
	 *	</pre>
	 *@return this matrix for chaining
	 */
	public Matrix4 set(	double m11, double m12, double m13, double m14,
						double m21, double m22, double m23, double m24,
						double m31, double m32, double m33, double m34,
						double m41, double m42, double m43, double m44) {
		return null;
	}
	

	/** Sets this matrix to the given affine matrix. The values are mapped as follows:
	 *
	 * <pre>
	 *      [  M00  M01   0   M02  ]
	 *      [  M10  M11   0   M12  ]
	 *      [   0    0    1    0   ]
	 *      [   0    0    0    1   ]
	 * </pre>
	 * @param affine the affine matrix
	 * @return This matrix for chaining */
	public Matrix4 set (Transform affine) {
		return null;
	}
	
	
	public final String toString() {
		return null;
	}

	
	public final boolean equals(final Object obj) {
		return true;
	}
	
	
	/**
	 * Post multiplies this matrix with the specified matrix. The result is written
	 * to this matrix.
	 * <pre>
	 * A.multiply(B) results in A := AB
	 * </pre>
	 * @param {Matrix4} rightMat
	 *            The other matrix to multiply by
	 * @return {Matrix4}
	 *          This matrix for the purpose of chaining operations.  
	 */
	public  Matrix4 multiply(Matrix4 rightMatrix) {
		return null;
	}
	
	
	/**
	 * Post multiplies this matrix with the specified affine transform. The result is written
	 * to this matrix.
	 * 
	 * @param {Transform } affine
	 *            The other matrix
	 * @return {Matrix4 }
	 *            This matrix for chaining
	 */
	public Matrix4 multiply(Transform affine){
		return null;
	}
	
	
	/**
	 * Sets the entries of this matrix to an identity matrix.
	 * 
	 * @return {Matrix4} this matrix set as identity for chaining
	 */
	public Matrix4 setToIdentity(){
		return null;
	}
	
	/**
	 * Sets the entries of this matrix to a translation matrix.
	 * 
	 * @param {number} dx
	 *            The X delta
	 * @param {number} dy
	 *            The Y delta.
	 * @param {number} dz
	 *            The Z delta.

	 * @return {Matrix4}
	 *            This matrix for chaining
	 */
	public Matrix4 setToTranslate(double dx, double dy,double dz){
		return null;
	}
	
	/**
	 * Sets the entries of this matrix to a scaling matrix.
	 * 
	 * @param {number} fx
	 *            The X scale factor
	 * @param {number} fy
	 *            The Y scale factor
	 * @param {number} fz
	 *            The Z scale factor

	 * @return {Matrix4}
	 *            This matrix for chaining
	 */
	public Matrix4 setToScale(double fx, double fy,double fz){
		return null;
	}
	/**
	 * Sets the entries of this matrix to a rotation matrix about X axis
	 * 
	 * @param {number} angle
	 *            The rotation angle in anti-clockwise RAD about x axis
	 * @return {Matrix4}
	 *            This matrix for chaining
	 */	
	public Matrix4 setToRotationX(double theta){
		return null;
	}
	
	/**
	 * Sets the entries of this matrix to a rotation matrix about Y axis
	 * 
	 * @param {number} angle
	 *            The rotation angle in anti-clockwise RAD about Y axis
	 * @return {Matrix4}
	 *            This matrix for chaining
	 */	
	public Matrix4 setToRotationY(double theta){
		return null;
	}
	
	/**
	 * Sets the entries of this matrix to a rotation matrix about Z axis
	 * 
	 * @param {number} angle
	 *            The rotation angle in anti-clockwise RAD about Z axis
	 * @return {Matrix4}
	 *            This matrix for chaining
	 */	
	public Matrix4 setToRotationZ(double theta){
		return null;
	}
	
	/**
	 * Sets this Matrix to rotation matrix for given angle about given axis
	 * @param angle The rotation angle in anti-clockwise RAD about given axis
	 * @param axis The axis about which rotation is to be done
	 * @return this matrix for chaining
	 */
	public Matrix4 setToRotate( double angle, Vector3 axis ){
		return null;
	}
	
	/**
	 * Sets the rotation component of this matrix to the rotation specified by q, as outlined here. The rest of the matrix is set to the identity
	 * @param quat {Quat}
	 * @return this matrix for chaining
	 */
	public Matrix4 setFromQuat(Quaternion quat){
		return null;	
	}
	
	/**
	 * View Matrix Generators
	 * This matrix will transform vertices from world-space to view-space.  This matrix is the inverse of the camera’s transformation matrix.
	 * where The transformation that places the camera in the correct position and orientation in world space (this is the transformation that you would apply to a 3D model of the camera if you wanted to represent it in the scene).
	 * @param eye camera location in world coordinates
	 * @param at  target location in world coordinates
	 * @param up  up direction of camera (a vector which is perpendicular to the camera axis )
	 * @see {@link https://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/lookat-function}
	 * @return this matrix for chaining
	 */
	public Matrix4 setToLookAt(Vector3 eye, Vector3 at, Vector3 up )
	{
		return null;
	}
	
	
	/**
	 * Orthographic Projection Matrix Generators
	 * Maps [left,right] to [-1,1] for x axis
	 * Maps [bottom,up] to [-1,1] for y axis
	 * Maps [near,far] to [-1,1] for z axis
	 * @param left
	 * @param right
	 * @param bottom
	 * @param top
	 * @param near
	 * @param far
	 * @return this matrix for chaining
	 */
	public Matrix4 setToOrtho( double left, double right, double bottom, double top, double near, double far )
	{
	
		return null;
	}


	
	/**
	 * Sets this matrix to perspective projection
	 * @param fovy   The vertical Field of View, in radians: the amount of "zoom". Think "camera lens". Usually between PI/2 (extra wide) and PI/6 (quite zoomed in)
	 * @param aspect  Aspect Ratio. Depends on the size of your window = width/height
	 * @param near Near clipping plane. Keep as big as possible, or you'll get precision issues.
	 * @param far Far clipping plane. Keep as little as possible.
	 * @return this matrix for chaining
	 */
	public Matrix4 setToPerspective( double fovy, double aspect, double near,double  far ){
		return null;
	}
	

	/**
	 * Creates a perspective projection matrix. This is used internally by 3D Camera
	 * @param left
	 * @param right
	 * @param top
	 * @param bottom
	 * @param near
	 * @param far
	 * @return this Matrix
	 */
	public Matrix4 setToPerspective(double left, double right, double top, double bottom, double near, double far ){
		return null;
	}
	
	/**
	 * Translates this matrix by given translations
	 * 
	 * @param {number} dx
	 *            The X delta
	 * @param {number} dy
	 *            The Y delta.
	 * @param {number} dz
	 *            The Z delta.

	 * @return {Matrix4}
	 *            This matrix
	 * @return this matrix for chaining
	 */
	public Matrix4 translate(double dx, double dy,double dz){
		return null;
	}
	
	/**
	 * Scales this matrix by given factors 
	 * 
	 * @param {number} fx
	 *            The X scale factor
	 * @param {number} fy
	 *            The Y scale factor
	 * @param {number} fz
	 *            The Z scale factor

	 * @return {Matrix4}
	 *            This matrix for chaining
	 */
	public Matrix4 scale(double fx, double fy,double fz){
		return null;
	}
	
	/**
	 * Rotates this matrix by given angles about X axis in radians
	 * 
	 * @param {number} angle
	 *            The rotation angle in anti-clockwise RAD about x axis
	 * @return {Matrix4}
	 *            This matrix for chaining
	 */	
	public Matrix4 rotateX(double theta){
		return null;
	}
	
	/**
	 * Sets the entries of this matrix to a rotation matrix about Y axis
	 * 
	 * @param {number} angle
	 *            The rotation angle in anti-clockwise RAD about Y axis
	 * @return {Matrix4}
	 *            This matrix for chaining
	 */	
	public Matrix4 rotateY(double theta){
		return null;
	}
	
	/**
	 * Sets the entries of this matrix to a rotation matrix about Z axis
	 * 
	 * @param {number} angle
	 *            The rotation angle in anti-clockwise RAD about Z axis
	 * @return {Matrix4}
	 *            This matrix for chaining
	 */	
	public Matrix4 rotateZ(double theta){
		return null;
	}
	
	/**
	 * Rotates this matrix for given angle about given axis
	 * @param angle The rotation angle in anti-clockwise RAD about given axis
	 * @param axis The axis about which rotation is to be done
	 * @return this matrix for chaining
	 */
	public Matrix4 rotate( double angle, Vector3 axis ){
		return null;

	}
	
	 /**
     * Transposes this matrix 
     * @return This matrix for chaining
     */

    public Matrix4 transpose(){
    	return null;
    }

    /**
     * Returns the determinant of this matrix.
     * @return The determinant
     */

    public  double getDeterminant()
    {
    	return 0;
    }
    
    /**
     * Checks if the specified matrix is an identity matrix.
     * @return True if matrix is an identity matrix, false if not
     */
    public boolean isIdentity()
    {
    	return true;
    }
    
    
    /**
     * Returns the inverse of matrix
     * @return  inverted matrix which can mutate later so make a copy if to be used later
     * */
   public Matrix4 getInverse(){
	   return null;
	 }

   /** Multiplies this vector by the given matrix dividing by w, assuming the fourth (w) component of the vector is 1. This is
	 * mostly used to project/unproject vectors via a perspective projection matrix.
	 * @param x
	 * @param y
	 * @param z 
	 * @return This vector for chaining 
	 * @see #transform(Vector3)*/
	public Vector3 project(double x,double y,double z) {
		return null;
	}
	
	/** 
	 * Multiplies this vector by the given matrix dividing by w, assuming the fourth (w) component of the vector is 1. This is
	 * mostly used to project/unproject vectors via a perspective projection matrix.
	 *
	 * @param v The vector to be project.
	 * @return This vector for chaining 
	 * @see #transform(Vector3)*/
	public Vector3 project(Vector3 v) {
		return null;
	}

	/**
	 * Transforms vector by this matrix
	 * @param x
	 * @param y
	 * @param z 
	 * @return transformed vector which can mutate later so make a copy if to be used later
	 * @see #project(Vector3)
	 */
	public Vector3 transform(double x,double y,double z) {
		return null;
	}
		
		
	/**
	 * Transforms vector by this matrix
	 * @param position
	 * @return transformed vector which can mutate later so make a copy if to be used later
	 */
	public Vector3 transform(Vector3 position) {
		return null;
	}
	
	/**
	 * Transforms direction by this matrix (No effect of translation)
	 * @param dir
	 * @return transformed direction which can mutate later so make a copy if to be used later
	 */
	public Vector3 transformDir(double x,double y,double z) {
		return null;
	}
	
	/**
	 * Transforms direction by this matrix
	 * @param dir
	 * @return transformed direction which can mutate later so make a copy if to be used later
	 */
	public Vector3 transformDir(Vector3 dir) {
		return null;
	}
	
	
	/**
	 * Sets this matrix to the transformation composed of position, quaternion and scale. 
	 * Internally this calls makeRotationFromQuaternion( quaternion ) followed by scale( scale ), then finally setPosition( position ).
	 * @param position if null then position is not set
	 * @param quaternion if null then quaternion is not set
	 * @param scale if null then scale is not set
	 * @return this matrix for chaining
	 */
	public Matrix4 compose (Vector3 position,Quaternion quaternion, Vector3 scale ) {
		return null;
	}

	/**
	 * Decomposes this matrix into it's position, quaternion and scale components.
	 * @param position {Vector3} vector to hold position 
	 * @param quaternion
	 * @param scale
	 */
	public void decompose (Vector3 position,Quaternion quaternion,Vector3 scale ) {

	}
	
	/**
	 * Extracts the rotation component of this matrix m into the target matrix's rotation component.
	 * If target matrix is null,then a new fresh matrix is created with rotation set as this matrix's rotation
	 * 
	 * @param {Matrix4} target
	 *            Optional target matrix, can be null
	 * @return {Matrix4} target Matrix with rotation set as this matrix's rotation
	 */
	public Matrix4 extractRotation( Matrix4 target ) {

		return null;
	}
	
	/**
	 * Extracts the rotation component of this matrix m into the target Quat.
	 * If target matrix is null,then a temporary Quat is created with rotation set as this matrix's rotation
	 * 
	 * @param {Quat} target
	 *            Optional target Quat, can be null
	 * @return {Quat} target Quat with rotation set as this matrix's rotation which can mutate later so make a copy if to be used later
	 */
	public Quaternion extractRotation( Quaternion target ) {
		return null;
	}
	
	/**
	 * Extracts the position component of this matrix m into the target vector.
	 * If target vector is null,then a new  vector is created with position set as this matrix's position
	 * 
	 * @param {Vector3} target
	 *            Optional target vector, can be null
	 * @return {Vector3} target Vector with position set as this matrix's translation which can mutate later so make a copy if to be used later
	 */
	public Vector3 extractPosition( Vector3 target ) {
		return null;
	}

	/**
	 * Extracts the scaling component of this matrix m into the target vector.
	 * If target vector is null,then a new  vector set as this matrix's scaling factors in each direction is returned
	 * 
	 * @param {Vector3} target
	 *            Optional target vector, can be null
	 * @return {Vector3} target Vector  set as this matrix's scale factors in x,y,z directions which can mutate later so make a copy if to be used later
	 */
	public Vector3 extractScale( Vector3 target ) {
		return null;
	}
	
	/**
	 * Returns first three elements of Row of matrix into the target vector
	 * @param index {Number} row index in 0 to 3
	 * @param target {Vector3} 
	 *            Optional target vector, can be null
	 * @return {Vector3} target Vector  set as this matrix row's elements which can mutate later so make a copy if to be used later
	 */
	public Vector3 extractRow(int index,Vector3 target){
		return null;
	}
	
	/**
	 * Returns first three elements of Column of matrix into the target vector
	 * @param index {Number} column index in 0 to 3
	 * @param target {Vector3} 
	 *            Optional target vector, can be null
	 * @return {Vector3} target Vector  set as this matrix row's elements which can mutate later so make a copy if to be used later
	 */
	public Vector3 extractColumn(int index,Vector3 target){
		return null;
	}
	
	 /**
	 * returns Column major 4x4 array of floats ready to be used in opengl shaders
	 * Note that you should make copy of floats if needed later
	 * @return array which can mutate later so make a copy if to be used later
	 */
	public float[] toGLArray() {
		return null;
	}
	
	


}
