//mend&jul&targa  program    proj4, ver-c.
//
//by Adrian Porter
//Super Computer Applications



//  -----  header files here:


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




//  ----- global stuff here:


const double pi=3.1415926535;
//const int w = 960, h = 768;
const int w = 200, h = 200;
int screenw = 200, screenh = 200;

int doredraw=1;
int option=0;
double jx, jy;
int jison=0;

int firsttime=1;
int points=0;
int pointx[400], pointy[400];


long maxiterations=1000;

double rpal[70],gpal[70],bpal[70];
int data[500][500];

//global targa struct
typedef struct {
	char id_len;
	char map_type;
	char img_type;
	int map_first;
	int map_len;
	char map_entry_size;
	int x, y, width, height;
	char bpp, misc;
} targa_header;
targa_header header;


//prototypes for targa file
void writeheader(FILE *);
void setupheader();
void putpixel(double, double, double, FILE *);







//prototype
static void display( );









//  ------  initializing funcs here:


void coolpal (void) {

	//this initializes the pallet to a rainbow ROYGBV (no I)	


	int i=0;
	double r2=1,g2=0,b2=0;
	//red
	for(;i<10;i++) {
		g2+=1.0/10.0;
		rpal[i]=r2; gpal[i]=g2; bpal[i]=b2;
	}
	//yellow
	for(;i<20;i++) {
		r2-=1.0/10.0;
		rpal[i]=r2; gpal[i]=g2; bpal[i]=b2;
	}
	//green
	for(;i<30;i++) {
		g2-=1.0/10.0;
		b2+=1.0/10.0;
		rpal[i]=r2; gpal[i]=g2; bpal[i]=b2;
	}
	//blue
	for(;i<40;i++) {
		r2+=0.8/10.0;
		b2-=0.2/10.0;
		rpal[i]=r2; gpal[i]=g2; bpal[i]=b2;
	}
	//purple
	for(;i<50;i++) {
		r2+=0.2/10.0;
		b2-=0.8/10.0;
		rpal[i]=r2; gpal[i]=g2; bpal[i]=b2;
	}
	//red
	/////////////////////////////////
}	
	



void goinit(void) {
        
//outputs the instructions to screen, cool!


}







//  ------  redraw funcs here:

void movething(int& x, int& y);
int checkthing(int x, int y);

void godraw(void)  // The Drawing Routine
{
	long i;
	int x, y, count;
	int num;
	FILE *tga;
	srand(23);
	cout << "pixels:"; cin >> maxiterations;

	for(x=0;x<screenw;x++) for(y=0;y<screenh;y++) {
		data[x][y]=0;
	}
	
	glBegin(GL_POINTS);
	for(num=0;num<points;num++) {
		data[pointx[num]][pointy[num]] = 1;
		glColor3f(rpal[1], gpal[1], bpal[1]);
		glVertex3f(pointx[num], pointy[num], 0.0);
	}
	glEnd();
	glFlush();
	auxSwapBuffers();

	x = int(rand() % screenw); y = int(rand() % screenh);
	
	i=0;
	while(i<maxiterations) {
		movething(x, y);
		if(checkthing(x, y)) {
			data[x][y] = checkthing(x, y) + 1;
			glBegin(GL_POINTS);
			glColor3f(rpal[data[x][y]%50], gpal[data[x][y]%50], bpal[data[x][y]%50]);
			glVertex3f(x, y, 0.0);
			glEnd();
			glFlush();
		   	auxSwapBuffers();
			x = int(rand() % screenw); y = int(rand() % screenh);
			i++;
		}
	}
	setupheader();
	tga=fopen("pic.tga", "wb");
	writeheader(tga);
	cout << "targa file . . . please wait";
	cout << "\n";
	for(y=0;y<screenh;y++) for(x=0;x<screenw;x++) {
		if(data[x][y]==0) putpixel(0, 0, 0, tga);
		else putpixel(rpal[data[x][y]%50], gpal[data[x][y]%50], bpal[data[x][y]%50], tga);
	}
	fclose(tga);
	cout << "done\n";

}



void movething(int& x, int& y) {
	x+=int(rand() % 3 - 1);
	y+=int(rand() % 3 - 1);
	if(x<=0) x=0;
	if(x>screenw) x=screenw-1;
	if(y<=0) y=0;
	if(y>screenh) y=screenh-1;
}

int checkthing(int x, int y) {
	int a, b;
	for(a=x-1;a<=x+1;a++) for(b=y-1;b<=y+1;b++)
		if(!(a==x && b==y) && a>=0 && a<screenw && b>=0 && b<screenh)
			if(data[a][b]!=0) return data[a][b];
	return 0;
}
			




//  ------  targa file funcs here:



void writeheader(FILE *tga) {  //writes the header to file tga
	fputc(header.id_len, tga);
	fputc(header.map_type, tga);
	fputc(header.img_type, tga);
	fputc(header.map_first % 256, tga);
	fputc(header.map_first / 256, tga);
	fputc(header.map_len % 256, tga);
	fputc(header.map_len / 256, tga);
	fputc(header.map_entry_size, tga);
	fputc(header.x % 256, tga);
	fputc(header.x / 256, tga);
	fputc(header.y % 256, tga);
	fputc(header.y / 256, tga);
	fputc(header.width % 256, tga);
	fputc(header.width / 256, tga);
	fputc(header.height % 256, tga);
	fputc(header.height / 256, tga);
	fputc(header.bpp, tga);
	fputc(header.misc, tga);
}

void setupheader(void) {   //sets up the header
	header.id_len=0;
	header.map_type=0;
	header.img_type=2;
	header.map_first=0;
	header.map_len=0;
	header.map_entry_size=0;
	header.x=0;
	header.y=0;
	header.width=screenw;
	header.height=screenh;
	header.bpp=24;
	header.misc=0x20;
}

void putpixel(double red3, double green3, double blue3, FILE *tga) {  //puts a pixel to file
	fputc(char(int(blue3*255)), tga);
	fputc(char(int(green3*255)), tga);
	fputc(char(int(red3*255)), tga);
}




















//  ------  mouse funcs here:



static GLenum gomouse(int mouseX, int mouseY, GLenum button)
{
	pointx[points]=mouseX;
	pointy[points]=mouseY;
	glBegin(GL_POINTS);
	glColor3f(rpal[1], gpal[1], bpal[1]);
	glVertex3f(mouseX, mouseY, 0.0);
	glEnd();
	glFlush();
  	auxSwapBuffers();
	points++;
}











//  ------  window funcs here:



// This Section creates a Window, but uses only GL commands rather than X.

//3.
static void Init( void )
{
   /* one-time init (clearColor, set palette, etc) */
   glClearColor(0.0, 0.0, 0.0, 1.0 );
   glShadeModel( GL_FLAT );
}



static void Reshape( int width, int height )  // Essential Magic again!
{

   glViewport(0, 0, (GLint)width, (GLint)height);

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho (0.0, width-1, height-1, 0.0, -1.0, 1.0 );
   glMatrixMode(GL_MODELVIEW);
   screenw=width+8;screenh=height+2;
   // doredraw=1;  do not redraw everytime the user switches screens!!!!
                    //the user may press r to redraw screen
}














//  -----  key funcs here:



//when a button is pressed, the values of
//ax, bx, ay, & by are changed and the screen
//is updated when the display() is run.


static void key_r( ) {
	doredraw=1;
}

static void key_e( ) {
	points=0;
	glClear( GL_COLOR_BUFFER_BIT );
	glFlush();
  	auxSwapBuffers();
}
	




//  ------  redraw screen func:



static void display( )  // Main display routine called from event loop
{
   
   if(doredraw) {
	doredraw=0;	
   	glClear( GL_COLOR_BUFFER_BIT );
	if(!firsttime) godraw();
	firsttime=0;

   }	


}





//  -----  main func:



int main( int argc, char **argv )
{  
	
   
   goinit();
   coolpal();	

   auxInitDisplayMode( AUX_RGBA );  // Initialize Display in RGB mode

   auxInitPosition( 0,0, w-8, h-2 );  // Draw a window starting at (50,50)
                                        // with size of 400 pixels for both                                        // X and Y dimensions.

   if (auxInitWindow("My Window") == GL_FALSE)  // Create window and give it 
    { 						// a name.  If problems, quit. 
      auxQuit();
    }

   Init();  // Call Init routine

   auxExposeFunc(Reshape);  //  More Magic

   auxReshapeFunc(Reshape);
   //key events
   auxKeyFunc( 'r', key_r );
   auxKeyFunc( 'e', key_e );
  
   tkMouseDownFunc(gomouse);


   auxMainLoop( display );  // Call display loop with display function
   //display();


   return 0;
}
