#include <windows.h>
#include <GL/glut.h>
#include <stdio.h>

// Angles here
float angle, angle2;

int moving, startx, starty;

GLfloat  ambient_light[] = {0.3, 0.3, 0.45, 1.0};
GLfloat   source_light[] = {0.9, 0.8, 0.8, 1.0};
GLfloat      light_pos[] = {7.0, 0.0, 0.0, 1.0};


void load_texture ( char *file_name, int width, int height, int depth,
                    GLenum colour_type, GLenum filter_type )
{
   GLubyte *raw_bitmap ;
   FILE *file;

   if ((file = fopen(file_name, "rb"))==NULL )
   {
      printf ( "File Not Found : %s\n", file_name );
      exit   ( 1 );
   }
   raw_bitmap = (GLubyte *) malloc ( width * height * depth * ( sizeof(GLubyte)) );
   if (raw_bitmap == NULL)
   {
      printf ( "Cannot allocate memory for texture\n" );
      fclose ( file);
      exit   ( 1 );
   }

   fread  ( raw_bitmap , width * height * depth, 1 , file );
   fclose ( file);
   //  Set Filtering type
   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_type );
   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_type );
      //  Build Mipmaps
   gluBuild2DMipmaps ( GL_TEXTURE_2D, colour_type, width, height,
                      colour_type, GL_UNSIGNED_BYTE, raw_bitmap );
   //  Free up the array
   free ( raw_bitmap );
}

void init ( void )
{
   // Set up simple lighting model
   glEnable ( GL_LIGHTING );
   glLightModelfv ( GL_LIGHT_MODEL_AMBIENT, ambient_light );
   glLightfv (GL_LIGHT0,GL_DIFFUSE, source_light );
   glLightfv ( GL_LIGHT0,GL_POSITION, light_pos  );
   glEnable  ( GL_LIGHT0 );
   // Enable material properties for lighting
   glEnable ( GL_COLOR_MATERIAL );
   glColorMaterial ( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
   glEnable ( GL_TEXTURE_2D );
    load_texture ( "earth.bmp", 20, 30, 3, GL_RED,  GL_LINEAR );
   //load_texture ( "thanaa.rgb", 60, 30, 3, GL_RED,  GL_LINEAR );
   glEnable ( GL_CULL_FACE );
   glClearColor (1.0, 1.0, 1.0, 0.0);
}

void draw_earth ( void )
{
   glPushMatrix ( );
   glRotatef ( 90.0, 1.0, 0.0, 0.0 );
   glColor4f ( 1.0, 1.0, 1.0, 1.0  );
   GLUquadricObj*  q = gluNewQuadric ( );
   gluQuadricDrawStyle ( q, GLU_FILL );
   gluQuadricNormals ( q, GLU_SMOOTH );
   gluQuadricTexture ( q, GL_TRUE    );
   gluSphere ( q, 1.0, 20, 20 );
   gluDeleteQuadric ( q );
   glPopMatrix ( );
}

void redraw ( void )
{
   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glLightfv ( GL_LIGHT0,GL_POSITION, light_pos );
   glPushMatrix ( );
   glTranslatef ( 0.0, 0.0, -4.0 );
   glRotatef    ( angle2, 1.0, 0.0, 0.0 );
   glRotatef    ( angle, 0.0, 1.0, 0.0  );
   draw_earth   ( );
   glPopMatrix  ( );
   glutSwapBuffers( );
}

void reshape ( int w, int h )
{
   glViewport   ( 0, 0, (GLint) w, (GLint) h );
   glMatrixMode ( GL_PROJECTION);
   glLoadIdentity( );
   if ( h==0 )
      gluPerspective ( 45, (GLdouble)w, 1.0, 2000.0 );
   else
      gluPerspective ( 45, (GLdouble)w / (GLdouble)h,1.0, 2000.0 );

   glMatrixMode ( GL_MODELVIEW );
   glLoadIdentity ( );
}

void mouse ( int button, int state, int x, int y )
{
   if ( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
   {
      moving = 1;
      startx = x;
      starty = y;
   }

   if ( button == GLUT_LEFT_BUTTON && state == GLUT_UP  )
      moving = 0;
}

void motion ( int x, int y )
{
   if ( moving )
   {
      angle = angle +   ( x - startx );
      angle2 = angle2 + ( y - starty );
      startx = x;
      starty = y;
      glutPostRedisplay ( );
   }
}

void idle_func ( void )
{
   angle = angle + 0.1;
   if ( angle == 360 )
      angle = 0;
   glutPostRedisplay ( );
}


//#pragma argsused
void keyboard ( unsigned char key, int x, int y )
{
   switch ( key )
   {
      case 27:  /*  Escape key  */
         exit(0);
         break;
      case 'f':
        glutFullScreen ( );
        break;
      case 'w':
         glutReshapeWindow ( 500,500 );
         break;
      default:
         break;
   }
}

int main ( int argc, char** argv )
{
   glutInit ( &argc, argv );
   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
   glutInitWindowSize ( 450, 450);
   glutCreateWindow("Earth");
    init();
   glutReshapeFunc  ( reshape   );
   glutMouseFunc    ( mouse     );
   glutMotionFunc   ( motion    );
   glutKeyboardFunc ( keyboard  );
   glutDisplayFunc  ( redraw   );
   glutIdleFunc     ( idle_func );
   glutMainLoop ( );
   return 0;
}
