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;
	double dEpsilon;
	double dCenter[] = new double[4];
	double Sphere3D[][];
	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);
		dRadius = r;
		dEpsilon = epsilon;
		
		dCenter[0] = cx;
		dCenter[1] = cy;
		dCenter[2] = cz;
		dCenter[3] = 1;

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

	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, int width, int height, 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 
	{	
		int iBound = (int)((1.0/dEpsilon)*(1.0/dEpsilon));
		
		double vector1[], vector2[], vector3[], vector4[];
		
		int len = getShape().length;
		
		for (int i=0; i<(len-(1/dEpsilon)); i++)
		{
			vector1	= getShape()[i];
			if (((i+1)%(1/dEpsilon)) == 0)
			{
				vector2	= getShape()[(int)(i+1-(1/dEpsilon))%len];
				vector3 = getShape()[(i+1)%len];
			}
			else
			{
				vector2	= getShape()[(int)((i+1)%len)];
				vector3	= getShape()[(int)(((i+1)+(1/dEpsilon))%len)];
			}
			vector4	= getShape()[(int)((i+(1/dEpsilon))%len)];
			
	 		drawQuad(vector1, vector2, vector3, vector4, g, clr, dEpsilon, iLines);
		}
	}
	
	public void setShape(double newSphere[][])
	{
		int len = newSphere.length;
		for (int i=0; i<len; i++)
			Sphere3D[i] = newSphere[i];
	}
	
	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;
	}
}
