/*
	Sean Dobbs
	Period 3
	Makes a bifurcation diagram for the logistic difference function
*/

#include <stdio.h>
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "glaux.h"

// Globals -- used for changing the viewing area and zooming 
static float gZoom = 0.0;
static int theHeight=300;
static int theWidth=700;
static double gXShift=0.0;
static double gYShift=0.0;


// Lets make a window with GL functions

static void Init(void)
{
	glClearColor(0.0, 0.0, 0.0, 1.0);
	glShadeModel( GL_FLAT );
}

// <MAGIC>
static void Reshape( int width, int height )
{
	glViewport(0, 0, (GLint)width, (GLint)height);
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	glOrtho( (0.0-gZoom+gXShift), (4.0+gZoom+gXShift), (0.0-gZoom+gYShift), 
		     (1.0+gZoom+gYShift), -5.0, 5.0);
	glMatrixMode(GL_MODELVIEW);
	theHeight=height;
	theWidth=width;
}

// </MAGIC>

// up arrow zooms out
static void key_up()
{
	gZoom-=.1;
	Reshape(theWidth, theHeight);
}

// down arrow zooms in
static void key_down()
{
        gZoom+=.1;
	Reshape(theWidth, theHeight);
}

// right arrow looks to right
static void key_right()
{
	gXShift += .2;
	Reshape(theWidth, theHeight);
}

// left arrow looks to left
static void key_left()
{
	gXShift -= .2;
	Reshape(theWidth, theHeight);
}

// 'a' key looks up
static void key_a()
{
        gYShift += .1;
        Reshape(theWidth, theHeight);
}

// 'z' key looks down
static void key_z()
{
        gYShift -= .1;
        Reshape(theWidth, theHeight);
}


static void key_esc()
{
	auxQuit();
}

// Draw the bifurcation
void DrawMyStuff()
{
	double x, k, n, r=0.4, g=0.8, b=.90;

	glColor3f(r,g,b);
	glBegin( GL_POINTS );

	// Loop through the k values
	for(k=0.1; k<4; k+=0.003)
	{
		x = 0.22;
		for(n=0; n<50; n++)
		{
			x = k * x * (1 - x);
			glVertex3f(k, x, -3.0);
		}
		r-=.0002;
		g-=.0004;
		glColor3f(r, g, b);
	}
	glEnd();
}

// The main loop
static void display()
{
	glClear( GL_COLOR_BUFFER_BIT );
	DrawMyStuff();
	glFlush();
	auxSwapBuffers();
}

int main(int arc, char **argv)
{
	auxInitDisplayMode( AUX_RGBA );
	
	// Window starting at (50,50) and 300x700 pixels big
	auxInitPosition(70,70,700,300);

	// If something goes wrong, bail
	if(auxInitWindow("My Window") == GL_FALSE)
	{
		auxQuit();
	}

	Init();

	// <MAGIC>
	auxExposeFunc(Reshape);
	auxReshapeFunc(Reshape);
	// </MAGIC>

	// assign functions to keys ...
	auxKeyFunc( AUX_UP, key_up );
	auxKeyFunc( AUX_DOWN, key_down );
	auxKeyFunc( AUX_LEFT, key_left );
	auxKeyFunc( AUX_RIGHT, key_right );
	auxKeyFunc( AUX_a, key_a );
	auxKeyFunc( AUX_z, key_z );

	// ... and off we go!
	auxMainLoop( display );
	return 0;
}
