/*
*     ___                       ____ ___
*    / _ \___ _    _____ ____  |_  // _ \
*   / ___/ _ \ |/|/ / -_) __/ _/_ </ // /
*  /_/   \___/__,__/\__/_/   /____/____/
*
*
*   Original Code by John Garrison
*   Written August 29, 1999
*   To be released under the LGPL
*
*   Setting of OpenGL graphics modes and buffers.
*
*   See LICENSE.TXT for more LGPL info
*/

#ifdef USE_P3D

#include <string.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include "power3d.h"
#include "gfx3d.h"


/////////////////////////////////////////////////
//          DISPLAY CREATION ROUTINES          //
/////////////////////////////////////////////////

int P3D_SetGFXMode (int Width, int Height, char *Title, int Bpp, int StencilFlag)
{
   if (Bpp == 8) {
      if (!StencilFlag)
         glutInitDisplayMode(GLUT_ALPHA|GLUT_DOUBLE|GLUT_INDEX|GLUT_DEPTH);
      else if (StencilFlag)
        glutInitDisplayMode(GLUT_ALPHA|GLUT_DOUBLE|GLUT_INDEX|GLUT_STENCIL|GLUT_DEPTH);
   }
   if (Bpp > 8) {
      if (!StencilFlag)
         glutInitDisplayMode(GLUT_ALPHA|GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
     else if (StencilFlag)
         glutInitDisplayMode(GLUT_ALPHA|GLUT_DOUBLE|GLUT_RGB|GLUT_STENCIL|GLUT_DEPTH);
   }

   glutInitWindowSize(Width, Height);
   glutInitWindowPosition(0, 0);
   glutCreateWindow(Title);

   glEnable(GL_DEPTH_TEST);
   glEnable(GL_NORMALIZE);
   glEnable(GL_DITHER);
   glShadeModel(GL_SMOOTH);
   glEnable(GL_LIGHTING);
   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
   glEnable(GL_LIGHT0);
   glEnable(GL_COLOR_MATERIAL);


   glClearColor(0.0, 0.0, 0.0, 0.0);
   glClearDepth(1.0);

   SCREENWIDTH3D = Width;
   SCREENHEIGHT3D = Height;
   BPP3D = Bpp;

   return 0;
}



int P3D_SetScreen(float W, float H, float MinDepth, float MaxDepth, int Split, int Section)
{
   int x, y;

   if (Split == P3D_NOSPLIT){
      glViewport (0, 0, (GLsizei) W, (GLsizei) H);
      glMatrixMode (GL_PROJECTION);
      glLoadIdentity ();
      glFrustum (-1.0, 1.0, -1.0, 1.0, MinDepth, MaxDepth);
      glMatrixMode (GL_MODELVIEW);
   }
   if (Split == P3D_HORIZONTAL){
      y = H/2;

      if (Section == 2)
         glViewport(0, 0, W, y);
      if (Section == 1)
         glViewport(0, y, W, H);
      glMatrixMode (GL_PROJECTION);
      glLoadIdentity ();
      glFrustum (-1.0, 1.0, -.50, .50, MinDepth, MaxDepth);
      glMatrixMode (GL_MODELVIEW);
   }
   if (Split == P3D_VERTICAL){
      x = W/2;

      if (Section == 2)
         glViewport(0, 0, x, H);
      if (Section == 1)
         glViewport(x, 0, W, H);
      glMatrixMode (GL_PROJECTION);
      glLoadIdentity ();
      glFrustum (-.50, .50, -1.0, 1.0, MinDepth, MaxDepth);
      glMatrixMode (GL_MODELVIEW);

   }
   if (Split == P3D_FOURWAY){
      x = W/2;
      y = H/2;

      if (Section == 3)
         glViewport(0, 0, x, y);
      if (Section == 4)
         glViewport(x, 0, W, y);
      if (Section == 1)
         glViewport(0, y, x, H);
      if (Section == 2)
         glViewport(x, y, W, H);
      glMatrixMode (GL_PROJECTION);
      glLoadIdentity ();
      glFrustum (-.50, .50, -.50, .50, MinDepth, MaxDepth);
      glMatrixMode (GL_MODELVIEW);
   }

   return 0;
}



//////////////////////////////////////////////
//          DOUBLE BUFFER ROUTINES          //
//////////////////////////////////////////////

/* Blit the DoubleBuffer to the Screen */
int P3D_ShowDoubleBuffer()
{
   glFlush ();
   glutSwapBuffers();

   return 0;
}



////////////////////////////////////////
//          SURFACE ROUTINES          //
////////////////////////////////////////

/* Clears a surface to Color */
int P3D_Clear()
{
   glClear(P3D_COLORBUFFER|P3D_DEPTHBUFFER);

   return 0;
}



////////////////////////////////////////
//          PALETTE ROUTINES          //
////////////////////////////////////////

/* Map RGB values to a color */
P3D_Color P3D_CreateColor (float R, float G, float B, float Alpha)
{
   P3D_Color color;

   color.r = R;
   color.g = G;
   color.b = B;
   color.a = Alpha;

   return (color);
}

#endif