package canvas.scene3d;

import java.util.function.BiFunction;

import canvas.Path2D;
import script.Color;
import script.Vector2;
import script.Vector3;

public class Meshes {
	public static Meshes instance=new Meshes();
	
	/**
	* Return instance of this singleton class
	 * @return
	 */
	public static Meshes getInstance(){
		return null;
	}
	
	public static Mesh getCachedSphereMesh(){
		return null;
	}
	
	public static Mesh getCashedConeMesh(){
		return null;
	}
	
	public static Mesh getcashedCylinderMesh(){
		return null;
	}

	/**
	 * Creates unconnected line segments for each group of two vertices. 
	 * If the points array has n vertices, it will create n/2 line segments. If n is odd, it ignores the final vertex.
	 * @param points
	 * @return
	 */
	public  Mesh createLines(Vector3[] points){
		return null;
	}
	
	/**
	 * Grids are two-dimensional arrays of lines.
	 * Creates a new Grid of size 'size' and divided into 'divisions' segments per side and centered at origin
	 * @param xSize The size of the grid along X.
	 * @param ySize The size of the grid along Y.
	 * @param divisions The number of divisions across the grid.
	 * @return
	 */
	public  Mesh createGrid(double xSize, double  ySize, int xDivisions,int yDivisions){
		return null;
	}
	
	/**
	 * Creates a new PolarGrid of radius 'radius' with 'radials' number of radials and 'circles' number of circles,
	 * where each circle is smoothed into 'divisions' number of line segments.
	 * @param radius The radius of the polar grid. This can be any positive number. 
	 * @param radials The number of radial lines. This can be any positive integer. 
	 * @param circles The number of circles. This can be any positive integer. 
	 * @param divisions The number of line segments used for each circle. This can be any positive integer that is 3 or greater.
	 * @return
	 */
	public  Mesh createPolarGrid(double radius, int  radials, int circles,int divisions){
		return null;
	};
	
	/**
	 * Creates Plane in XY Pane with center as origin, with along axis and height along y axis)<br>
	 * It can be used to Create grid and rectangles
	 * 
	 * @param width
	 *            (must be +ve)
	 * @param height
	 *            (must be +ve)
	 * @param widthSegments
	 *            (must be >= 1)
	 * @param heightSegments
	 *            (must be >= 1)
	 */
	public  Mesh createPlane(double width, double height, int widthSegments, int heightSegments) {
		return null;
	}

	/**
	 * Creates a filled circle in the xy-plane, centered at the origin. <br>
	 * A polygonal approximation of the circle is drawn. It can be used to create any regular polygon
	 * 
	 * @param radius
	 *            the radius of the circle
	 * @param slices
	 *            the number of sides of the polygon
	 * @param theradtart
	 *            Start angle for first segment, measured from three o'clock position.
	 * @param thetalength
	 *            A circular cutout from the texture is applied to the circle.
	 */
	public  Mesh createDisc(double radius, double radialSegments, double thetaStart, double thetaLength) {
		return null;
	}

	/**
	 * Draw a filled ring in the xy-plane, centered at the origin. The ring is a disk with a smaller disk deleted from
	 * its center. A polygonal approximation of the ring is drawn.
	 * 
	 * @param innerRadius
	 *            the radius of the hole in the ring. Must be greater than or equal to zero; if the value is zero, then
	 *            a completely filled disk is drawn.
	 * @param outerRradius
	 *            the radius of the ring, measured from center to outer edge. Must be greater than innerRadius.
	 * @param slices
	 *            the number of sides of the polygon
	 * @param makeTexCoords
	 *            tells whether to make texture coordinates for the circle. A cutout from the texture is applied to the
	 *            disk.
	 */
	public  Mesh createRing(double innerRadius, double outerRadius, int slices) {
		return null;
	}
	
	/**
	 * Creates an one-sided polygonal geometry from path shape.
	 * 
	 * @param path
	 *            Path2D object
	 * @param fineNess
	 *            Maximum deviation from original curve
	 * @return Created polygon Mesh in XY plane
	 */
	public  Mesh createPath(Path2D path, double fineNess) {
		return null;
	}

	/**
	 * Creates extruded geometry from a path2D shape. The faces represented by path lie parallel to XY Plane equally above and below it
	 * 
	 * @param path
	 *            Path2D object
	 * @param fineNess
	 *            Maximum Deviation from original path
	 * @param topCap
	 *            if true Polygon cap is true on top face
	 * @param bottomCap
	 *            if true Polygon cap is true on bottom face
	 * @param depth
	 *            Depth to extrude the shape.
	 * @return
	 */
	public  Mesh extrudeFromPath(Path2D path, double fineNess, boolean topCap, boolean bottomCap,
			double depth) {
		return null;
	}

	/**
	 * Creates unit cube centered at origin
	 * 
	 * @return Created Mesh
	 */
	public  Mesh createBox() {
		return null;
	}

	/**
	 * Creates a a rectangular cuboid with a given 'width', 'height', and 'depth'. On creation, the cuboid is centred on
	 * the origin, with each edge parallel to one of the axes.
	 * 
	 * @param width
	 *            the length of the edges parallel to the X axis (must be +ve).
	 * @param height
	 *            the length of the edges parallel to the Y axis (must be +ve).
	 * @param depth
	 *            the length of the edges parallel to the Z axis (must be +ve).
	 * @return Created Mesh
	 */
	public  Mesh createBox(double width, double height, double depth) {
		return null;
	}

	/**
	 * Creates Sphere mesh of unit radius centered at origin
	 */
	public  Mesh createSphere(double radius, int widthSegments, int HeightSegments) {
		return null;
	}

	/**
	 * Creates Sphere centered at origin <br>
	 * The geometry is created by sweeping and calculating vertexes around the Y axis (horizontal sweep) and the Z axis
	 * (vertical sweep). Thus, incomplete spheres ('sphere slices') can be created through the use of different values
	 * of phiStart, phiLength, thetaStart and thetaLength, in order to define the points in which we start (or end)
	 * calculating those vertices.
	 * 
	 * @param radius
	 *            — sphere radius. Default is 1.
	 * @param widthSegments
	 *            — number of horizontal segments. Minimum value is 3, and the default is 8.
	 * @param heightSegments
	 *            — number of vertical segments. Minimum value is 2, and the default is 6.
	 * @param phiStart
	 *            — specify horizontal starting angle. Default is 0.
	 * @param phiLength
	 *            — specify horizontal sweep angle size. Default is Math.PI * 2.
	 * @param thetaStart
	 *            — specify vertical starting angle. Default is 0.
	 * @param thetaLength
	 *            — specify vertical sweep angle size. Default is Math.PI.
	 * @return created Mesh
	 */
	public  Mesh createSphere(double radius, int widthSegments, int heightSegments, double phiStart,
			double phiLength, double thetaStart, double thetaLength) {
		return null;
	}

	/**
	 * Creates Cone centered at origin and axis along Y axis
	 * 
	 * @param radius
	 *            radius of base (must be +ve)
	 * @param height
	 *            height of cone (must be +ve)
	 * @param radialSegments
	 *            Number of segmented faces around the circumference of the cone. (must be >2)
	 * @param closed
	 *            A boolean indicating whether the base of the cone is open or capped.
	 * @return
	 */
	public  Mesh createCone(double radius, double height, int radialSegments, boolean closed) {
		return null;
	}

	/**
	 * Creates Cylinder centered at origin and axis along Y axis
	 * 
	 * @param radius
	 *            radius of base (must be +ve)
	 * @param height
	 *            height of cylinder (must be +ve)
	 * @param radialSegments
	 *            Number of segmented faces around the circumference of the cylinder. (must be >2)
	 * @param closed
	 *            A boolean indicating whether the bases of the cylinder are open or capped.
	 * @return
	 */
	public  Mesh createCylinder(double radius, double height, int radialSegments, boolean closed) {
		return null;
	}

	/**
	 * creates Cone Frustum centered at origin with axis along Y axes Used to create cone and cylindrical geometries
	 * 
	 * @param radiusTop
	 *            Radius of the cylinder at the top.
	 * @param radiusBottom
	 *            Radius of the cylinder at the bottom.
	 * @param height
	 *            Height of the cylinder.
	 * @param radialSegments
	 *            Number of segmented faces around the circumference of the cylinder.
	 * @param heightSegments
	 *            Number of rows of faces along the height of the cylinder.
	 * @param closed
	 *            A Boolean indicating whether the ends of the cylinder are open or capped. Default is false, meaning
	 *            capped.
	 * @param thetaStart
	 *            Start angle for first segment (measured from three o'clock position).
	 * @param thetaLength
	 *            The central angle, often called theta, of the circular sector. here 2*Pi makes for a complete
	 *            cylinder.
	 * @return
	 */
	public  Mesh createConeFrustum(double radiusTop, double radiusBottom, double height, int radialSegments,
			int heightSegments, boolean closed, double thetaStart, double thetaLength) {
		return null;
	}

	/**
	 * Creates torus or doughnut shape centered at origin, and axis along Z axis
	 * 
	 * @param radius
	 *            - Radius of the torus, from the center of the torus to the center of the tube. Default is 1.
	 * @param tube
	 *            — Radius of the tube. Default is 0.4.
	 * @param radialSegments
	 *            — Default is 8
	 * @param tubularSegments
	 *            — Default is 6.
	 * @param arc
	 *            — Central angle. Default is Math.PI * 2.
	 * @return
	 */
	public  Mesh createTorus(double radius, double tube, int radialSegments, int tubularSegments, double arc) {
		return null;
	}

	/**
	 * Creates a torus knot, the particular shape of which is defined by a pair of coprime integers, p and q. If p and q
	 * are not coprime, the result will be a torus link
	 * 
	 * @param radius
	 *            - Radius of the torus. Default is 1.
	 * @param tube
	 *            — Radius of the tube. Default is 0.4.
	 * @param tubularSegments
	 *            — Default is 64.
	 * @param radialSegments
	 *            — Default is 8.
	 * @param p
	 *            — This value determines, how many times the geometry winds around its axis of rotational symmetry.
	 *            Default is 2.
	 * @param q
	 *            — This value determines, how many times the geometry winds around a circle in the interior of the
	 *            torus. Default is 3.
	 * @return
	 */
	public  Mesh createTorusKnot(double radius, double tube, int tubularSegments, int radialSegments, int p,
			int q) {
		return null;
	}

	/**
	 * Generates Text as a single 3D geometry centered at origin, aligned along x axis and extruded along z axis
	 * 
	 * @param text
	 *            {String} Any Unicode String to be converted to geometry
	 * @param fineNess
	 *            {Number} Maximum deviation from original geomtery
	 * @param depth
	 *            {Number} Depth to extrude shape (must be >=0)
	 * @param cssFont
	 *            {String} case insensitive case CSS-font string indicating fontName, fontStyle and fotnSize separated
	 *            by space in any order. Few valid examples are: <br>
	 * 
	 *            <pre>
	 * "32px bold Arial", "Arial italic" ,"bold dialog 32px", "Dialog 12"
	 *            </pre>
	 * 
	 * @return
	 */
	public  Mesh create3DText(String text, double fineNess, double depth, String cssFont) {
		return null;
	}

	/**
	 * Creates meshes with axial symmetry along Y axis like vases.
	 * 
	 * @param points
	 *            Array of Vector2s. The x-coordinate of each point must be greater than zero.
	 * @param segments
	 *            the number of circumference segments to generate. Default is 12.
	 * @param phiStart
	 *            the starting angle in radians.
	 * @param phiLength
	 *            the radian (0 to 2PI) range of the lathed section 2PI is a closed lathe, less than 2PI is a portion
	 * @return
	 */
	public  Mesh LatheGeometry(Vector2[] points, int segments, double phiStart, double phiLength) {
		return null;
	}

	/**
	 * Creates a tube that extrudes along a 3d curve created by a function which returns a vector corresponding to parameter t that varies from 0 to 1
	 * @param curve a non null curve
	 * @param tubularSegments
	 *            The number of segments that make up the tube
	 * @param radius
	 *            The radius of the tube,
	 * @param radialSegments
	 *            The number of segments that make up the cross-section
	 * @param closed
	 *            the tube open or closed at ends
	 * @return
	 */
	public  Mesh createTubeGeomtery(Curve curve, int tubularSegments, double radius, int radialSegments,
			boolean closed) {
		return null;
	}


	/**
	 * Generates parametric surface for expressions containing u and v where each is varied form 0 to 1
	 * @param exprX 
	 * @param exprY
	 * @param exprZ
	 * @param slices The count of slices to use for the parametric function
	 * @param stacks The count of stacks to use for the parametric function
	 * @return
	 */
	public  Mesh ParametricSurface(String exprX, String exprY, String exprZ, int slices, int stacks) {
		return null;
	}

	 
	/**
	 * Generates parametric surface 
	 * @param vertexFunction (must not be null) 
	 * 				A function that takes in a u and v value each between 0 and 1 and returns a  Vector3 vertex
	 * @param colorFunction (can be null) 
	 * 				A function that takes in a u and v value each between 0 and 1 and returns a  Vector3 color with r,g,b component each in [0,1]
	 * @param slices 
	 * 				The count of slices to use for the parametric function
	 * @param stacks 
	 * 				The count of stacks to use for the parametric function
	 * @return
	 */
	public  Mesh ParametricSurface(BiFunction<Float,Float,Vector3> vertexFunction, BiFunction<Float,Float,Vector3> colorFunction,int slices, int stacks) {
		return null;
	}
	
	/**
	 * Creates EdgeGeometry for current Mesh created using current Mesh info,
	 * This method should be called just after creation of mesh using {@link Meshes} methods
	 * An edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this
	 * value. default = 1 degree.
	 * 
	 * @param thresholdAngle
	 *            — An edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces
	 *            exceeds this value. default = 1 degree.
	 * @return Wireframe Mesh showing only hard edges
	 */
	public Mesh buildEdgeGeometry(double thresholdAngle, Color lineColor, double lineWidth){
		return null;
	}
	
}

