/*  The Blue Mango Quest
 *  Copyright (c) Clément 'phneutre' Bourdarias (code)
 *                   email: phneutre@users.sourceforge.net
 *                Guillaume 'GuBuG' Burlet (graphics)
 *                   email: gubug@users.sourceforge.net
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifdef WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>

#include <stdlib.h>
#include <stdio.h>
//#include <math.h>

// #include "world_building.h"
// #include "map.h"
// #include "timers.h"
// #include "mango.h"
// #include "game_loop.h"
#include "system_gl.h"

void init_GL()
{
  printf("OpenGL initialization...");
  printf(" OpenGL version: %s\n", glGetString (GL_VERSION));
  printf(" GL driver: %s (%s)\n", glGetString (GL_VENDOR), glGetString (GL_RENDERER));

  /* float col[] = { .95, .95, .95, 1.0 }; 
     float dif[] = { 0.4, 0.4, 0.4, 1
     }; float amb[] = { 0.05, 0.05, 0.05, 1 }; */

  GLfloat col[] = { .95, .95, .95, 1.0 };
  GLfloat dif[] ={ 1.0f, 1.0f, 1.0f, 1.0f };

  //GLfloat amb2[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  GLfloat amb[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  GLfloat pos[] = { 0.0, 0.0, 1.0, 1.0 };

  // float spec[]={0.9, 0.9, 0.9, 1 };

//  float dif2[] ={ 0.0f, 1.0f, 1.0f, 1.0f };
//  float amb2[] = { 0.5f, 0.5f, 0.5f, 1.0f };
//  float pos2[] = { 0.0, 0.0, 1.0, 1.0 };
  GLfloat spec2[]={0.9, 0.9, 0.9, 1 };

//  GLfloat black[] = { 0., 0., 0., 1. };

  glViewport(0, 0, 800, 600);
  glClearDepth(1.0);

  glEnable(GL_DEPTH_TEST);

  glDepthFunc(GL_LEQUAL);

  // glBlendFunc(GL_SRC_ALPHA,GL_ONE);

  //glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);

  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  glShadeModel(GL_SMOOTH);
  glEnable(GL_POINT_SMOOTH);
  glEnable(GL_LINE_SMOOTH);
  glClear(GL_COLOR_BUFFER_BIT);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  gluPerspective(45.0f, 1.33333f, 0.01f, 100.0f);
  glMatrixMode(GL_MODELVIEW);

  glFrontFace(GL_CCW);
  glCullFace(GL_BACK);
  glEnable(GL_CULL_FACE);

  glHint(GL_FOG_HINT, GL_DONT_CARE);
  glFogf(GL_FOG_START, 15.0);
  glFogf(GL_FOG_END, 40.0);
  glFogf(GL_FOG_MODE, GL_LINEAR);
  glFogf(GL_FOG_DENSITY, 0.1);
  glEnable(GL_FOG);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  
  SDL_GL_SwapBuffers();

  //glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black);

  glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
  glLightfv(GL_LIGHT0, GL_SPECULAR, col);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
  glLightfv(GL_LIGHT0, GL_POSITION, pos);
  glEnable(GL_LIGHT0);

  //glLightfv(GL_LIGHT3, GL_AMBIENT, amb2);
  //glLightfv(GL_LIGHT3, GL_POSITION, pos);

  GLfloat spot_dir[4]= {0.0, 0.0, -1.0};

  glLightfv(GL_LIGHT1, GL_AMBIENT, amb);
  glLightfv(GL_LIGHT1, GL_SPECULAR, col);
  glLightfv(GL_LIGHT2, GL_DIFFUSE, dif);
  glLightfv(GL_LIGHT2, GL_POSITION, pos);
  glLightfv(GL_LIGHT2, GL_SPECULAR,spec2 );
  glLightf(GL_LIGHT2, GL_LINEAR_ATTENUATION, 0.1);
  glLightfv(GL_LIGHT2, GL_SPOT_DIRECTION, spot_dir);
  glLightf(GL_LIGHT2,GL_SPOT_CUTOFF, 10);
  glLightf(GL_LIGHT2,GL_SPOT_EXPONENT, 3.0);
  //glEnable(GL_LIGHT2);

  //glDisable(GL_LIGHT0);  
 
  glEnable (GL_LIGHTING);
}

void set_GL_projection (char proj_mode)
{
  switch (proj_mode)
    {
    case MANGO_2D:
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(0, 800, 0, 600, -1.0, 1.0);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      glColor4f(1.0, 1.0, 1.0, 1.0);
      break;

    case MANGO_3D:
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();

      gluPerspective(45.0f, 1.33333f, 0.01f, 100.0f);
      glMatrixMode(GL_MODELVIEW);
      break;

    default:
      break;
    }
}

void set_GL_options(char mode)
{
  switch (mode)
    {
    case MANGO_2D:
      glEnable( GL_TEXTURE_2D );
      glDisable( GL_DEPTH_TEST );
      glDisable( GL_CULL_FACE );
      glDisable( GL_LIGHTING );
      glDisable( GL_NORMALIZE );
      glDisable( GL_ALPHA_TEST );
      glEnable( GL_BLEND );

      glDisable( GL_STENCIL_TEST );
      glDisable( GL_TEXTURE_GEN_S );
      glDisable( GL_TEXTURE_GEN_T );
      glDisable( GL_COLOR_MATERIAL );
      glDepthMask( GL_TRUE );
      glShadeModel( GL_SMOOTH );
      //glDepthFunc( GL_LESS );

      glDisable( GL_FOG );
      break;

    case MANGO_3D:
      glFrontFace(GL_CCW);
      glCullFace(GL_BACK);
      glEnable(GL_CULL_FACE);
      glEnable( GL_DEPTH_TEST );
      glEnable( GL_LIGHTING );
      glEnable( GL_NORMALIZE );
      glDisable( GL_BLEND );
      glEnable(GL_FOG);
      break;
    }
}
