#include <windows.h>		
#include <gl/gl.h>			
#include <gl/glu.h>			
#include <gl/glaux.h>		
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <GL/glut.h>

typedef float VertexArray[3];
typedef float NormalArray[3];
typedef float TextureCoordsArray[2];

GLfloat size=100.0;
GLint N=6;

HDC			hDC=NULL;		
HGLRC		hRC=NULL;		
HWND		hWnd=NULL;		
HINSTANCE	hInstance;		

bool	keys[256];			
bool	active=TRUE;		
bool	fullscreen=TRUE;	
bool	light=true;
bool	textures=true;
enum	TypeTexture{TEXTURES=1, TEXTURES1=2};
int		textureType= TEXTURES;
bool	textures1=true;
bool	wire= true;
bool	wire1= true;
bool	click=false;

static int  R = 10, R1 = 10, R2=-22; 
static double  self_sun = 0.68, gong_earth = 7, self_earth = 1, gong_moon = 10, 
           self_mercury = 58.6 ,gong_mercury = 200, self_venus = -243, gong_venus = 4, self_mars = 1.0, gong_mars = 80, self_jupiter = 0.41, gong_jupiter = 150,
		   self_saturn = 0.44 ,gong_saturn = 60, self_uranus=0.71, gong_uranus = 300, self_neptune = 0.67, gong_neptune = 20, self_pluto = 6.3, gong_pluto = 110,
           gong_saturn2 = 60, gong_gori = 10; // 행성 위치

GLuint tex[12]; //텍스쳐 매핑을 위해 그림이 들어갈 공간선언


GLUquadricObj *obj;
GLfloat ratio;

GLfloat	xTheta=22.5, yTheta=0., zTheta=0.;
GLfloat	scale=1.0;
int mouseX=0;
int mouseY=0;
int x, y;
int windowWidth;
AUX_RGBImageRec *texture[12];

const double PI     = 3.14159265358979f;
const double TWOPI  = 6.28318530717958f;
const double PIDIV2 = 1.57079632679489f;


LRESULT	CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);	


AUX_RGBImageRec *LoadBMPFile(char *filename)
{
	FILE *hFile = NULL;
	if(!filename) return NULL;
		hFile = fopen(filename, "r");
	if(hFile) 
	{
		fclose(hFile);
		return auxDIBImageLoad(filename);
	}   
	return NULL;
}

void loadtexture()
{	
	int i;
	 AUX_RGBImageRec *texRec[13];
	 memset(texRec, 0, sizeof(void *)*13);
   
	 if((texRec[0]=LoadBMPFile("Sun.bmp")) &&  // 그림의 파일을 8비트 단위로 맞춰 넣는다.
		(texRec[1]=LoadBMPFile("Mercury.bmp")) && // texRec[] 각각의 그림파일을 넣는다.
		(texRec[2]=LoadBMPFile("Venus.bmp")) &&
		(texRec[3]=LoadBMPFile("earth.bmp")) &&
		(texRec[4]=LoadBMPFile("Moon.bmp")) &&
		(texRec[5]=LoadBMPFile("Mars.bmp")) &&
		(texRec[6]=LoadBMPFile("Jupiter.bmp")) &&
		(texRec[7]=LoadBMPFile("Saturn.bmp")) &&
		(texRec[8]=LoadBMPFile("Uranus.bmp")) &&
		(texRec[9]=LoadBMPFile("Neptune.bmp")) &&
		(texRec[10]=LoadBMPFile("pluto.bmp")) &&
		(texRec[11]=LoadBMPFile("Saturn2.bmp")) &&
		(texRec[12]=LoadBMPFile("Space.bmp")))
		{
			glGenTextures(13, &tex[0]);
			for( i=0; i<13; i++) 
			{
			   glBindTexture(GL_TEXTURE_2D, tex[i]);
			   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			   glTexImage2D(GL_TEXTURE_2D, 0, 3, texRec[i]->sizeX, texRec[i]->sizeY, 0,GL_RGB, GL_UNSIGNED_BYTE,texRec[i]->data);
			}
		}
		for( i=0; i<13; i++) 
		{
			if(texRec[i]) 
			{
				if(texRec[i]->data) free(texRec[i]->data);
				free(texRec[i]);
			} 
		}   
		glEnable(GL_TEXTURE_2D);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}


void myAxis(void)
{
	int i;

	glColor3f(.98,.04,.70);
	glutWireCube(size*2.0);
	glBegin(GL_LINES);
	for(i=0;i<=N;i++)
	{
		//glVertex2f(-size*2, 0*i*size/N, -size);
		//glVertex2f(-size*2, 0*i*size/N, size);
		glVertex2f(-size, -size+2.0*i*size/N);
		glVertex2f(size, -size+2.0*i*size/N);
	}
	glEnd();
	glColor3f(.25,.25,.25);
	glBegin(GL_LINES);
	{
		glVertex2f(0, -size);
		glVertex2f(0, size);
		glVertex2f(-size, 0);
		glVertex2f(size,0);
	}
	
	glEnd();

}


void TexturesInit()
{
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
				
		
		glNewList(1, GL_COMPILE);
		texture[0] = auxDIBImageLoad("Sun.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[0]->sizeX, texture[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[0]->data);
		glEndList();
		
		glNewList(2, GL_COMPILE);
		texture[1] = auxDIBImageLoad("Mercury.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[1]->sizeX, texture[1]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[1]->data);
		glEndList();
		
		glNewList(3, GL_COMPILE);
		texture[2] = auxDIBImageLoad("Venus.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[2]->sizeX, texture[2]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[2]->data);
		glEndList();
		
		glNewList(4, GL_COMPILE);
		texture[3] = auxDIBImageLoad("earth.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[3]->sizeX, texture[3]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[3]->data);
		glEndList();
		
		glNewList(5, GL_COMPILE);
		texture[4] = auxDIBImageLoad("Moon.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[4]->sizeX, texture[4]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[4]->data);
		glEndList();

		glNewList(6, GL_COMPILE);
		texture[5] = auxDIBImageLoad("Mars.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[5]->sizeX, texture[5]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[5]->data);
		glEndList();

		glNewList(7, GL_COMPILE);
		texture[6] = auxDIBImageLoad("Jupiter.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[6]->sizeX, texture[6]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[6]->data);
		glEndList();

		glNewList(8, GL_COMPILE);
		texture[7] = auxDIBImageLoad("Saturn.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[7]->sizeX, texture[7]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[7]->data);
		glEndList();

		glNewList(9, GL_COMPILE);
		texture[8] = auxDIBImageLoad("Uranus.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[8]->sizeX, texture[8]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[8]->data);
		glEndList();

		glNewList(10, GL_COMPILE);
		texture[9] = auxDIBImageLoad("Neptune.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[9]->sizeX, texture[9]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[9]->data);
		glEndList();

		glNewList(11, GL_COMPILE);
		texture[10] = auxDIBImageLoad("Pluto.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[10]->sizeX, texture[10]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[10]->data);
		glEndList();

		glNewList(11, GL_COMPILE);
		texture[11] = auxDIBImageLoad("Saturn2.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[10]->sizeX, texture[11]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[11]->data);
		glEndList();


		glNewList(12, GL_COMPILE);
		texture[11] = auxDIBImageLoad("Space.bmp");
		glTexImage2D(GL_TEXTURE_2D, 0, 3, texture[11]->sizeX, texture[11]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[11]->data);
		glEndList();
}

void spinDisplay(void)//행성들의 공전 속도
{
	if (active)
	{
		self_sun = self_sun + 0.68;
		gong_mercury = gong_mercury + 1.8; if (gong_mercury>359.95f) gong_mercury=0.0f;
		self_mercury = self_mercury + 58.6;
		gong_venus = gong_venus + 1.4; if (gong_venus>359.95f) gong_venus=0.0f;
		self_venus = self_venus + 243.01;
		gong_earth = gong_earth + 1.0; if (gong_earth>359.95f) gong_earth=0.0f;
		self_earth = self_earth + 1.0; //자전속도
		gong_moon = gong_moon + 1.5; if (gong_moon>359.95f) gong_moon=0.0f;
		gong_mars = gong_mars + 1.35; if (gong_mars>359.95f) gong_mars=0.0f;
		self_mars = self_mars + 1.1;
		gong_jupiter = gong_jupiter + 1.3; if (gong_jupiter>359.95f) gong_jupiter=0.0f;
		self_jupiter = self_jupiter + 0.41;
		gong_saturn = gong_saturn + 1.2; if (gong_saturn>359.95f) gong_saturn=0.0f;
		self_saturn = self_saturn + 1.44;
		gong_saturn2 = gong_saturn2 + 1.2; if (gong_saturn2>359.95f) gong_saturn2=0.0f;
		gong_uranus = gong_uranus + 1.1; if (gong_uranus>359.95f) gong_uranus=0.0f;
		self_uranus = self_uranus + 0.71;
		gong_neptune = gong_neptune + 0.9; if (gong_neptune>359.95f) gong_neptune=0.0f;
		self_neptune = self_neptune + 0.67;
		gong_pluto = gong_pluto + 0.8; if (gong_pluto>359.95f) gong_pluto=0.0f;
		self_pluto = self_pluto + 6.3;
		gong_gori = gong_gori + 1.0;  if (gong_gori>359.95f) gong_gori=0.0f;

	}
	
}
GLvoid ReSizeGLScene(GLsizei width, GLsizei height)		
{
	if (height==0)										
	{
		height=1;										
	}

	glViewport(0,0,width,height);						

	glMatrixMode(GL_PROJECTION);						
	glLoadIdentity();									

	
	ratio = (GLfloat)width/(GLfloat)height;
	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

	glMatrixMode(GL_MODELVIEW);							
	glLoadIdentity();									
}

bool InitGL(GLvoid)										
{	
	obj = gluNewQuadric();	
	loadtexture();

	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);		
	
	glEnable(GL_NORMALIZE);

	glShadeModel(GL_SMOOTH);
	
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
	

	
	glClearDepth(1.0f);									
	glEnable(GL_DEPTH_TEST);						
	glEnable(GL_COLOR_MATERIAL);	
	
	glDepthFunc(GL_LEQUAL);								
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	
	
    gluQuadricNormals(obj, GLU_SMOOTH);
    gluQuadricOrientation(obj, GLU_OUTSIDE);
    gluQuadricTexture(obj, GL_FALSE);
	
	glEnable(GL_LIGHTING);	

    glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);	
    glEnable(GL_COLOR_MATERIAL);
	TexturesInit();
	glEnable(GL_TEXTURE_2D);

	return true;	
}

void renderSphere( float cx, float cy, float cz, float r, int p )
{
	int i, j;	

	double theta1 = 0.0;
	double theta2 = 0.0;
	double theta3 = 0.0;

	double ex = 0.0f;
	double ey = 0.0f;
	double ez = 0.0f;

	double px = 0.0f;
	double py = 0.0f;
	double pz = 0.0f;

	// Disallow a negative number for radius.
	if( r < 0 )
		r = -r;

	// Disallow a negative number for precision.
	if( p < 0 )
		p = -p;

	// If the sphere is too small, just render a OpenGL point instead.
	if( p < 4 || r <= 0 ) 
	{
		glBegin( GL_POINTS );
		glVertex3f( cx, cy, cz );
		glEnd();
		return;
	}

    for(i = 0; i < p/2; ++i ) 
	{
        theta1 = i * TWOPI / p - PIDIV2;
        theta2 = (i + 1) * TWOPI / p - PIDIV2;

        glBegin(GL_TRIANGLE_STRIP); 
        {
            for(j = 0; j <= p; ++j )
            {
                theta3 = j * TWOPI / p;

                ex = cos(theta2) * cos(theta3);
                ey = sin(theta2);
                ez = cos(theta2) * sin(theta3);
                px = cx + r * ex;
                py = cy + r * ey;
                pz = cz + r * ez;

                glNormal3f( ex, ey, ez );
                glTexCoord2f( -(j/(float)p) , 2*(i+1)/(float)p );
                glVertex3f( px, py, pz );

                ex = cos(theta1) * cos(theta3);
                ey = sin(theta1);
                ez = cos(theta1) * sin(theta3);
                px = cx + r * ex;
                py = cy + r * ey;
                pz = cz + r * ez;

                glNormal3f( ex, ey, ez );
                glTexCoord2f( -(j/(float)p), 2*i/(float)p );
                glVertex3f( px, py, pz );
            }
        }
        glEnd();
	}
}

int DrawGLScene(GLvoid)									
{
	if(wire1)	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);	
	if(!wire1)	glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);


    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	if(!textures)	glDisable(GL_TEXTURE_2D);
	if(textures)	glEnable(GL_TEXTURE_2D);
	
	if(!light)	glDisable(GL_LIGHTING);
	if(light)	glEnable(GL_LIGHTING);

	glLoadIdentity();	
	spinDisplay();	
	glInitNames();

	glPushMatrix();	
	glTranslatef(0.0f, 0.0f, -22.0f);
	glRotatef(xTheta, 1.0, 0.0, 0.0);
	glRotatef(yTheta, 0.0, 1.0, 0.0);
	glRotatef(zTheta, 0.0, 0.0, 1.0);
	glScalef(scale, scale, scale);
	

	glPushName(101);	// 태양
	glPushMatrix();		
		glRotatef((GLfloat) self_sun, 0.0, 1.0, 0.0);
		switch(textureType)
		{
		case TEXTURES:			
			glBindTexture(GL_TEXTURE_2D, tex[0]); // tex[0]이 태양						
			renderSphere(0.0, 0.0, 0.0, 0.6, 100 ); // x, y, z, 반지름, 정밀도								
			break;
		case TEXTURES1:
			glCallList(1);
			gluQuadricTexture(obj, GL_TRUE);
			gluSphere(obj, 0.6f, 100, 100);
			break;		
		}				
	glPopMatrix();
	glPopName();	
	
	glPushName(102);	// 수성
	glPushMatrix();	
		glRotatef ((GLfloat) gong_mercury, 0.0, 1.0, 0.0);
		glTranslatef (1.0, 0.0, 0.0);
		glRotatef((GLfloat) self_mercury, 0.0, 1.0, 0.0);
		switch(textureType)
		{
		case TEXTURES:
			glBindTexture(GL_TEXTURE_2D, tex[1]); 
			renderSphere(0.0, 0.0, 0.0, 0.13, 100 ); 
			break;
		case TEXTURES1:
			glCallList(2);
			gluQuadricTexture(obj, GL_TRUE);
			gluSphere(obj, 0.13f, 100, 100);
			break;
		}	
	glPopMatrix();	
	glPopName();

	glPushMatrix();//수성궤도
		glColor3ub(255, 255, 255);
		glRotatef (90.0, 1.0, 0.0, 0.0);
		gluDisk(obj, 1.0, 0, 100, 1);// 궤도 좌표(위치)
	glPopMatrix();
	

	glPushName(103);
	glPushMatrix();	//금성		
		glColor3f (1.0, 1.0, 1.0);
		glRotatef ((GLfloat) gong_venus, 0.0, 1.0, 0.0);
		glTranslatef (2, 0.0, 0.0);
		glRotatef((GLfloat) self_venus, 0.0, 1.0, 0.0);
		switch(textureType)
		{
		case TEXTURES:
			glBindTexture(GL_TEXTURE_2D, tex[2]); 
			renderSphere(0.0, 0.0, 0.0, 0.22, 30 ); 		
			break;
		case TEXTURES1:
			glCallList(3);
			gluQuadricTexture(obj, GL_TRUE);
			gluSphere(obj, 0.22f, 100, 100);
			break;
		}			
	glPopMatrix();
	glPopName();


	glPushMatrix();	//금성궤도
		glColor3ub(255, 255, 255);
		glRotatef (90.0, 1.0, 0.0, 0.0);
		gluDisk(obj, 2, 0, 100, 1);	
	glPopMatrix();

	
	glPushName(104);
	glPushMatrix();//지구
		glColor3f (1.0, 1.0, 1.0);		
		glRotatef ((GLfloat) gong_earth, 0.0, 1.0, 0.0);
		glTranslatef (3, 0.0, 0.0);
		glRotatef ((GLfloat) self_earth, 0.0, 1.0, 0.0);		
		switch(textureType)
		{
		case TEXTURES:			
			glBindTexture(GL_TEXTURE_2D, tex[3]); 			
			renderSphere(0.0, 0.0, 0.0, 0.2, 30 );
			break;
		case TEXTURES1:
			glCallList(4);
			gluQuadricTexture(obj, GL_TRUE);
			gluSphere(obj, 0.2f, 100, 100);
			break;
		}
		
		
			//달
			glRotatef ((GLfloat) gong_moon, 0.0, 1.0, 0.0);
			glTranslatef (0.4, 0.0, 0.0);
			switch(textureType)
				{
				case TEXTURES:
					glBindTexture(GL_TEXTURE_2D, tex[4]); 
					renderSphere(0.0, 0.0, 0.0, 0.07, 30 );
					break;
				case TEXTURES1:
					glCallList(5);
					gluQuadricTexture(obj, GL_TRUE);
					gluSphere(obj, 0.07f, 100, 100);
					break;
				}
	glPopMatrix();
	glPopName();

	glPushMatrix();//달궤도		
		glColor3ub(255, 255, 255);
		glRotatef ((GLfloat) gong_gori, 0.0, 1.0, 0.0);
		glTranslatef (3, 0.0, 0.1);
		glRotatef (90.0, 1.0, 0.0, 0.0);
		gluDisk(obj, 0.4, 0, 100, 1);		
	glPopMatrix();

	glPushMatrix();//지구궤도		
		glColor3ub(255, 255, 255);
		glRotatef (90.0, 1.0, 0.0, 0.0);
		gluDisk(obj, 3, 0, 100, 1);
	glPopMatrix();

	glPushName(105);
	glPushMatrix();//화성		
		glColor3f (1.0, 1.0, 1.0);
		glRotatef ((GLfloat) gong_mars, 0.0, 1.0, 0.0);
		glTranslatef (4.0, 0.0, 0.0);
		glRotatef((GLfloat) self_mars, 0.0, 1.0, 0.0);
		switch(textureType)
			{
			case TEXTURES:
				glBindTexture(GL_TEXTURE_2D, tex[5]);
				renderSphere(0.0, 0.0, 0.0, 0.16, 30 );		
				break;
			case TEXTURES1:
				glCallList(6);
				gluQuadricTexture(obj, GL_TRUE);
				gluSphere(obj, 0.16f, 100, 100);
				break;
			}
	glPopMatrix();
	glPopName();

	glPushMatrix();	//화성궤도	
		glColor3ub(255, 255, 255);
		glRotatef (90.0, 1.0, 0.0, 0.0);
		gluDisk(obj, 4.0, 0, 100, 1);
	glPopMatrix();

	glPushName(106);
	glPushMatrix();//목성		
		glColor3f (1.0, 1.0, 1.0);
		glRotatef ((GLfloat) gong_jupiter, 0.0, 1.0, 0.0);
		glTranslatef (7, 0.0, 0.0);	
		glRotatef((GLfloat) self_jupiter, 0.0, 1.0, 0.0);
		switch(textureType)
			{
			case TEXTURES:
				glBindTexture(GL_TEXTURE_2D, tex[6]); 
				renderSphere(0.0, 0.0, 0.0, 0.3, 30 );
				break;
			case TEXTURES1:
				glCallList(7);
				gluQuadricTexture(obj, GL_TRUE);
				gluSphere(obj, 0.3f, 100, 100);
				break;
			}		
	glPopMatrix();
	glPopName();

	glPushMatrix();//목성궤도	
		glColor3ub(255, 255, 255);
		glRotatef (90.0, 1.0, 0.0, 0.0);
		gluDisk(obj, 7, 0, 100, 1);	
	glPopMatrix();

	glPushName(107);
	glPushMatrix();	//토성		
		glColor3f (1.0, 1.0, 1.0);
		glRotatef ((GLfloat) gong_saturn, 0.0, 1.0, 0.0);	
		glTranslatef (9, 0.0, 0.0);			
		glRotatef((GLfloat) self_saturn, 0.0, 1.0, 0.0);
		switch(textureType)
			{
			case TEXTURES:
				glBindTexture(GL_TEXTURE_2D, tex[7]); 
				renderSphere(0.0, 0.0, 0.0, 0.25, 30 ); 		
				break;
			case TEXTURES1:
				glCallList(8);
				gluQuadricTexture(obj, GL_TRUE);
				gluSphere(obj, 0.25f, 100, 100);
				break;
			}		
	glPopMatrix();
	glPopName();

	glPushMatrix();//토성궤도
		glColor3ub(255, 255, 255);
		glRotatef (90.0, 1.0, 0.0, 0.0);
		gluDisk(obj, 9, 0, 100, 1);
	glPopMatrix();

	glPushMatrix();	//토성고리		
		glColor3ub(255,255,255);
		glRotatef ((GLfloat) gong_saturn2, 0.0, 1.0, 0.0);
		glTranslatef (9, 0.0, 0.0);
		glRotatef (45.0, 1.0, 0.0, 0.0);
		gluDisk(obj, 0.29, 0.50, 100, 1); 
	glPopMatrix();

	glPushName(108);
	glPushMatrix();//천왕성		
		glColor3f (1.0, 1.0, 1.0);
		glRotatef ((GLfloat) gong_uranus, 0.0, 1.0, 0.0);
		glTranslatef (11, 0.0, 0.0);
		glRotatef((GLfloat) self_uranus, 0.0, 1.0, 0.0);
		switch(textureType)
			{
			case TEXTURES:
				glBindTexture(GL_TEXTURE_2D, tex[8]); 
				renderSphere(0.0, 0.0, 0.0, 0.23, 30 ); 		
				break;
			case TEXTURES1:
				glCallList(9);
				gluQuadricTexture(obj, GL_TRUE);
				gluSphere(obj, 0.23f, 100, 100);
				break;
			}				
	glPopMatrix();
	glPopName();

	glPushMatrix();//천왕성궤도	
		glColor3ub(255, 255, 255);	
		glRotatef (90.0, 1.0, 0.0, 0.0);
		gluDisk(obj, 11, 0, 100, 1);	
	glPopMatrix();

	glPushName(109);
	glPushMatrix();//해왕성		
		glColor3f (1.0, 1.0, 1.0);
		glRotatef ((GLfloat) gong_neptune, 0.0, 1.0, 0.0);
		glTranslatef (14, 0.0, 0.0);
		glRotatef((GLfloat) self_neptune, 0.0, 1.0, 0.0);
		switch(textureType)
			{
			case TEXTURES:
				glBindTexture(GL_TEXTURE_2D, tex[9]); 
				renderSphere(0.0, 0.0, 0.0, 0.21, 30 ); 		
				break;
			case TEXTURES1:
				glCallList(10);
				gluQuadricTexture(obj, GL_TRUE);
				gluSphere(obj, 0.21f, 100, 100);
				break;
			}					
	glPopMatrix();
	glPopName();

	glPushMatrix();//해왕성궤도
		glColor3ub(255, 255, 255);	
		glRotatef (90.0, 1.0, 0.0, 0.0);
		gluDisk(obj, 14, 0, 100, 1);
	glPopMatrix();

	glPushName(110);
	glPushMatrix();//명왕성		
		glColor3f (1.0, 1.0, 1.0);
		glRotatef ((GLfloat) gong_pluto, 15, 1, 0);
		glTranslatef (18, 0.0, 0.0);
		glRotatef((GLfloat) self_pluto, 0.0, 1.0, 0.0);
		switch(textureType)
			{
			case TEXTURES:
				glBindTexture(GL_TEXTURE_2D, tex[10]); 
				renderSphere(0.0, 0.0, 0.0, 0.20, 30 ); 		
				break;
			case TEXTURES1:
				glCallList(11);
				gluQuadricTexture(obj, GL_TRUE);
				gluSphere(obj, 0.20f, 100, 100);
				break;
			}						
	glPopMatrix();
	glPopName();

	glPushMatrix();//명왕성궤도	
		glColor3ub(255, 255, 255);	
		glRotatef (90.0, 1.0, 0.0, 0.0);
		gluDisk(obj, 18, 0, 100, 1);	
	glPopMatrix();
	glPopMatrix();	
    return TRUE;
}

void ProcessSelect(GLuint index[64])  
{
	switch(index[3]) {		
		case 101: MessageBox(hWnd, "반지름(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(hWnd, "반지름(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(hWnd, "반지름(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(hWnd, "반지름(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(hWnd, "반지름(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(hWnd, "반지름(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(hWnd, "반지름(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(hWnd, "반지름(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(hWnd, "반지름(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(hWnd, "반지름(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(hWnd, "What?", "Selection", MB_OK); 
		//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,ratio,0.1f,100.0f);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		DrawGLScene();
		hits = glRenderMode(GL_RENDER);
		if(hits>0) ProcessSelect(selectBuff);
		glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
}


GLvoid KillGLWindow(GLvoid)								
{
	if (fullscreen)										
	{
		ChangeDisplaySettings(NULL,0);					
		ShowCursor(TRUE);								
	}

	if (hRC)											
	{
		if (!wglMakeCurrent(NULL,NULL))					
		{
			MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		}

		if (!wglDeleteContext(hRC))						
		{
			MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		}
		hRC=NULL;										
	}

	if (hDC && !ReleaseDC(hWnd,hDC))					
	{
		MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		hDC=NULL;										
	}

	if (hWnd && !DestroyWindow(hWnd))					
	{
		MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		hWnd=NULL;										
	}

	if (!UnregisterClass("OpenGL",hInstance))			
	{
		MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		hInstance=NULL;									
	}


	gluDeleteQuadric(obj);      
}

 
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
	windowWidth=width;
	GLuint		PixelFormat;			
	WNDCLASS	wc;						
	DWORD		dwExStyle;				
	DWORD		dwStyle;				
	RECT		WindowRect;				
	WindowRect.left=(long)0;			
	WindowRect.right=(long)width;		
	WindowRect.top=(long)0;				
	WindowRect.bottom=(long)height;		

	fullscreen=fullscreenflag;			

	hInstance			= GetModuleHandle(NULL);				
	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	
	wc.lpfnWndProc		= (WNDPROC) WndProc;					
	wc.cbClsExtra		= 0;									
	wc.cbWndExtra		= 0;									
	wc.hInstance		= hInstance;							
	wc.hIcon			= LoadIcon(NULL, IDI_WINLOGO);			
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			
	wc.hbrBackground	= NULL;									
	wc.lpszMenuName		= NULL;									
	wc.lpszClassName	= "OpenGL";								

	if (!RegisterClass(&wc))									
	{
		MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;											
	}
	
	if (fullscreen)												
	{
		DEVMODE dmScreenSettings;								
		memset(&dmScreenSettings,0,sizeof(dmScreenSettings));	
		dmScreenSettings.dmSize=sizeof(dmScreenSettings);		
		dmScreenSettings.dmPelsWidth	= width;				
		dmScreenSettings.dmPelsHeight	= height;				
		dmScreenSettings.dmBitsPerPel	= bits;					
		dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

		
		if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
		{
			
			if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","2nd Term OpenGL Project",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
			{
				fullscreen=FALSE;		
			}
			else
			{
				
				MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
				return FALSE;									
			}
		}
	}

	if (fullscreen)												
	{
		dwExStyle=WS_EX_APPWINDOW;								
		dwStyle=WS_POPUP;										
		ShowCursor(FALSE);										
	}
	else
	{
		dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			
		dwStyle=WS_OVERLAPPEDWINDOW;							
	}

	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);		

	
	if (!(hWnd=CreateWindowEx(	dwExStyle,							
								"OpenGL",							
								title,							
								dwStyle |							
								WS_CLIPSIBLINGS |					
								WS_CLIPCHILDREN,					
								0, 0,								
								WindowRect.right-WindowRect.left,	
								WindowRect.bottom-WindowRect.top,	
								NULL,								
								NULL,								
								hInstance,							
								NULL)))								
	{
		KillGLWindow();								
		MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	static	PIXELFORMATDESCRIPTOR pfd=				
	{
		sizeof(PIXELFORMATDESCRIPTOR),				
		1,											
		PFD_DRAW_TO_WINDOW |						
		PFD_SUPPORT_OPENGL |						
		PFD_DOUBLEBUFFER,							
		PFD_TYPE_RGBA,								
		bits,										
		0, 0, 0, 0, 0, 0,							
		0,											
		0,											
		0,											
		0, 0, 0, 0,									
		16,											  
		0,											
		0,											
		PFD_MAIN_PLANE,								
		0,											
		0, 0, 0										
	};
	
	if (!(hDC=GetDC(hWnd)))							
	{
		KillGLWindow();								
		MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))	
	{
		KillGLWindow();								
		MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	if(!SetPixelFormat(hDC,PixelFormat,&pfd))		
	{
		KillGLWindow();								
		MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	if (!(hRC=wglCreateContext(hDC)))				
	{
		KillGLWindow();								
		MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	if(!wglMakeCurrent(hDC,hRC))					
	{
		KillGLWindow();								
		MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	ShowWindow(hWnd,SW_SHOW);						
	SetForegroundWindow(hWnd);						
	SetFocus(hWnd);									
	ReSizeGLScene(width, height);					

	if (!InitGL())									
	{
		KillGLWindow();								
		MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							
	}

	return TRUE;								
}




LRESULT CALLBACK WndProc(	HWND	hWnd, UINT	uMsg,	WPARAM	wParam,	LPARAM	lParam)			
{
	switch (uMsg)									
	{
		case WM_SYSCOMMAND:							
		{
			switch (wParam)							
			{
				case SC_SCREENSAVE:					
				case SC_MONITORPOWER:				
				return 0;							
			}
			break;									
		}

		case WM_CLOSE:								 
		{
			PostQuitMessage(0);						
			return 0;								
		}

		case WM_KEYDOWN:							
		{
			switch(wParam)
			{
			case VK_SPACE:
				active=!active;
				break;
			case VK_ADD:
				scale+=0.3;
				break;
			case VK_SUBTRACT:
				scale-=0.3;
				break;
			default :
				keys[wParam] = TRUE;					
				break;
			}
			return 0;
		}

		case WM_KEYUP:								
		{
			keys[wParam] = FALSE;					
			return 0;								
		}

		case WM_LBUTTONDOWN: 
		{
			SelectObjects(LOWORD(lParam), HIWORD(lParam));
			return 0;
		}

		case WM_RBUTTONDOWN: 
		{
			click = true;			
			return 0;
		}

		case WM_MOUSEMOVE:
		{
			
			x=LOWORD(lParam);
			y=HIWORD(lParam);
			if (click)
			{
				yTheta -= (mouseX - x)/1.;
				xTheta -= (mouseY - y)/1.;
			}
			mouseX=x;
			mouseY=y;
			return 0;
		}

		case WM_RBUTTONUP:
		{
			click = false;
			return 0;
		}

		case WM_SIZE:								
		{
			ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  
			return 0;								
		}
	}

	
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}


int main(	HINSTANCE	hInstance,	HINSTANCE	hPrevInstance,		
					LPSTR		lpCmdLine,	int			nCmdShow)			
{
	MSG		msg;									
	BOOL	done=FALSE;								
	fullscreen=FALSE;							


	
	if (!CreateGLWindow("OpenGL Team Project",800,600,16,fullscreen))
	{
		return 0;									
	}

	while(!done)									
	{
		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	
		{
			if (msg.message==WM_QUIT)				
			{
				done=TRUE;							
			}
			else									
			{
				TranslateMessage(&msg);				
				DispatchMessage(&msg);				
			}
		}
		else										
		{
			
			if ((active && !DrawGLScene()) || keys[VK_ESCAPE])	
			{
				done=TRUE;							
			}
			else									
			{
				SwapBuffers(hDC);					
			}

			if (keys[VK_F1])						
			{
				keys[VK_F1]=FALSE;					
				KillGLWindow();						
				fullscreen=!fullscreen;				
				
				if (!CreateGLWindow("OpenGL Team Project",800,600,16,fullscreen))
				{
					return 0;						
				}
				
			}
			
			if (keys[VK_F2])						
			{
				keys[VK_F2]=FALSE;
				light=!light;				
				
			}
			if (keys[VK_F3])	
			{
				keys[VK_F3]=FALSE;
				textures=!textures;
				
				
			}
			if (keys[VK_F4])
			{
				keys[VK_F4]=FALSE;
				wire1=!wire1;	
				
			}
			if (keys[VK_F5])
			{
				keys[VK_F5]=FALSE;
				if (textureType == TEXTURES)
				{
					textureType = TEXTURES1;
				}
				else if(textureType == TEXTURES1)
				{
					textureType = TEXTURES;
				}				
			}			
		}
	}

	KillGLWindow();								
	return (msg.wParam);							
}
