// 
// Torbert, 9.12.2008, updated 8.26.2009
// 
// Mandelbrot Set, Version 1.0
// 
// For each pixel, find the corresponding point in a rectangle [-2,2]x[-1.5,1.5]
// in the complex plane, use that point as C, start Z at 0, iterate Z=Z^2+C, use
// that result to color the original point.
// 

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <GL/glut.h>

double pi=3.1415926;

double xmin,ymin,xmax,ymax;
int w=400,h=300;

void display(void)
{
   double x,y,a,b,tmp,c1,c2;
	int j,k,red;

   glClear(GL_COLOR_BUFFER_BIT); // clear the screen

   glBegin(GL_POINTS);
	for(k=0;k<h;k++)
		for(j=0;j<w;j++)
	   { 
			a=b=0.0;
			c1=-2.0+4.0*j/w;
			c2=-1.5+3.0*k/h;
			red=0;
			while(red<255 && a*a+b*b<4.0)
			{
				tmp=a*a-b*b+c1;
				b=2*a*b+c2;
				a=tmp;
				red++;
			}

			x=xmin+(xmax-xmin)*(  j)/w;
			y=ymin+(ymax-ymin)*(h-k)/h;
   		glColor3f(pow(1.0-red/255.0,5.0),0.0,0.0);
	   	glVertex2f(x,y);
	   }
   glEnd();

   glFlush(); // single buffering, for double use glutSwapBuffers();
}
void mouse(int button,int state,int xscr,int yscr)
{
	if(button==GLUT_LEFT_BUTTON)
		if(state==GLUT_DOWN)
		{
			glutPostRedisplay(); // callback
		}
}
void motion(int xscr,int yscr)
{
	printf("(x,y)=(%d,%d)\n",xscr,yscr);
}
void keyfunc(unsigned char key,int xscr,int yscr)
{
	if(key=='q')
	{
		exit(0);
	}
}
void reshape(int wscr,int hscr)
{
	w=wscr; h=hscr;
   glViewport(0,0,(GLsizei)w,(GLsizei)h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();

	xmin=ymin=0.0; xmax=ymax=1.0;
	if(w<=h)
	   ymax=1.0*(GLfloat)h/(GLfloat)w;
	else
		xmax=1.0*(GLfloat)w/(GLfloat)h;

	gluOrtho2D(xmin,xmax,ymin,ymax);
   glMatrixMode(GL_MODELVIEW);
}
int main(int argc,char* argv[])
{  
   glutInit(&argc,argv);
   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // single buffering
   glutInitWindowSize(w,h);                     // for double use GLUT_DOUBLE
   glutInitWindowPosition(100,50);
   glutCreateWindow("Mandelbrot Set");

   glClearColor(1.0,1.0,1.0,0.0);
	glShadeModel(GL_SMOOTH);

   glutDisplayFunc(display);		// register callback functions
	glutIdleFunc(NULL);				// no animation
   glutMouseFunc(mouse);
   glutMotionFunc(motion);
	glutKeyboardFunc(keyfunc);
	glutReshapeFunc(reshape);

   glutMainLoop();					// here we go

   return 0;
}

// 
// Notes
// -----
// chmod 755 Lgcc
// ./Lgcc mandel_0
// ./mandel_0
// 
