#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include<fstream.h>   
#include <windows.h>   
#include <gl/Gl.h>
#include <GL/glut.h>

struct Planet {
	char* name;
	char* orbits;
	float distance;
	float o_period;
	float inclination;
	float radius;
	float rotate;
	float tilt;
	GLubyte *texture;
};

void changeSize(int w, int h) {
if(h == 0)
h = 1;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45,(GLfloat)w/(GLfloat)h,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

float angle = 0.0;

GLUquadricObj*  sph;

int LE=-40,RE=40,BE=-20,TE=20,DB=-200,DF=200;

Planet SSystem[10000];

int pcount = 0;
int majorcount = 0;

float translatex = 0;
float translatey = 0;
float currentscalexy = 1;
float currentscalez = 1;

float posx = 0;
float posy = 0;
float posz = 40;

float px=0,py=0,pz=0;

int W=600,H=300;

void drawPlanet(GLubyte * tex, int components, float radius) 
{
  glPushMatrix();
	    glRotatef(90.0, 1.0, 0.0, 0.0);

	    glColor4f (1.0, 1.0, 1.0, 1.0);

	    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 256, 0,
		 GL_RGB, GL_UNSIGNED_BYTE, tex);

	    gluSphere(sph, radius, components, components);
  glPopMatrix();
}
void parseMajor()
{
	for(int v=0;v<pcount;v++)
	{
		if(!strncmp(SSystem[v].orbits,"Sun",3))
		{
			majorcount++;
		}
	}
}

void adjustRadius()
{
	for(int c=1;c<pcount;c++)
	{
		if(SSystem[c].radius<10000)
			SSystem[c].radius+=15000;
	}
}
void adjustDistance()
{
	SSystem[1].distance=67910;
	SSystem[2].distance=108200;
	SSystem[3].distance=149600;
	SSystem[4].distance=227940;
	SSystem[5].distance=308330;
	SSystem[6].distance=388330;
	SSystem[7].distance=468330;
	SSystem[8].distance=558330;
	SSystem[9].distance=658330;
}
void adjustPeriod()
{
	SSystem[1].o_period=87.97*2;
	SSystem[2].o_period=224.70*2;
	SSystem[3].o_period=365.26*2;
	SSystem[4].o_period=686.98*2;
	SSystem[5].o_period=4332.71;
	SSystem[6].o_period=10759.50/2;
	SSystem[7].o_period=30685.00/2;
	SSystem[8].o_period=60190.00/2;
	SSystem[9].o_period=90800/2;
}
void display(void)
{
    /* clear the screen to the clear colour */

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity ();
	glOrtho(LE,RE,BE,TE,DB,DF);
	gluPerspective(0, 0, 0, 0); 
	gluLookAt(posx, posy, posz, 0, 0, 0, 0, 1, 0);
	glMatrixMode(GL_MODELVIEW);
	glClearColor(0,0,0,1);
	glPushMatrix();
	glScalef(currentscalexy, currentscalexy, currentscalexy);
	glTranslatef(translatex,translatey,0);		
	glPushMatrix();

	float sun_glow[] = {0.7, 0.5, 0, 1};
	glMaterialfv(GL_FRONT, GL_EMISSION, sun_glow);
	glRotatef(SSystem[0].tilt, 0, -1, 0);

	glPushMatrix();
		glRotatef(SSystem[0].rotate,0,1,0);
		drawPlanet(SSystem[0].texture, 20, SSystem[0].radius/159999);
	glPopMatrix();	
	glPopMatrix();
	glPopMatrix();
	/* swap buffers */  
	glFlush();
	glutSwapBuffers();
	glutPostRedisplay();
} 
void dealWithParameters(int argc, char **argv)
{
	FILE *solarsystem;
	char *name;
	char *read;
	char *line;
	float radius=0;
	name=(char*)malloc(sizeof(char)*300);
	read=(char*)malloc(sizeof(char)*300);
	line=(char*)malloc(sizeof(char)*300);
	solarsystem=fopen("solar.txt","r");
	if(solarsystem==NULL) {
		printf("Can not read file.\n");
		exit(1);
	}
	fgets(read,300,solarsystem);
	fgets(read,300,solarsystem);
	fgets(read,300,solarsystem);
	while(fgets(read,300,solarsystem)!=NULL)
	{
		/* Name */
		line=strtok(read," ");
		
		if(!strncmp(line, "Key:",4))
		{
			printf("end of data reached...\n");
			break;
		}		
		if(strlen(read)==1)
		{
			continue;
		}
		SSystem[pcount].name=(char*)malloc(sizeof(char)*300);
		strcpy(SSystem[pcount].name,line);
		/* # */
		line=strtok(NULL," ");
		/* Orbits */
		line=strtok(NULL," ");
		SSystem[pcount].orbits=(char*)malloc(sizeof(char)*300);
		strcpy(SSystem[pcount].orbits,line);
		/* Distance */
		line=strtok(NULL," ");
		SSystem[pcount].distance = atof(line);
		/* O_Period */
		line=strtok(NULL," ");
		SSystem[pcount].o_period = atof(line);
		/* Incl */
		line=strtok(NULL," ");
		SSystem[pcount].inclination = atof(line);
		/* Eccen */
		line=strtok(NULL," ");
		/* Discover */
		line=strtok(NULL," ");
		/* Date */
		line=strtok(NULL," ");
		/* Radius */
		line=strtok(NULL," ");
		SSystem[pcount].radius = atof(line);
		radius=atof(line);
		/* Mass */
		line=strtok(NULL," ");
		/* Dens */
		line=strtok(NULL," ");		
		/* Abo */
		line=strtok(NULL," ");
		/* Vo */
		line=strtok(NULL," ");
		/* Rotate */
		line=strtok(NULL," ");
		SSystem[pcount].rotate = atof(line);
		/* Tilt */
		line=strtok(NULL," ");
		SSystem[pcount].tilt = atof(line);
		/* increment planet struct */
		if(radius>=500)
			pcount++;
	}
	parseMajor();	
	adjustRadius();
	adjustDistance();
	adjustPeriod();
	fclose(solarsystem);
}
int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    dealWithParameters(argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(W,H);
	glutInitWindowPosition(100,100);
	glutCreateWindow("النظام الشمسي");
	glutDisplayFunc(display);
    sph = gluNewQuadric();
	glutReshapeFunc(changeSize);
    glutMainLoop();
    gluDeleteQuadric(sph);
	return 0;  
}
