/*
 *  opengl driver code for glaux under windows,
 *  originally from an opengl sample
 */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>

#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>

#define PI ((float)3.14159265358979323846)

#define WIDTH 512
#define HEIGHT 512

BOOL fSingle = FALSE;

void *Malloc(size_t cb)
{
    void *pv;

    pv = malloc(cb);
    if (pv == NULL)
    {
        printf("Unable to alloc %d bytes\n", cb);
        exit(1);
    }
    return pv;
}


void Init(void)
{
    float fv4[4];
    int iv1[1];
    int i;
    GLint dlBase;

    extern void horn_initgl();

    horn_initgl();

#if 0
    fv4[0] = 0.05f;
    fv4[1] = 0.05f;
    fv4[2] = 0.05f;
    fv4[3] = 1.0f;
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fv4);
    
    fv4[0] = 0.0f;
    fv4[1] = 1.0f;
    fv4[2] = 1.0f;
    fv4[3] = 0.0f;
    glLightfv(GL_LIGHT0, GL_POSITION, fv4);
    fv4[0] = 0.9f;
    fv4[1] = 0.9f;
    fv4[2] = 0.9f;
    fv4[3] = 1.0f;
    glLightfv(GL_LIGHT0, GL_DIFFUSE, fv4);
    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHTING);
    
    fv4[0] = 0.6f;
    fv4[1] = 0.6f;
    fv4[2] = 0.6f;
    fv4[3] = 1.0f;
    glMaterialfv(GL_FRONT, GL_SPECULAR, fv4);
    iv1[0] = 40;
    glMaterialiv(GL_FRONT, GL_SHININESS, iv1);
    
    glEnable(GL_CULL_FACE);
    
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
    glEnable(GL_COLOR_MATERIAL);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, 1, .01, 15);
    gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
    glMatrixMode(GL_MODELVIEW);

#endif
}

DWORD dwTotalMillis = 0;

void ResetTotals(void)
{
    dwTotalMillis = 0;
}

void CALLBACK Redraw(void)
{
    DWORD dwMillis;
    char szMsg[80];
    extern void horn_paintgl();

    dwMillis = GetTickCount();

    horn_paintgl();

    if (fSingle) {
        glFlush();
    } else {
        auxSwapBuffers();
    }

    dwMillis = GetTickCount()-dwMillis;

    dwTotalMillis += dwMillis;

#if 0
    if (dwTotalMillis > 1000) {
        sprintf(szMsg, "%s%s: %.3lf tri/sec",
                fDisplayList ? "Display List " : "",
                pszListType[iCurrentType],
                (double)iTotalTriangles*1000.0/dwTotalMillis);
        SetWindowText(auxGetHWND(), szMsg);

        ResetTotals();
    }
#endif
}

void CALLBACK Reshape(GLsizei w, GLsizei h)
{
    {
        extern int screenwidth;
        extern int screenheight;
        screenwidth = w;
        screenheight = h;
    }

    glViewport(0, 0, w, h);
}

void CALLBACK KeySPACE(void)
{
    ResetTotals();
}
    
void __cdecl main(int argc, char **argv)
{
    GLenum eMode;
    
    while (--argc > 0)
    {
        argv++;

        if (!strcmp(*argv, "-sb"))
        {
            fSingle = TRUE;
        }
    }
    
    auxInitPosition(10, 10, WIDTH, HEIGHT);
    eMode = AUX_RGB;
    if (!fSingle)
    {
        eMode |= AUX_DOUBLE;
    }
    auxInitDisplayMode(eMode);
    auxInitWindow("Vertex Array/Direct Comparison");

    auxReshapeFunc(Reshape);
    auxIdleFunc(Redraw);

    auxKeyFunc(AUX_SPACE, KeySPACE);

    Init();
    auxMainLoop(Redraw);
}
