#include "Planet.h"

#define MAX_SIZE	30

GLUquadricObj *obj;  // 도형을 사용하기 위해
float Perspect,EyeToX,EyeToY,LookAtX,LookAtY = 0.0f;
float g_Ratio = 0.0f;

Planet g_Planet[MAX_SIZE];
char chTextureNameArray[11][50] = {"Sun.bmp", "Mercury.bmp", "Venus.bmp", "Earth.bmp", "Moon.bmp",
					"Mars.bmp", "Jupiter.bmp", "Saturn.bmp", "Uranus.bmp", "Neptune.bmp",
					"Pluto.bmp"};

float fRandom(int nValue)
{
	return (float)((rand() % nValue)-30);
}

float fRandom()
{
	return (float)((rand() % 4)+1);
}


void PlanetInit()
{
	for(int i = 0 ; i < MAX_SIZE ; i++)
	{
		g_Planet[i].SetPosition(GL3DVector(fRandom(60),fRandom(60),fRandom(1)));
		g_Planet[i].SetRadius(fRandom());
		g_Planet[i].SetSpeed(fRandom());
		g_Planet[i].SetTexture(chTextureNameArray[rand()%11]);
		g_Planet[i].SetLife(true);
		
	}	
}

void GLInit()
{
	// 재질과 광원 초기화
	GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };	
	GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };

	glClearColor(0.0, 0.0, 0.0, 0.0);

	// 도형사용 Quadric 초기화
	obj = gluNewQuadric();	
	gluQuadricDrawStyle(obj, GLU_FILL);
	gluQuadricNormals(obj, GL_SMOOTH);
	gluQuadricOrientation(obj, GLU_OUTSIDE);
	gluQuadricTexture(obj, GL_FALSE);

	glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialfv(GL_FRONT, GL_EMISSION, mat_specular);
	glMaterialf(GL_FRONT, GL_SHININESS, 50.0);
	
	PlanetInit();
	
	glEnable(GL_DEPTH_TEST);  // z버퍼 적용
	
}

void Display(void)
{
	GLfloat light_position[] = { 0.0, 0.0, 0.0, 1.0 };
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glColor3f (0.0, 0.0, 0.0);

	glLoadIdentity();
	glRotatef(15,0,1,0);

	for(int i = 0 ; i < MAX_SIZE ; i++)
	{
		
		if(g_Planet[i].GetLife())
		{
			int Num = i+101;
			glPushName(Num);
			glPushMatrix();
			glColor3ub(255, 255, 255);
			g_Planet[i].Update();
			g_Planet[i].Render();
			glPopMatrix();
			glPopName();
		}
	}
	
	glutSwapBuffers();
}

void ProcessSelect(GLuint index[64])
{
	
	g_Planet[index[3]-101].SetLife(false);
	//
	//switch(index[3]) {		
	//	case 101: MessageBox(NULL, "반지름(Km) : 695,500\n질량(10*24승 Kg) : 1,989,000\n밀도(g/cm3) : 1.41\n중력(지구=1) : 28\n자전주기 : 25.4일\n공전주기 : -", "태양", MB_OK); break;		
	//	case 102: MessageBox(NULL, "반지름(Km) : 2439.7\n질량(10*24승 Kg) : 0.330\n밀도(g/cm3) : 5.43\n중력(지구=1) : 0.38\n자전주기 : 58.6일\n공전주기 : 88.0일", "수성", MB_OK); break;
	//	case 103: MessageBox(NULL, "반지름(Km) : 6051.8\n질량(10*24승 Kg) : 4.87\n밀도(g/cm3) : 5.24\n중력(지구=1) : 0.91\n자전주기 : 243일\n공전주기 : 224.7일", "금성", MB_OK); break;		
	//	case 104: MessageBox(NULL, "반지름(Km) : 6378.1\n질량(10*24승 Kg) : 5.97\n밀도(g/cm3) : 5.52\n중력(지구=1) : 1.00\n자전주기 : 23.93시간\n공전주기 : 365.24일", "지구", MB_OK); break;		
	//	case 105: MessageBox(NULL, "반지름(Km) : 3397\n질량(10*24승 Kg) : 0.642\n밀도(g/cm3) : 3.93\n중력(지구=1) : 0.38\n자전주기 : 24.62시간\n공전주기 : 1.88년", "화성", MB_OK); break;		
	//	case 106: MessageBox(NULL, "반지름(Km) : 71492\n질량(10*24승 Kg) : 1899\n밀도(g/cm3) : 1.33\n중력(지구=1) : 2.14\n자전주기 : 9.93시간\n공전주기 : 11.86년", "목성", MB_OK); break;		
	//	case 107: MessageBox(NULL, "반지름(Km) : 60268\n질량(10*24승 Kg) : 568\n밀도(g/cm3) : 0.69\n중력(지구=1) : 0.74\n자전주기 : 10.7시간\n공전주기 : 29.4년", "토성", MB_OK); break;		
	//	case 108: MessageBox(NULL, "반지름(Km) : 25559\n질량(10*24승 Kg) : 86.8\n밀도(g/cm3) : 1.27\n중력(지구=1) : 0.86\n자전주기 : 17.2시간\n공전주기 : 84.0년", "천왕성", MB_OK); break;		
	//	case 109: MessageBox(NULL, "반지름(Km) : 24764\n질량(10*24승 Kg) : 102\n밀도(g/cm3) : 1.64\n중력(지구=1) : 1.10\n자전주기 : 16.1시간\n공전주기 : 164.8년", "해왕성", MB_OK); break;		
	//	case 110: MessageBox(NULL, "반지름(Km) : 1151\n질량(10*24승 Kg) : 0.013\n밀도(g/cm3) : 2.0\n중력(지구=1) : 0.08\n자전주기 : 6.4일\n공전주기 : 247.9년", "명왕성", MB_OK); break;		

	//	default:
	//		MessageBox(NULL, "What?", "Selection", MB_OK);
	//		printf("인덱스 %d\n", index[3]);
	//		break;
	//}
	
}

void SelectObjects(GLint x, GLint y) 
{
	GLuint selectBuff[64];
	GLint hits, viewport[4];

	glSelectBuffer(64, selectBuff);
	glGetIntegerv(GL_VIEWPORT, viewport);
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glRenderMode(GL_SELECT);
	glLoadIdentity();
	gluPickMatrix(x, viewport[3]-y, 2, 2, viewport);
	gluPerspective(45.0f,g_Ratio,0.2f,1000.0f);
	glMatrixMode(GL_MODELVIEW);
	//glLoadIdentity();
	Display();
	hits = glRenderMode(GL_RENDER);
	if(hits>0) ProcessSelect(selectBuff);
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
}


void Reshape(int w, int h)
{
	glViewport (0, 0, (GLsizei) w, (GLsizei) h);
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();

	g_Ratio = (GLfloat) w/(GLfloat) h;

	gluPerspective(45.0f, (GLfloat) w/(GLfloat) h, 0.2, 1000.0);
	glMatrixMode(GL_MODELVIEW);	
	glLoadIdentity();
	gluLookAt (EyeToX, EyeToY, 200.0 , LookAtX, LookAtY, 0.0, 0.0, 1.0, 0.0);
}

void UpdateDisplay()
{	
	glutPostRedisplay();
}

void mouse(int button, int state, int x, int y) 
{
	switch (button) 
	{
	case GLUT_LEFT_BUTTON:
		if (state == GLUT_DOWN)
			SelectObjects(x,y);
		break;
	case GLUT_MIDDLE_BUTTON:
	case GLUT_RIGHT_BUTTON:
		if (state == GLUT_DOWN)
			glutIdleFunc(NULL);	
		break;
	default:
		break;
	}
}
void main(int argc, char** argv)
{
	srand(timeGetTime());
	glutInit(&argc, argv);	
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
	glutInitWindowSize (1024, 768);	
	glutInitWindowPosition (0, 0);
	glutCreateWindow ("OutSider : Solar System");
	GLInit();

	glutDisplayFunc(Display);
	glutReshapeFunc(Reshape);
	glutMouseFunc(mouse);

	glutIdleFunc(UpdateDisplay);
	glutMainLoop();
	gluDeleteQuadric(obj);

}