// sample1.cpp
// Glenn G. Chappell
// 30 Aug 2012
//
// For CS 381 Fall 2012
// Sample 2-D OpenGL/GLUT program

// OpenGL/GLUT includes - DO THESE FIRST
#include <cstdlib>       // Do this before GL/GLUT includes
using std::exit;
#ifndef __APPLE__
# include <GL/glut.h>    // GLUT stuff, includes OpenGL headers as well
#else
# include <GLUT/glut.h>  // Apple puts glut.h in a different place
#endif

// Other includes
#include <iostream>
using std::cout;
using std::cerr;
using std::endl;


// Global variables
// Window/viewport
const int startwinsize = 600;  // Start window width & height (pixels)


// myDisplay
// The GLUT display function
void myDisplay()
{
    // Clear the viewport
    glClearColor(0.5f, 0.9f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // Draw a few primitives
    glColor3d(0.1, 0.1, 0.8);
    glBegin(GL_LINE_LOOP);
        glVertex2d(0.05, 0.05);
        glVertex2d(0.95, 0.05);
        glVertex2d(0.95, 0.95);
        glVertex2d(0.05, 0.95);
    glEnd();

    glColor3d(0.9, 0.1, 0.1);
    glBegin(GL_LINES);
        glVertex2d(0.85, 0.4);
        glVertex2d(0.85, 0.6);
        glVertex2d(0.65, 0.6);
        glVertex2d(0.65, 0.4);
    glEnd();

    glColor3d(0.7, 0.1, 0.9);
    glBegin(GL_QUADS);
        glVertex2d(0.15, 0.4);
        glVertex2d(0.15, 0.6);
        glVertex2d(0.35, 0.6);
        glVertex2d(0.35, 0.4);
    glEnd();

    glColor3d(0.9, 0.9, 0.1);
    glBegin(GL_POLYGON);
        glVertex2d(0.5, 0.65);
        glVertex2d(0.4, 0.85);
        glVertex2d(0.6, 0.85);
    glEnd();

    glColor3d(0.0, 0.0, 0.0);
    glBegin(GL_LINE_STRIP);
        glVertex2d(0.5, 0.35);
        glVertex2d(0.4, 0.15);
        glVertex2d(0.6, 0.15);
    glEnd();

    // Send it all down the pipeline
    glFlush();
}


// myIdle
// The GLUT idle function
void myIdle()
{
    // Print OpenGL errors, if there are any (for debugging)
    static int error_count = 0;
    if (GLenum err = glGetError())
    {
        ++error_count;
        cerr << "OpenGL ERROR " << error_count << ": "
             << gluErrorString(err) << endl;
    }
}


// init
// Initialize GL states & global data
// Called by main after window creation
void init()
{
    // OpenGL Stuff
    glLineWidth(5.0);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, 1.0, 0.0, 1.0);

    glMatrixMode(GL_MODELVIEW);  // Always go back to model/view mode

    // Documentation in text window
    cout << "Sample 2-D OpenGL/GLUT Program" << endl;
    cout << "by Glenn G. Chappell" << endl;
    cout << "for CS 381 Fall 2012" << endl;
    cout << endl;
    cout << "Kill window to quit." << endl;
}


int main(int argc, char ** argv)
{
    // Initialize OpenGL/GLUT
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

    // Make a window
    glutInitWindowSize(startwinsize, startwinsize);
    glutInitWindowPosition(50, 50);
    glutCreateWindow("CS 381 - Sample 2-D Program");

    // Initialize GL states & register GLUT callbacks
    init();
    glutDisplayFunc(myDisplay);
    glutIdleFunc(myIdle);

    // Do something
    glutMainLoop();

    return 0;
}

