
#include "include/glut.h"
#include <stdlib.h>
#include "core.h"
#include "wrapglut.h"
#include "starfield.h"



void CStarfield::Init(int numstars,float scale)
{
	if (numstars>0)
	{
		m_fScaleX=scale;
		m_fScaleY=scale;
		m_fScaleZ=scale;
		m_intNumStars=numstars;
		if (m_pStar!=NULL) delete [] m_pStar;
		m_pStar = new CStar[m_intNumStars];
	}
}

void CStarfield::Init(int numstars,float scalex,float scaley,float scalez)
{
	if (numstars>0)
	{
		m_fScaleX=scalex;
		m_fScaleY=scaley;
		m_fScaleZ=scalez;
		m_intNumStars=numstars;
		if (m_pStar!=NULL) delete [] m_pStar;
		m_pStar = new CStar[m_intNumStars];
	}
}

void CStarfield::SetRotate(float rotx,float roty,float rotz)
{
	m_fRot[0]=rotx;
	m_fRot[1]=roty;
	m_fRot[2]=rotz;
	/*for (int i=0; i<m_intNumStars; i++)
	{
		m_pStar[i].Rotate(rotx,roty,rotz);
	}*/
}

void CStarfield::SetVelocity(float x,float y,float z)
{
	int i;
	for (i=0; i<m_intNumStars; i++)
	{
		m_pStar[i].SetVelocity(x,y,z);
	}
	for (i=0; i<m_intNumAttractors; i++)
	{
		m_pAttractor[i].SetVelocity(x,y,z);
	}
	for (i=0; i<m_intNumRepellers; i++)
	{
		m_pRepeller[i].SetVelocity(x,y,z);
	}
}

void CStarfield::SetForce(float x,float y,float z)
{
	int i;
	for (i=0; i<m_intNumStars; i++)
	{
		m_pStar[i].SetForce(x,y,z);
	}
	for (i=0; i<m_intNumAttractors; i++)
	{
		m_pAttractor[i].SetForce(x,y,z);
	}
	for (i=0; i<m_intNumRepellers; i++)
	{
		m_pRepeller[i].SetForce(x,y,z);
	}
}

void CStarfield::SetStarTexture(char *filename)
{
	m_pStarSurface.LoadTGARAR(filename);
	m_intStarGLIndex=GetFreeTextureIndex();
	m_pStarSurface.Bind(m_intStarGLIndex);	
}


void CStarfield::Randomise()
{
	int i;
	for (i=0; i<m_intNumStars; i++)
	{
		m_pStar[i].SetPosition(frand()*m_fScaleX,frand()*m_fScaleY,frand()*m_fScaleZ);
		m_pStar[i].SetVelocity(frand(),frand(),frand());
		m_pStar[i].SetColor(f2rand(),f2rand(),f2rand());
	}
	for (i=0; i<m_intNumAttractors; i++)
	{
		m_pAttractor[i].SetPosition(frand()*m_fScaleX,frand()*m_fScaleY,frand()*m_fScaleZ);
		m_pAttractor[i].SetVelocity(frand(),frand(),frand());
		m_pAttractor[i].SetColor(f2rand(),f2rand(),f2rand());
	}
	for (i=0; i<m_intNumRepellers; i++)
	{
		m_pRepeller[i].SetPosition(frand()*m_fScaleX,frand()*m_fScaleY,frand()*m_fScaleZ);
		m_pRepeller[i].SetVelocity(frand(),frand(),frand());
		m_pRepeller[i].SetColor(f2rand(),f2rand(),f2rand());
	}
}


void CStarfield::CreateAttractors(int num)
{
	if (num>0)
	{
		m_intNumAttractors=num;
		if (m_pAttractor!=NULL) delete [] m_pAttractor;
		m_pAttractor = new cAttractor[m_intNumAttractors];
	}
}

void CStarfield::CreateRepellers(int num)
{
	if (num>0)
	{
		m_intNumRepellers=num;
		if (m_pRepeller!=NULL) delete [] m_pRepeller;
		m_pRepeller = new cRepeller[m_intNumRepellers];
	}
}


void CStarfield::Update(float time)
{
	int i,j;
	for (i=0; i<m_intNumStars; i++)
	{
		for (j=0; j<m_intNumAttractors; j++)
		{
			m_pStar[i].GravityAttract(
				m_pAttractor[j].GetX(),
				m_pAttractor[j].GetY(),
				m_pAttractor[j].GetZ(),
				m_pAttractor[j].GetMass());
		}
		
		for (j=0; j<m_intNumRepellers; j++)
		{
			m_pStar[i].GravityRepel(
				m_pRepeller[j].GetX(),
				m_pRepeller[j].GetY(),
				m_pRepeller[j].GetZ(),
				m_pRepeller[j].GetMass());
		}
		m_pStar[i].Update(time);
		if (wrap) m_pStar[i].Wrap(m_fScaleX,m_fScaleY,m_fScaleZ);
		//m_pStar[i].Wall(m_fScaleX,m_fWallDamping);
	}

	for (i=0; i<m_intNumRepellers; i++)
	{
		m_pRepeller[i].Update(time);
		m_pRepeller[i].Wrap(m_fScaleX,m_fScaleY,m_fScaleZ);
	}
	for (i=0; i<m_intNumAttractors; i++)
	{
		m_pAttractor[i].Update(time);
		m_pAttractor[i].Wrap(m_fScaleX,m_fScaleY,m_fScaleZ);
		//m_pAttractor[i].Wall(m_fScaleX,m_fWallDamping/5);
	}
}

void CStarfield::Draw()
{
	int i;

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(0,0,-50);
	glRotatef(m_fRot[0],1,0,0);
	glRotatef(m_fRot[1],0,1,0);
	glRotatef(m_fRot[2],0,0,1);
	m_pStarSurface.Bind(m_intStarGLIndex);

	glDisable(GL_DEPTH_TEST);
	glEnable(GL_BLEND);
	glDisable(GL_LIGHTING);
	glDisable(GL_COLOR_MATERIAL);
	glEnable(GL_TEXTURE_2D);
	for (i=0; i<m_intNumStars; i++)
	{
		m_pStar[i].Draw();
	}

	//glutWireCube(m_fScale);
	//glEnable(GL_BLEND);
	//glColor4f(0.2,0.2,0.3,0.2);
	//glutSolidCube(m_fScale);

	/*glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(0,0,-150);
	glRotatef(m_fRot[0],1,0,0);
	glRotatef(m_fRot[1],0,1,0);
	glRotatef(m_fRot[2],0,0,1);
	for (i=0; i<m_intNumAttractors; i++)
	{
		m_pAttractor[i].Draw();
	}
	for (i=0; i<m_intNumRepellers; i++)
	{
		m_pRepeller[i].Draw();
	}*/
}


CStarfield::CStarfield()
{
	m_pStar=NULL;
	m_intNumStars=0;
	m_fScaleX=0;
	m_fScaleY=0;
	m_fScaleZ=0;
	m_fRot[0]=0;
	m_fRot[1]=0;
	m_fRot[2]=0;
	m_fWallDamping=0.8;
	m_pAttractor=NULL;
	m_intNumAttractors=0;
	m_pRepeller=NULL;
	m_intNumRepellers=0;
}

CStarfield::~CStarfield()
{
	if (m_pStar!=NULL) delete [] m_pStar;
	m_pStar=NULL;
	m_intNumStars=0;
	m_fScaleX=0;
	m_fScaleY=0;
	m_fScaleZ=0;
	m_fRot[0]=0;
	m_fRot[1]=0;
	m_fRot[2]=0;
	m_fWallDamping=1;
	if (m_pAttractor!=NULL) delete [] m_pAttractor;
	m_pAttractor=NULL;
	m_intNumAttractors=0;
	if (m_pRepeller!=NULL) delete [] m_pRepeller;
	m_pRepeller=NULL;
	m_intNumRepellers=0;
}


