#include <math.h>
#include <SDL/SDL.h>


Uint32 yellow;
Uint32 red;
Uint32 green;
Uint32 blue;
Uint32 white;
Uint32 brown;
Uint32 grey;

SDL_Event event;

struct  {
	float time;
	int tick;
	int end;
	int scale;
}EzE_state;

struct  {
	float x;
	float y;
	float w;
	float h;
	int b;
}EzE_mice;


//=================================================================================================
//=================================================================================================
//=================================================================================================
//=================================================================================================

void EzE_Init(SDL_Surface *eze_surface)
{
	if (eze_surface->w > eze_surface->h)
	{
		EzE_state.scale = eze_surface->h;
	}
	else
	{
		EzE_state.scale = eze_surface->w;
	}

	yellow = SDL_MapRGB(eze_surface->format, 0xff, 0xff, 0x00);
	red = SDL_MapRGB(eze_surface->format, 0xff, 0x00, 0x00);
	blue = SDL_MapRGB(eze_surface->format, 0x00, 0x00, 0xff);
	green = SDL_MapRGB(eze_surface->format, 0x00, 0xff, 0x00);
	white = SDL_MapRGB(eze_surface->format, 0xff, 0xff, 0xff);
	brown = SDL_MapRGB(eze_surface->format, 0xcc, 0x99, 0x00);
	grey = SDL_MapRGB(eze_surface->format, 0xcc, 0xcc, 0xcc);
}

int EzE_Loop(SDL_Surface *eze_surface) 
{
	EzE_state.end = 0;
	EzE_state.tick = SDL_GetTicks();
	EzE_state.time = ((float)EzE_state.tick) / 1000;

	while ( SDL_PollEvent(&event) ) {
		switch ( event.type ) {
			case SDL_QUIT:
				EzE_state.end = 1;
				break;
			case SDL_MOUSEMOTION:
				EzE_mice.x = (((float)event.motion.x / (eze_surface->w/2))-1)  * ((float)eze_surface->w / EzE_state.scale);
				EzE_mice.y = (-(((float)event.motion.y / (eze_surface->h/2))-1))  * ((float)eze_surface->h / EzE_state.scale);
				//EzE_mice.w =  ((float)2*event.motion.xrel / (EzE_state.scale/2));
				//EzE_mice.h = -((float)2*event.motion.yrel / (EzE_state.scale/2));
				break;
			case SDL_MOUSEBUTTONDOWN:
				EzE_mice.b = 1;
				break;
			case SDL_MOUSEBUTTONUP:
				EzE_mice.b = 0;
				break;
		}
	}

	SDL_UpdateRect(eze_surface, 0, 0, 0, 0);

	return EzE_state.end;
}

//=================================================================================================
//=================================================================================================
//=================================================================================================
//=================================================================================================

void EzE_Sleep(float time)
{
	SDL_Delay((int)(time * 1000));
}

//=================================================================================================
//=================================================================================================
//=================================================================================================
//=================================================================================================

void EzE_Clear(SDL_Surface *surface)
{
		SDL_FillRect(surface,NULL,0x00ffffff);
}

Uint32 EzE_Got_Pixel(SDL_Surface *EzE_surface, float EzE_w, float EzE_h)
{
	int EzE_x = (int)(((1+EzE_w)) * (EzE_state.scale/2)) + ((EzE_surface->w - EzE_state.scale)/2);
	int EzE_y = (int)((2-(1+EzE_h)) * (EzE_state.scale/2)) + ((EzE_surface->h - EzE_state.scale)/2);

	if ( (EzE_x>=0) || (EzE_x<=EzE_surface->w) || (EzE_y>=0) || (EzE_y<=EzE_surface->h) )
	{
		int EzE_bpp = EzE_surface->format->BytesPerPixel;
		Uint8 *EzE_offzet = (Uint8 *)EzE_surface->pixels + EzE_y * EzE_surface->pitch + EzE_x * EzE_bpp;
		switch(EzE_bpp) 
		{
	    		case 1:
        			return *EzE_offzet;
	    		case 2:
	        		return *(Uint16 *)EzE_offzet;
	    		case 3:
	        		if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
	            			return EzE_offzet[0] << 16 | EzE_offzet[1] << 8 | EzE_offzet[2];
	        		else
	            			return EzE_offzet[0] | EzE_offzet[1] << 8 | EzE_offzet[2] << 16;
	    		case 4:
	        		return *(Uint32 *)EzE_offzet;
	    		default:
	        		return 0;
	    	}
	}
	return 0;
}

void EzE_Giv_Pixel(SDL_Surface *EzE_surface, float EzE_w, float EzE_h,Uint32 EzE_color)
{
	int EzE_x = (int)((1+EzE_w) * (EzE_state.scale/2)) + ((EzE_surface->w - EzE_state.scale)/2);
	int EzE_y = (int)((2-(1+EzE_h)) * (EzE_state.scale/2)) + ((EzE_surface->h - EzE_state.scale)/2);

	if ((EzE_x >= 0)||(EzE_x <= EzE_surface->w)||(EzE_y >= 0)||(EzE_y <= EzE_surface->h))
	{
     		int EzE_bpp = EzE_surface->format->BytesPerPixel;
    		Uint8 *EzE_offzet = (Uint8 *)EzE_surface->pixels + EzE_y * EzE_surface->pitch + EzE_x * EzE_bpp;
    		switch(EzE_bpp) 
		{
			case 1:
	        		*EzE_offzet = EzE_color;
	        		break;
	    		case 2:
        			*(Uint16 *)EzE_offzet = EzE_color;
	        		break;
	    		case 3:
	        		if(SDL_BYTEORDER == SDL_BIG_ENDIAN) 
				{
	            			EzE_offzet[0] = (EzE_color >> 16) & 0xff;
	            			EzE_offzet[1] = (EzE_color >> 8) & 0xff;
	            			EzE_offzet[2] = EzE_color & 0xff;
	        		} 
				else 
				{
	            			EzE_offzet[0] = EzE_color & 0xff;
	            			EzE_offzet[1] = (EzE_color >> 8) & 0xff;
	            			EzE_offzet[2] = (EzE_color >> 16) & 0xff;
	        		}
	        	break;
	    			case 4:
	        		*(Uint32 *)EzE_offzet = EzE_color;
	        	break;
	    	}
	}
}

void EzE_brescircle(SDL_Surface *EzE_surface,float radius,float xcenter,float ycenter,Uint32 color) 
{
  	float xstart = 0;
  	float ystart = radius;
  	float sum = 0.03-2*radius;
  	while(xstart <= ystart)
  	{
        	SDL_LockSurface(EzE_surface);
        	EzE_Giv_Pixel(EzE_surface,xstart+xcenter,ystart+ycenter,color);
        	EzE_Giv_Pixel(EzE_surface,-xstart+xcenter,ystart+ycenter,color);
       		EzE_Giv_Pixel(EzE_surface,xstart+xcenter,-ystart+ycenter,color);
		EzE_Giv_Pixel(EzE_surface,-xstart+xcenter,-ystart+ycenter,color);
		EzE_Giv_Pixel(EzE_surface,ystart+xcenter,xstart+ycenter,color);
		EzE_Giv_Pixel(EzE_surface,-ystart+xcenter,xstart+ycenter,color);
		EzE_Giv_Pixel(EzE_surface,ystart+xcenter,-xstart+ycenter,color);
		EzE_Giv_Pixel(EzE_surface,-ystart+xcenter,-xstart+ycenter,color);
		SDL_UnlockSurface(EzE_surface);
      		if(sum <= 0)
      		{
			sum = sum + 4*xstart + 0.06;
        	}
      		else
      		{
			sum = sum + 4*(xstart-ystart) + 0.10;
			ystart = ystart - 0.003;
      		}
      		xstart = xstart + 0.003;
  	}
}

void EzE_bresline(SDL_Surface *EzE_surface, float lx1, float lx2, float ly1, float ly2, Uint32 color)
{
     	float deltax,deltay,lx,ly,xinc1,xinc2,yinc1,yinc2,den,num,numadd,numpixels,curpixel;
     	deltax = fabs(lx2 - lx1);        // The difference between the x's
     	deltay = fabs(ly2 - ly1);        // The difference between the y's
     	lx = lx1;                       // Start x off at the first pixel
     	ly = ly1;                       // Start y off at the first pixel

     	if (lx2 >= lx1)                 // The x-values are increasing
     	{      	xinc1 = 0.003;
           	xinc2 = 0.003;
     	} else {
           	xinc1 = -0.003;
           	xinc2 = -0.003;
     	}

     	if (ly2 >= ly1)                 // The y-values are increasing
     	{      	yinc1 = 0.003;
           	yinc2 = 0.003;
     	} else {
           	yinc1 = -0.003;
           	yinc2 = -0.003;
     	}

     	if (deltax >= deltay)         // There is at least one x-value for every y-value
     	{      	xinc1 = 0;                  // Don't change the x when numerator >= denominator
           	yinc2 = 0;                  // Don't change the y for every iteration
           	den = deltax;
           	num = deltax / 2;
           	numadd = deltay;
           	numpixels = deltax;         // There are more x-values than y-values
     	} else {
           	xinc2 = 0;                  // Don't change the x for every iteration
           	yinc1 = 0;                  // Don't change the y when numerator >= denominator
           	den = deltay;
           	num = deltay / 2;
           	numadd = deltax;
           	numpixels = deltay;         // There are more y-values than x-values
     	}
        SDL_LockSurface(EzE_surface);
     	for (curpixel = 0; curpixel <= numpixels; curpixel = curpixel + 0.003)
     	{
           	EzE_Giv_Pixel(EzE_surface,lx,ly,color);
           	num += numadd;              // Increase the numerator by the top of the fraction
           	if (num >= den)             // Check if numerator >= denominator
           	{
                  	num -= den;               // Calculate the new numerator value
                  	lx += xinc1;               // Change the x as appropriate
                  	ly += yinc1;               // Change the y as appropriate
           	}
           	lx += xinc2;                 // Change the x as appropriate
           	ly += yinc2;                 // Change the y as appropriate
     	}
        SDL_UnlockSurface(EzE_surface);
}


void EzE_Stamp(SDL_Surface * EzE_surface, float EzE_x, float EzE_y,SDL_Surface * stamp)
{
	SDL_Rect rectsrc, rectdest;
	rectsrc.h = stamp->h;
	rectsrc.w = stamp->w;
	rectsrc.x = 0;
	rectsrc.y = 0;
	rectdest.x = (int)((1+EzE_x)/2 * EzE_state.scale) - rectsrc.h/2 + ((EzE_surface->w - EzE_state.scale)/2);
	rectdest.y = (int)((1-EzE_y)/2 * EzE_state.scale) - rectsrc.w/2 + ((EzE_surface->h - EzE_state.scale)/2);
	rectdest.h = rectsrc.h;		//here i should set if screen border cut the stamp
	rectdest.w = rectsrc.w;

	SDL_BlitSurface(stamp, &rectsrc, EzE_surface, &rectdest);
}

SDL_Surface * EzE_Format(SDL_Surface * EzE_surface)
{
	SDL_Surface * EzE_tmp = SDL_DisplayFormat(EzE_surface);
	SDL_FreeSurface(EzE_surface);
	//Map the color key 
	Uint32 EzE_colorkey = SDL_MapRGB( EzE_tmp->format, 0xFF, 0xFF, 0xFF );
	//Set all pixels of color R 0, G 0xFF, B 0xFF to be transparent 
	SDL_SetColorKey( EzE_tmp, SDL_RLEACCEL | SDL_SRCCOLORKEY, EzE_colorkey );

	return EzE_tmp;
}
//=================================================================================================
//=================================================================================================
//=================================================================================================
//=================================================================================================
