#include <GL/gl.h>
#include <GL/glu.h>
#include "aux.h"
#define GRAD 360
#define GL_PI 3.1415f

GLbyte  bCull,bOutline,bDepth;
// Rotation amounts
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;




void display(void)
{
GLfloat x,y,angle;  // Storage for coordinates and angles
        int iPivot = 1;         // Used to flag alternating colors

        // Clear the window and the depth buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Turn culling on if flag is set
        if(bCull)
                glEnable(GL_CULL_FACE);
        else
                glDisable(GL_CULL_FACE);

        // Enable depth testing if flag is set
        if(bDepth)
                glEnable(GL_DEPTH_TEST);
        else
                glDisable(GL_DEPTH_TEST);

        // Draw back side as a polygon only, if flag is set
        if(bOutline)
                glPolygonMode(GL_BACK,GL_LINE);
        else
                glPolygonMode(GL_BACK,GL_FILL);


 // Save matrix state and do the rotation
        glPushMatrix();
        glRotatef(xRot, 1.0f, 0.0f, 0.0f);
        glRotatef(yRot, 0.0f, 1.0f, 0.0f);


        // Begin a triangle fan
        glBegin(GL_TRIANGLE_FAN);

        // Pinnacle of cone is shared vertex for fan, moved up Z axis
        // to produce a cone instead of a circle
        glVertex3f(0.0f, 0.0f, 75.0f);

        // Loop around in a circle and specify even points along the circle
        // as the vertices of the triangle fan
        for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/8.0f))
                {
                // Calculate x and y position of the next vertex
                x = 50.0f*sin(angle);
                y = 50.0f*cos(angle);

                // Alternate color between red and green
                if((iPivot %2) == 0)
                        glColor3f(0.0f, 1.0f, 0.0f);
                else
                        glColor3f(1.0f, 0.0f, 0.0f);

                // Increment pivot to change color next time
                iPivot++;

                // Specify the next vertex for the triangle fan
                glVertex2f(x, y);
                }

        // Done drawing fan for cone
        glEnd();
        // Begin a new triangle fan to cover the bottom
        glBegin(GL_TRIANGLE_FAN);

        // Center of fan is at the origin
        glVertex2f(0.0f, 0.0f);
        for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/8.0f))
                {
                // Calculate x and y position of the next vertex
                x = 50.0f*sin(angle);
                y = 50.0f*cos(angle);

                // Alternate color between red and green
                if((iPivot %2) == 0)
                        glColor3f(0.0f, 1.0f, 0.0f);
                else
                        glColor3f(1.0f, 0.0f, 0.0f);

                // Increment pivot to change color next time
                iPivot++;

                // Specify the next vertex for the triangle fan
                glVertex2f(x, y);
                }

        // Done drawing the fan that covers the bottom
        glEnd();

        // Restore transformations
        glPopMatrix();

        // Flush drawing commands
        glFlush();

}

void myinit (void) { 
     // Black background        
                glClearColor(0.0f, 0.0f, 0.0f, 0.0f );

        // Set drawing color to green        
                glColor3f(0.0f, 1.0f, 0.0f);

        // Set color shading model to flat        
                glShadeModel(GL_FLAT);

        // Clock wise wound polygons are front facing, this is reversed       
 // because we are using triangle fans
        glFrontFace(GL_CW);

}

void myReshape(int w, int h)
{
    GLfloat nRange = 100.0f;

        // Prevent a divide by zero
        if(h == 0)
                h = 1;

        // Set Viewport to window dimensions
    glViewport(0, 0, w, h);

        // Reset coordinate system
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

        // Establish clipping volume (left, right, bottom, top, near, far)
    if (w <= h)
                glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
    else
                glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

}
void uphandle(void) { xRot-= 5.0f; if(xRot < -1.0f) xRot = 355.0f;}
void downhandle(void) { xRot+= 5.0f;if(xRot > 356.0f) xRot = 0.0f; }
void lefthandle(void) { yRot -= 5.0f; if(yRot < -1.0f) yRot = 355.0f;}
void righthandle(void) { yRot += 5.0f;  if(yRot > 356.0f) yRot = 0.0f;}
void c_handle(void) { bCull++; bCull %= 2; }
void b_handle(void) { bOutline++; bOutline %= 2; }
void d_handle(void) { bDepth++; bDepth %= 2; }
int main(int argc, char** argv)
{
    auxInitDisplayMode (AUX_SINGLE | AUX_RGB | AUX_DEPTH);
    auxInitPosition (0, 0, 500, 500);
    auxInitWindow (argv[0]);
    myinit ();
    auxKeyFunc(AUX_UP,uphandle);
    auxKeyFunc(AUX_DOWN,downhandle);
    auxKeyFunc(AUX_LEFT,lefthandle);
    auxKeyFunc(AUX_RIGHT,righthandle);
    auxKeyFunc(AUX_c,c_handle);
    auxKeyFunc(AUX_b,b_handle);
    auxKeyFunc(AUX_d,d_handle);
    auxReshapeFunc (myReshape);
    auxMainLoop(display);
}