/*
 * Modified version of the NeHe tutorial 5.
 * The original code was created by Jeff Molofee 2000
 * nehe.gamedev.net
 *
 * Change set 1:
 * Changed entry point from WinMain to WinMainCRTStartup
 * Removed call to memset()
 *
 * Change set 2:
 * Eliminated windowed mode
 * Locked the window size
 * Merged InitGL and ReSizeGLScene functions into CreateGLWindow
 * Simplified keyboard processing with GetAsyncKeyState
 * Removed code to handle screensaver and monitor-power events
 * Removed render-when-active switch
 * Simplified OpenGL state setup
 * 
 * Change set 3:
 * Eliminated all error-checking
 * Eliminated all cleanup code
 * Moved CreateGLWindow into main
 *
 * Change set 4:
 * Switched to "static" window class
 * Used WM_VISIBLE flag
 * Used 0 for module handle
 * Switched to static structures
 * Filled structures with 0 wherever possible
 */

#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>

/*
 * Constants:
 */
#define MAIN_X (800)
#define MAIN_Y (600)

/*
 * Data structures:
 */
DEVMODE s_main_mode = {
  "",                             /* dmDeviceName[CCHDEVICENAME] */
  0,                              /* dmSpecVersion */
  0,                              /* dmDriverVersion */
  sizeof(DEVMODE),                /* dmSize */
  0,                              /* dmDriverExtra */
  DM_PELSWIDTH | DM_PELSHEIGHT,   /* dmFields */
  0, 0, 0, 0, 0, 0, 0, 0,         /* Paper stuff */
  0,                              /* dmColor */
  0,                              /* dmDuplex */
  0,                              /* dmYResolution */
  0,                              /* dmTTOption */
  0,                              /* dmCollate */
  "",                             /* dmFormName[CCHFORMNAME] */
  0,                              /* dmLogPixels */
  0,                              /* dmBitsPerPel */
  MAIN_X,                         /* dmPelsWidth */
  MAIN_Y,                         /* dmPelsHeight */
  0,                              /* dmDisplayFlags */
  0                               /* dmDisplayFrequency */
};

PIXELFORMATDESCRIPTOR s_main_pfd = {
  0,                              /* nSize */
  0,                              /* nVersion */
  PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL, /* dwFlags */
  PFD_TYPE_RGBA,                  /* iPixelType */
  0,                              /* cColorBits */
  0, 0,                           /* cRedBits,   cRedShift */
  0, 0,                           /* cGreenBits, cGreenShift */
  0, 0,                           /* cBlueBits,  cBlueShift */
  0, 0,                           /* cAlphaBits, cAlphaShift */
  0,                              /* cAccumBits */
  0,                              /* cAccumRedBits */
  0,                              /* cAccumGreenBits */
  0,                              /* cAccumBlueBits */
  0,                              /* cAccumAlphaBits */
  16,                             /* cDepthBits */
  0,                              /* cStencilBits */
  0,                              /* cAuxBuffers */
  PFD_MAIN_PLANE,                 /* iLayerType */
  0,                              /* bReserved */
  0,                              /* dwLayerMask */
  0,                              /* dwVisibleMask */
  0                               /* dwDamageMask */
};

int render()
{
  static float rtri = 0;
  static float rquad = 0;

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  /* Draw pyramid: */
  glLoadIdentity();                  
  glTranslatef(-1.5f,0.0f,-6.0f);    
  glRotatef(rtri,0.0f,1.0f,0.0f);    
  glBegin(GL_TRIANGLES);             
    glColor3f(1.0f,0.0f,0.0f);       
    glVertex3f( 0.0f, 1.0f, 0.0f);   
    glColor3f(0.0f,1.0f,0.0f);       
    glVertex3f(-1.0f,-1.0f, 1.0f);   
    glColor3f(0.0f,0.0f,1.0f);       
    glVertex3f( 1.0f,-1.0f, 1.0f);   
    glColor3f(1.0f,0.0f,0.0f);       
    glVertex3f( 0.0f, 1.0f, 0.0f);   
    glColor3f(0.0f,0.0f,1.0f);       
    glVertex3f( 1.0f,-1.0f, 1.0f);   
    glColor3f(0.0f,1.0f,0.0f);       
    glVertex3f( 1.0f,-1.0f, -1.0f);  
    glColor3f(1.0f,0.0f,0.0f);       
    glVertex3f( 0.0f, 1.0f, 0.0f);   
    glColor3f(0.0f,1.0f,0.0f);       
    glVertex3f( 1.0f,-1.0f, -1.0f);  
    glColor3f(0.0f,0.0f,1.0f);       
    glVertex3f(-1.0f,-1.0f, -1.0f);  
    glColor3f(1.0f,0.0f,0.0f);       
    glVertex3f( 0.0f, 1.0f, 0.0f);   
    glColor3f(0.0f,0.0f,1.0f);       
    glVertex3f(-1.0f,-1.0f,-1.0f);   
    glColor3f(0.0f,1.0f,0.0f);       
    glVertex3f(-1.0f,-1.0f, 1.0f);   
  glEnd();

  /* Draw cube: */
  glLoadIdentity();                  
  glTranslatef(1.5f,0.0f,-7.0f);     
  glRotatef(rquad,1.0f,1.0f,1.0f);   
  glBegin(GL_QUADS);                 
    glColor3f(0.0f,1.0f,0.0f);       
    glVertex3f( 1.0f, 1.0f,-1.0f);   
    glVertex3f(-1.0f, 1.0f,-1.0f);   
    glVertex3f(-1.0f, 1.0f, 1.0f);   
    glVertex3f( 1.0f, 1.0f, 1.0f);   
    glColor3f(1.0f,0.5f,0.0f);       
    glVertex3f( 1.0f,-1.0f, 1.0f);   
    glVertex3f(-1.0f,-1.0f, 1.0f);   
    glVertex3f(-1.0f,-1.0f,-1.0f);   
    glVertex3f( 1.0f,-1.0f,-1.0f);   
    glColor3f(1.0f,0.0f,0.0f);       
    glVertex3f( 1.0f, 1.0f, 1.0f);   
    glVertex3f(-1.0f, 1.0f, 1.0f);   
    glVertex3f(-1.0f,-1.0f, 1.0f);   
    glVertex3f( 1.0f,-1.0f, 1.0f);   
    glColor3f(1.0f,1.0f,0.0f);       
    glVertex3f( 1.0f,-1.0f,-1.0f);   
    glVertex3f(-1.0f,-1.0f,-1.0f);   
    glVertex3f(-1.0f, 1.0f,-1.0f);   
    glVertex3f( 1.0f, 1.0f,-1.0f);   
    glColor3f(0.0f,0.0f,1.0f);       
    glVertex3f(-1.0f, 1.0f, 1.0f);   
    glVertex3f(-1.0f, 1.0f,-1.0f);   
    glVertex3f(-1.0f,-1.0f,-1.0f);   
    glVertex3f(-1.0f,-1.0f, 1.0f);   
    glColor3f(1.0f,0.0f,1.0f);       
    glVertex3f( 1.0f, 1.0f,-1.0f);   
    glVertex3f( 1.0f, 1.0f, 1.0f);   
    glVertex3f( 1.0f,-1.0f, 1.0f);   
    glVertex3f( 1.0f,-1.0f,-1.0f);   
  glEnd();

  rtri += 0.2f;
  rquad -= 0.15f;
  return TRUE;
}

/**
 * Native program entry point
 */
void WINAPI WinMainCRTStartup()
{
  HDC dc;

  /* Change the display settings: */
  ChangeDisplaySettings(&s_main_mode, CDS_FULLSCREEN);

  /* Create the window: */
  dc = GetDC(CreateWindowExA(
    0, "edit", 0,
    WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS|WS_MAXIMIZE,
    0, 0, 0, 0, 0, 0, 0, 0));

  /* Set up OpenGL: */
  SetPixelFormat(dc, ChoosePixelFormat(dc, &s_main_pfd), &s_main_pfd);
  wglMakeCurrent(dc, wglCreateContext(dc));
  ShowCursor(FALSE);

  /* Set up the OpenGL options: */
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0f, (float)MAIN_X/MAIN_Y, 0.1f, 100.0f);
  glMatrixMode(GL_MODELVIEW);

  glClearDepth(1.0f);
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);

  /* Render loop: */
  do {
    if (!render())
      break;
    SwapBuffers(dc);
  } while (!GetAsyncKeyState(VK_ESCAPE));

  /* Clean up and exit: */
  ExitProcess(0);
}
