/***********************
 * assignment3.c shell *
 *****************************************************************
 * written 2/10/95                                               *
 * by Andy Johnson                                               *
 *****************************************************************
 * this is the shell for the third EECS 488 Spring 96 assignment *
 * written in Mesa (OpenGL.)                                     *
 *                                                               *
 *****************************************************************/
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "aux.h"


/****************************************************************/

#define WIDTH  300 /* width of the window */
#define HEIGHT 300 /* height of the window  */


/****************************************************************/

static void initializeGraphics(char *);
static void drawScene(void);
static void key_esc(void);
static void reshape(int width, int height);
static void display(void);

/****************************************************************
 * Global Variables
 * 
 * YES,  THESE ARE BAD, SHOULDN'T USE THEM, BAD FOR ALL KINDS OF
 * REASONS,  BUT THIS PROGRAM IS NASTY ENOUGH WITHOUT PASSING
 * ARRAYS AROUND,  AND HEY I HAVE A PHD SO I'M ALLOWED TO USE THEM.
 * 
 * YOU WILL PROBABLY WANT TO DECLARE SOME MATRICIES HERE
 ****************************************************************/

#define MAXPOLYGONS 500
#define MAXVERTICES 10


/* you will probably want to place several matrix manipulation
 * functions here
 * 
 */
 
/****************************************************************
 * INITIALIZEGRAPHICS
 * 
 * function to initialize the graphics
 * 
 * input: windowName - name of window to be opened
 * no outputs
 ****************************************************************/

static void initializeGraphics(char * windowName)
    {
    /* create a single-buffered RGBA window of size WIDTH by HEIGHT
     * located at 0, 0. If this window can not be created then exit
     * the program
     */

    auxInitDisplayMode(AUX_SINGLE | AUX_RGBA);
    auxInitPosition( 0,0, WIDTH, HEIGHT);
    if (auxInitWindow(windowName) == GL_FALSE)
	{
	fprintf(stderr, "could not open a window\n");
	auxQuit();
	}


    /* clear the background of the window to black and set up
     * the window for orthographic viewing. This is the only time
     * in the program that the glMatrixMode command
     * will occur. You are responsible for doing all of the
     * perspective transformations yourself so that they can be
     * drawn in the orthographic window. 
     * 
     */

    glClearColor( 0.0, 0.0, 0.0, 0.0);
    glClear( GL_COLOR_BUFFER_BIT );

    glViewport(0,0,WIDTH,HEIGHT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho( 0, WIDTH, 0, HEIGHT, -1.0, 1.0 );


    /* you will want to initialize several variables and vectors here
     * 
     */
   }


/****************************************************************/

static void drawScene(void)
    {

   /* clear the window to black
    * 
    */
     
    glClearColor( 0.0, 0.0, 0.0, 0.0);
    glClear( GL_COLOR_BUFFER_BIT );

    /* here you will want to perform steps 1-3
     * probably using some functions
     */

    /* here you will want to perform steps 4: clipping
     * probably using some functions
     */

    /* and then on to the rest of the steps
     * probably using some functions
     */
     
    /* and finally actually drawing the resulting polygons.
     * you can use glBegin(GL_LINE_STRIP)/glEnd(); here as well as
     * glColor3f() and glVertex2f()
     * 
     */

    /* force all unfinished graphics commands to execute
    * 
    */

    glFlush();
    }
    
/****************************************************************
 * KEY_ESC
 * 
 * whenever the escape key is pressed while focus is on this
 * process' window the program will halt
 * 
 * no inputs
 * no outputs
 ****************************************************************/

static void key_esc()
    {
    auxQuit();
    }

/****************************************************************
 * RESHAPE
 * 
 * whenever the window is shrunk or expanded this function is
 * called to update the contents of the window. In this case this
 * function does something (unlike previous assignments) - it sets
 * the new size of the viewport based on the new size of the window, 
 * so the scene will be stretched to fit into the shape of the new
 * window
 * 
 * inputs: new width and height of the window
 * no outputs
 ****************************************************************/

static void reshape( int width, int height )
    {
    glViewport(0, 0, width, height);
    }
    
/****************************************************************
 * DISPLAY
 * 
 * the function call within is called to update the 
 * contents of the window. In this case it calls the
 * function which draws the scene into the frame buffer
 * 
 * no inputs
 * no outputs
 ****************************************************************/

static void display( void )
    {	
    drawScene();
    }

/****************************************************************
 * MAIN
 * 
 * program to read in a datafile specifying the color and 3D
 * locations of the polygons forming a small town and allow the
 * user to drive through the town viewing using perspective viewing
 * 
 * inputs: command line arguments
 * outputs: 0 if program exited properly
 ****************************************************************/

int main( int argc, char **argv )
    {
    /* initialize the window, and set up the graphics
     * 
     */
    
    initializeGraphics(argv[0]);
 
     /* The code you wrote in assignments 1 and 3 for reading in a single
     * polygon will need to be modified to handle n polygons, that
     * each polygon now has 3 coordinates (X,  Y,  Z),  and the
     * reading in of the colour of each polygon
     */
   

     /* display the window until the user kills it
     * 
     * THIS CODE ALLOWS INTERATION WITH THE WINDOWING SYSTEM
     * DECLARING WHICH FUNCTIONS SHOULD BE CALLED WHEN THE WINDOW
     * MUST BE UPDATED OR THERE IS INPUT FROM THE KEYBOARD OR MOUSE
     * 
     * here you can include: auxKeyFunc( AUX_?, functionName);
     * where ? is a key on the keyboard and functionName() is the
     *    function to call when that key is pressed.
     * 
     * ? include a, b, c ... z,  A, B, C ... Z, UP, DOWN, LEFT, RIGHT
     */
    
    auxExposeFunc(reshape);
    auxReshapeFunc(reshape);


    auxMainLoop( display );

 
    return 0;
}



