// SpectrumSphere.vtx
// Author - morte0815

float time = 0;
float rx,rxamt,ry,ryamt;

float[] org_coordsX(70);
float[] org_coordsY(70);
float[] org_coordsZ(70);
float[] org_colorR(70);
float[] org_colorG(70);
float[] org_colorB(70);

float stacks = 8;
float segments = 8;

float velX,velY,velZ;
float posX,posY,posZ;
float signX,signY,signZ;
Map	map;

int x,y;

void Init()
{
  velX= 0;
  velY= 0;
  velZ = 0;
  posX= 0;
  posY= 0;
  posZ = 0;
  posX= 0;
  posY= 0;
  posZ = 0;
  signX= 1;
  signY= 1;
  signZ = 1;

  if(BASS < 0.2f){signZ = 1;}
  if(MIDDLE < 0.2f){signY = -1;}
  if(TREBLE < 0.2f){signX = -1;}
  
  for (int i = 0; i< stacks; i++)
  {
    float temp = Cos(3.14159f/6.0f*i-3.14159f/2.0f);
    for (int j = 0; j < segments; j++)
    {
      org_coordsY[Fabs(i*segments+j)] = Sin(3.14159f/6.0f*i-3.14159f/2.0f);
      org_coordsX[Fabs(i*segments+j)] = Cos(2*3.14159f/segments*j) * temp;
      org_coordsZ[Fabs(i*segments+j)] = Sin(2*3.14159f/segments*j) * temp;
    }
  }
  for (int i = 0; i< stacks; i++)
  {
    for (int j = 0; j< segments; j++)
    {
      org_colorR[i*segments+j] = Sin(i);
      org_colorG[i*segments+j] = Sin(j);
      org_colorB[i*segments+j] = 1-Sin(j);
    }
  }
  
  
  


}

void RenderSphere()
{
  float addX=0;
  float addY=0;
  float addZ=0;
  float scale = 0.5f;
  float colorVal = 0;
  gfxBegin(PRIM_TRIANGLELIST);
    for (int i = 0; i< stacks-2; i++)
    {
      for (int j = 0; j< segments; j++)
      {
        float temp = i*segments+j;
        addX = GetSpec(Fabs(temp/2)) * org_coordsX[temp]*scale;
        addY = GetSpec(Fabs(temp/2)) * org_coordsY[temp]*scale;
        addZ = GetSpec(Fabs(temp/2)) * org_coordsZ[temp]*scale;
        colorVal = GetSpec(Fabs(temp/2));
        
        
        gfxColour(org_colorR[temp],org_colorG[temp] ,org_colorB[temp] ,1);
        gfxVertex(org_coordsX[temp] + addX,org_coordsY[temp] + addY,org_coordsZ[temp] + addZ);
        
        temp = (i+1)*segments+((j+1)%segments);
        gfxVertex(org_coordsX[temp] + addX,org_coordsY[temp] + addY,org_coordsZ[temp] + addZ);
        
        temp = i*segments+((j+1)%segments);
        gfxVertex(org_coordsX[temp] + addX,org_coordsY[temp] + addY,org_coordsZ[temp] + addZ);
        
        temp = i*segments+j;
        addX = GetSpec(Fabs(temp/2)) * org_coordsX[temp]*scale;
        addY = GetSpec(Fabs(temp/2)) * org_coordsY[temp]*scale;
        addZ = GetSpec(Fabs(temp/2)) * org_coordsZ[temp]*scale;
        colorVal = GetSpec(Fabs(temp/2));
        
        gfxColour(org_colorR[temp],org_colorG[temp],org_colorB[temp],1);
        gfxVertex(org_coordsX[temp] + addX,org_coordsY[temp] + addY,org_coordsZ[temp] + addZ);
        
        temp = (i+1)*segments+j;
        gfxVertex(org_coordsX[temp] + addX,org_coordsY[temp] + addY,org_coordsZ[temp] + addZ);
        
        temp = (i+1)*segments+((j+1)%segments);
        gfxVertex(org_coordsX[temp] + addX,org_coordsY[temp] + addY,org_coordsZ[temp] + addZ);
      }
    }
  gfxEnd();
}

void PushAround()
{
    if (Abs(BASS) > 0.3f){velZ += BASS*3.0f;}
    if (Abs(BASS) < 0.3f){velZ -= BASS*3.0f;}
    if (Abs(MIDDLE) > 0.3f){velY += MIDDLE*3.0f;}
    if (Abs(MIDDLE) < 0.3f){velY -= MIDDLE*3.0f;}
    if (Abs(TREBLE) > 0.3f){velX += TREBLE*3.0f;}
    if (Abs(TREBLE) < 0.3f){velX -= TREBLE*3.0f;}
    
   velX = Clamp(velX,-3.0f,3.0f);
  velY = Clamp(velY,-3.0f,3.0f);
  velZ = Clamp(velZ,-3.0f,3.0f);
  
  posX += signX*velX*TIMEPASS;
  posY += signY*velY*TIMEPASS;
  posZ += signZ*velZ*TIMEPASS;
  
  if (posX < -4 || posX > 4){signX = -signX;}
  if (posY < -4 || posY > 4){signY = -signY;}
  if (posZ < -4 || posZ > 4){signZ = -signZ;}
  
  gfxTranslate(posX,posY,posZ);
 
}

void Render()
{
    time += TIMEPASS;
    for (y=0;y<24;y=y+1)
    	{
    		for (x=0;x<32;x=x+1)
    		{
    		  float dx = (x-16);
    		  float dy = (y-12);
    		  float s = Mag(dx,dy)/Mag(16,12);
    		  if (s == 0)
    		  {
    		    map.SetValues(x, y, 0.1, 0.1, 0.8,0.8, 0.8);
          }
    			map.SetValues(x, y, dx*s*0.1*Fabs(BASS), dy*s*0.1*Fabs(BASS), 0.8,0.8, 0.8);
    		}
    	
    	}
  	map.Render();
  
  	gfxSetRenderTarget(map);
  	gfxPushMatrix();
    gfxTranslate(0,0,15);
	
    PushAround();                                   

    if (BASS>0.3) ryamt = 1;
  	if (BASS<-0.3) ryamt = -1;
		ry = ry + (ryamt*TIMEPASS);

  	gfxRotate(ry*90,0,1,0);

		
		RenderSphere();
		
		gfxPopMatrix();

  	gfxSetRenderTarget(0);
  	gfxSetEnvTexture(NULL);
  	gfxSetTexture(map);
  
  	gfxSetAspect(0);
  	gfxTranslate(0, 0, 2.414);
  	gfxColour(1, 1, 1, 1);
  	gfxTexRect(-1, 1, 1, -1);   
}
