#include <math.h>
#include <stdlib.h>
#include "noidZ.h"

#define limit 1001
#define scale 0.05
#define decay 0.7071
#define gravite 50

struct {
	float x;
	float y;
	float mass;
	float horizontal;
	float vertical;
} bulles[limit];

//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================

void repulse(int m,int k)
{
	float deltaX = (bulles[m].x - bulles[k].x);
	float deltaY = (bulles[m].y - bulles[k].y);
	float dist = fabs(deltaX*deltaX)+fabs(deltaY*deltaY);
	float rapport = (bulles[m].mass)+(bulles[k].mass);
	if (dist <= (rapport*rapport))
	{
		bulles[m].horizontal = bulles[m].horizontal + ((deltaX*bulles[k].mass)/dist);
		bulles[m].vertical = bulles[m].vertical + ((deltaY*bulles[k].mass)/dist);
		bulles[k].horizontal = bulles[k].horizontal + ((deltaX*bulles[m].mass)/dist);
		bulles[k].vertical = bulles[k].vertical + ((deltaY*bulles[m].mass)/dist);
	}
}

void friction(int bumb)
{	//int bumb;
	//for (bumb = 1 ; bumb < limit ; bumb = bumb+1)
	//{	
	bulles[bumb].horizontal = bulles[bumb].horizontal * decay;
	bulles[bumb].vertical = bulles[bumb].vertical * decay;
	//}
}

void permutation(int bumb)
{	//int bumb;
	//for (bumb = 1 ; bumb < limit ; bumb = bumb+1)
	//{	
	bulles[bumb].horizontal = bulles[bumb].horizontal / (limit+2);
	bulles[bumb].vertical = bulles[bumb].vertical / (limit+2);
	bulles[bumb].x = bulles[bumb].x + scale*bulles[bumb].horizontal;
	bulles[bumb].y = bulles[bumb].y + scale*bulles[bumb].vertical;
	//}
}

void gravity(int bumb)
{	//int bumb;
	//for (bumb = 1 ; bumb < limit ; bumb = bumb+1)
	//{
		bulles[bumb].vertical = bulles[bumb].vertical - gravite;
	//}
}

void valley(int bumb,float tan,float cot,float x, float y)
{	//int bumb;
	//for (bumb = 1 ; bumb < limit ; bumb = bumb+1)
	//{
		float deltaX = (x - bulles[bumb].x);
		float deltaY = tan * (y - bulles[bumb].y);
		if (deltaX<deltaY)
		{
			bulles[bumb].horizontal = -(abs(bulles[bumb].horizontal));
			bulles[bumb].vertical = fabs(bulles[bumb].vertical);
			bulles[bumb].x = x - fabs(deltaY) - 0.01;
		}
	//}
}

void covalley(int bumb,float tan,float x, float y)
{
	//int bumb;
	//for (bumb = 1 ; bumb < limit ; bumb = bumb+1)
	//{
		float deltaX = (bulles[bumb].x - x);
		float deltaY = tan * (y - bulles[bumb].y);
		if (deltaX<deltaY)
		{
			bulles[bumb].horizontal = (fabs(bulles[bumb].horizontal));
			bulles[bumb].vertical = (fabs(bulles[bumb].vertical));
			bulles[bumb].x = x + fabs(deltaY) + 0.01;
		}
	//}
}

void wall_bulle(int bumb)
{	//int bumb;
	//for (bumb = 1 ; bumb < limit ; bumb = bumb+1)
	//{	
		if (bulles[bumb].x >= 0.951)
		{
			bulles[bumb].x = 0.95;
			bulles[bumb].horizontal = 1-fabs(bulles[bumb].horizontal);

		}
		if (bulles[bumb].x <= -0.951)
		{
			bulles[bumb].x = -0.95;
			bulles[bumb].horizontal = fabs(bulles[bumb].horizontal);

		}
		if (bulles[bumb].y >= 0.951)
		{
			bulles[bumb].y = 0.95;
			bulles[bumb].vertical = 1-fabs(bulles[bumb].vertical);
		}
		if (bulles[bumb].y <= -0.951)
		{
			bulles[bumb].y = -0.95;
			bulles[bumb].vertical = fabs(bulles[bumb].vertical);
		}
	//}
}


void warp_bulle(int bumb)
{	//int bumb;
	//for (bumb = 1 ; bumb < limit ; bumb = bumb+1)
	//{
		if (bulles[bumb].x <= -1)
		{	bulles[bumb].x = bulles[bumb].x + floor(fabs(bulles[bumb].x));
				bulles[bumb].x = bulles[bumb].x + 1;
		}
		if (bulles[bumb].y <= -1)
		{	bulles[bumb].y = bulles[bumb].y + floor(fabs(bulles[bumb].y));
				bulles[bumb].y = bulles[bumb].y + 1;
		}
		if (bulles[bumb].x >= 1)
		{	bulles[bumb].x = bulles[bumb].x - floor(fabs(bulles[bumb].x));
				bulles[bumb].x = bulles[bumb].x -1;
		}
		if (bulles[bumb].y >= 1)
		{	bulles[bumb].y = bulles[bumb].y - floor(fabs(bulles[bumb].y));
				bulles[bumb].y = bulles[bumb].y -1;
		}
	//}
}

//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================

void toute_bulle(void)
{
	int bumb;
	for (bumb = 1 ; bumb < limit ; bumb = bumb+1)
	{
				friction(bumb);
				gravity(bumb);

				//wall_bulle(bumb);
				warp_bulle(bumb);

				valley(bumb,1.5,-1,1,0);
				covalley(bumb,1,-1,0);
				permutation(bumb);

	}
}

void inter_bulle(void)
{	int bumb;
	for (bumb = 1 ; bumb < limit ; bumb = bumb+1)
	{	int dumb;
		for (dumb = bumb; dumb < limit; dumb = dumb+1)
		{	if(dumb != bumb)
			{
				repulse(bumb,dumb);
			}
		}
	}
}



//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================


void init_bulle(void)
{	int bumb;
	for (bumb = 1 ; bumb < limit ; bumb = bumb+1)
	{	bulles[bumb].x = ((float)rand()/ (RAND_MAX/2)-1);
		bulles[bumb].y = ((float)rand()/ (RAND_MAX/2)-1);
		bulles[bumb].mass = ((float)rand()/ (RAND_MAX))/10;
	}
}

void draw_bulle(SDL_Surface *surface)
{	int bumb;
	for (bumb = 1 ; bumb < limit ; bumb = bumb+1)
	{	//brescircle(surface,0.01,bulles[bumb].x,bulles[bumb].y,0xffff0000+(Uint32)(bulles[bumb].mass*655360));
		noidZ_Giv_Pixel(surface,bulles[bumb].x,bulles[bumb].y,0xffff0000+(Uint32)(bulles[bumb].mass*655360));
	}
}




//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================


