import java.awt.*;
import java.util.*;
import java.lang.Math;

public class ParamSphere extends ParamSurface //Sphere is the subclass
{
	double dTheta = 0, dPhi = 0;
	double dRadius, dEpsilon;
	double dCenter[] = new double[4];
	double Sphere3D[][][];
	int iEpsInv;
	boolean bWasDrawn = false;	
	
	public ParamSphere()
	{
	}
	
	public ParamSphere(double cx, double cy, double cz, double r, 
			double epsilon, int iHeight, int iWidth)
	{
		super();
		
		setBounds(iHeight, iWidth, epsilon);
		dRadius = r;
		dEpsilon = epsilon;
		iEpsInv = (int)(1/dEpsilon);
		
		dCenter[0] = cx;
		dCenter[1] = cy;
		dCenter[2] = cz;
		dCenter[3] = 1;

		
		Sphere3D = new double[iEpsInv+1][iEpsInv][4];
		
		int i = 0, j = 0;
		for (double v = 0; v < 1+dEpsilon; v += dEpsilon)
		{
			for (double u = 0; u < 1; u += dEpsilon)
			{
				Sphere3D[i][j][0] = x(u,v);
				Sphere3D[i][j][1] = y(u,v);
				Sphere3D[i][j][2] = z(u,v);
				Sphere3D[i][j][3] = 1;
				j++;
			}
			i++;
			j=0;
		}
	}

	public double x(double u, double v)
	{
		dTheta = 2 * Math.PI * u;
		dPhi = (Math.PI * v) - (Math.PI / 2);
		
		return dRadius * Math.cos(dTheta) * Math.cos(dPhi) + dCenter[0];
	}	

	public double y(double u, double v)
	{
		dPhi = (Math.PI * v) - (Math.PI / 2);
		
		return dRadius * Math.sin(dPhi) + dCenter[1];
	}	

	public double z(double u, double v)
	{
		dTheta = 2 * Math.PI * u;
		dPhi = (Math.PI * v) - (Math.PI / 2);
		
		return -1 * dRadius * Math.sin(dTheta) * Math.cos(dPhi) + dCenter[2];
	}
	
	public void draw(Graphics g, double dEpsilon, Color clr, int iLines)
		//will draw the entire parametric surface
		//keep a counter starting at 0, whenever drawquad is called, increment
		
		//this will not loop through u and v, this will go through the sphere
		//matrix and 
	{	
		double vector1[], vector2[], vector3[], vector4[];

		for (int i=0; i<iEpsInv; i++)
		{
			for (int j=0; j<iEpsInv; j++)
			{
				vector1	= getShape()[i][j];
				vector2	= getShape()[i+1][j];
				vector3 = getShape()[i+1][(j+1)%iEpsInv];
				vector4	= getShape()[i][(j+1)%iEpsInv];
				
		 		drawQuad(vector1, vector2, vector3, vector4, g, clr, dEpsilon, iLines);
		 	}
		}
	}
	
	public void setShape(double newSphere[][][])
	{
		for (int i=0; i<iEpsInv+1; i++)
			for (int j=0; j<iEpsInv; j++)
				Sphere3D[i][j] = newSphere[i][j];
	}
	
	public double[][][] getShape()
	{
		return Sphere3D;
	}
	
	public double[] getCenter()
	{
		return dCenter;
	}
	
	public double getRadius()
	{
		return dRadius;
	}
	
	public void setCenter(double newCenter[])
	{
		for (int i=0; i<4; i++)
			dCenter[i] = newCenter[i];
	}
	
	public boolean wasDrawn()
	{
		return bWasDrawn;
	}
	
	public void setDraw(boolean drawState)
	{
		bWasDrawn = drawState;
	}
}
