#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>


// variables go here
#define WIDTH 600
#define HEIGHT 600
#define FALSE 0
#define TRUE 1
#define LEFT
#define TOP
#define NSOURCES 3

typedef struct source
{
	int x;
	int y;
	float f;

}SOURCE, *PSOURCE;

source s1, s2, s3, s4;
source src[NSOURCES];
float value[WIDTH][HEIGHT];
int first;

// functions start here
void initalize(void);
void draw(void);
void update(void);
void animate(void);
void camera(void);
void ifs(void);
void interference(void);
void scale(void);

/////////////////////////////////////////
void main(int argc, char* argv[])
{
	int nSources = NSOURCES;
	extern source s1, s2, s3, s4, s5, s6;
	extern source src[NSOURCES];
	int i;
	
	s1.f = 100;
	s1.x = 25;
	s1.y = 25;

	s2.f = 77;
	s2.x = 452;
	s2.y = 325;

	s3.f = 66;
	s3.x = 210;
	s3.y = 150;

	s4.f = 49;
	s4.x = 570;
	s4.y = 111;

	src[0] = s1;
	src[1] = s2;
	src[2] = s3;
	//src[3] = s4;

glutInit(&argc, argv);
initalize();
glutMainLoop();
}
////////////////////////////////////////
void animate(void){
update();
glutPostRedisplay();	
}

void initalize(void)
{
// glvariables and initializations go here
glutInitDisplayMode(GLUT_DOUBLE |GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(WIDTH,HEIGHT);
glutInitWindowPosition(100, 100);
glutCreateWindow("chuck_d");
glutDisplayFunc(draw);
glutIdleFunc(animate);
glPointSize(1.5);


}

void draw(void)
{
// clearing background
	glClearColor( 0.0, 0.0, 0.0, 1.0 );


// clearing opengl states	
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

// camera
	camera();

// action! (draw here)
	ifs();


// swap buffers
	glutSwapBuffers();
}

void update(void)
{
// update variables here
}

void camera(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, 1.0, .1, 450);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(WIDTH/2, WIDTH/2, 250.0, WIDTH/2, WIDTH/2, 0, 0, 1, 0);
}


void ifs(void)
{
	extern float value[WIDTH][HEIGHT];
	int i,j;
	extern int first;
	first = TRUE;
	interference();
	scale();

	for(i=0; i<WIDTH; i++)
	{
		for(j=0; j<HEIGHT; j++)
		{
			glColor3f(value[i][j]+0.2,value[i][j],value[i][j]);
			glBegin(GL_POINTS);
			glVertex2i(i,j);
			glEnd();

		}
	}
	
	


}

void interference(void)
{
	int nSources = NSOURCES;
	extern source s1, s2;
	extern source src[NSOURCES];
	extern float value[WIDTH][HEIGHT];
	static double d[WIDTH][HEIGHT];
	static source srcs[NSOURCES];
	int i,j,k;
	extern int first;
	double l,s;

	l = s1.f - s2.f;
	s = s1.f + s2.f;

	if (first)
	{
		for(i=0; i<WIDTH; i++)
		{
			for(j=0; j<HEIGHT; j++)
			{
				value[i][j] = 0.0;
			}
		}

		first = FALSE;
		
	}

for(k=0; k<nSources; k++)
{
	for(i=0; i<WIDTH; i++)
	{
		for(j=0; j<HEIGHT; j++)
		{
			float x,y;
			x = i;
			y = j;
			d[i][j] = (src[k].x - x) * (src[k].x - x) + (src[k].y - y) * (src[k].y - y);
			d[i][j] = sqrt(d[i][j]);
			d[i][j] = d[i][j] / 100.0;
		}
	}


	for(i=0; i<WIDTH; i++)
	{
		for(j=0; j<HEIGHT; j++)
		{
			double c;
			//c = cos(d[i][i] * src[k].f);
			//value[i][j] = value[i][j] + c * d[i][j];
			c = sin(d[i][j] * src[k].f);
			value[i][j] = value[i][j] + c;
		}
	}
}//sources loop
}

/*
void scale(void)
{
	int i,j;
	for(i=0; i<WIDTH; i++)
	{
		for(j=0; j<HEIGHT; j++)
		{
			if (value[i][j] > 0.0)
				value[i][j] = 1.0;
			else
				value[i][j] = 0.0;
		}
	}

}


*/
void scale(void)
{
	float max = 0.0;
	int i,j;
	extern float value[WIDTH][HEIGHT];

	for(i=0; i<WIDTH; i++)
	{
		for(j=0; j<HEIGHT; j++)
		{
			if (abs(value[i][j]) > max)
			max = abs(value[i][j]);
		}
	}


	for(i=0; i<WIDTH; i++)
	{
		for(j=0; j<HEIGHT; j++)
		{
			value[i][j] = abs(value[i][j]) / max;
			
		}
	}

}
