#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include <math.h>
#include "sdlcommon.h"

bool inCarArea(SDL_Surface *screen, int x, int y)
	{
	if(x<0 || y<0 || x>screen->w || y>screen->h) return 0;
	if(x<320 && y<100) return 0;
	//DrawLine(screen,0,100,320,100,0,0,128);
	return 1;
	}

void setpixel(SDL_Surface *screen, int x, int y, Uint8 r, Uint8 g, Uint8 b)
	{
	Uint8 *ubuff8;
	Uint16 *ubuff16;
	Uint32 *ubuff32;
	Uint32 color;
	char c1, c2, c3;
	
	if(x >= screen->w || x < 0 || y >= screen->h || y <0 ) return;
	
	if(SDL_MUSTLOCK(screen)) 
		{
		if(SDL_LockSurface(screen) < 0) 
		return;
		}	
	color = SDL_MapRGB( screen->format, r, g, b );
	switch(screen->format->BytesPerPixel) 
		{
		case 1: 
			ubuff8 = (Uint8*) screen->pixels;
			ubuff8 += (y * screen->pitch) + x; 
			*ubuff8 = (Uint8) color;
			break;
		case 2:
			ubuff8 = (Uint8*) screen->pixels;
			ubuff8 += (y * screen->pitch) + (x*2);
			ubuff16 = (Uint16*) ubuff8;
			*ubuff16 = (Uint16) color; 
			break;  
		case 3:
			ubuff8 = (Uint8*) screen->pixels;
			ubuff8 += (y * screen->pitch) + (x*3);
			if(SDL_BYTEORDER == SDL_LIL_ENDIAN) 
				{
				c1 = (color & 0xFF0000) >> 16;
				c2 = (color & 0x00FF00) >> 8;
				c3 = (color & 0x0000FF);
				} 
			else	{
				c3 = (color & 0xFF0000) >> 16;
				c2 = (color & 0x00FF00) >> 8;
				c1 = (color & 0x0000FF);
				}
			ubuff8[0] = c3;
			ubuff8[1] = c2;
			ubuff8[2] = c1;
			break;
		case 4:
			ubuff8 = (Uint8*) screen->pixels;
			ubuff8 += (y*screen->pitch) + (x*4);
			ubuff32 = (Uint32*)ubuff8;
			*ubuff32 = color;
			break;
		default:
			fprintf(stderr, "Error: Unknown bitdepth!\n");
		}
	if(SDL_MUSTLOCK(screen)) 
		{
		SDL_UnlockSurface(screen);
		}
	}
	
int getpixel(SDL_Surface *screen, int x, int y)
	{
	int bpp = screen->format->BytesPerPixel;
	Uint8 *p = (Uint8 *)screen->pixels + y * screen->pitch + x * bpp;
	switch(bpp)
		{
		case 1:
		return *p;
		case 2:
			return *(Uint16 *)p;
		case 3:
			if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
				return p[0] << 16 | p[1] << 8 | p[2];
			else
				return p[0] | p[1] << 8 | p[2] << 16;
		case 4:
			return *(Uint32 *)p;
		default:
			return 0;
		}
	}
	
void interpole(SDL_Surface* src, SDL_Surface* dst, Uint32 nulcol)
	{
	/* Interpolation */
	Uint32 ipol;
	for(int i=1;i< (src->w-1) ;i++)
		for(int j=1;j< (src->h-1);j++)
			{
			if((ipol=getpixel(src,i,j))==nulcol)
				{
				Uint32 ir=0,ig=0,ib=0;
				int tot=0;
				if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
					ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
					tot++;
					}
				if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
					ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
					tot++;
					}
				if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
					ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
					tot++;
					}
				if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
					ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
					tot++;
					}
				if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
					ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
					tot++;
					}
				if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
					ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
					tot++;
					}
				if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
					ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
					tot++;
					}
				if((ipol=getpixel(src,i-1,j-1))!=NULLCOL){
					ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
					tot++;
					}
				
					
				if((ipol=getpixel(src,i,j-2))!=NULLCOL){
					ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
					tot++;
					}
				if((ipol=getpixel(src,i,j+1))!=NULLCOL){
					ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
					tot++;
					}
				if((ipol=getpixel(src,i-2,j))!=NULLCOL){
					ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
					tot++;
					}
				if((ipol=getpixel(src,i+2,j))!=NULLCOL){
					ir+=(ipol>>16)%256; ig+=(ipol>>8)%256; ib+=(ipol)%256;
					tot++;
					}
				
				if(tot>3) 
					{
					ir/=tot;
					ig/=tot;
					ib/=tot;
					//printf("interpol pixel %d,%d, with %d,%d,%d (%d)\n",i,j,ir,ig,ib,tot);
					setpixel(dst,i,j,(Uint8)ir,(Uint8)ig,(Uint8)ib);
					//setpixel(dst,i,j,255,0,0);
					}
				// else pixel à interpolé entouré de rien ...
				}
			else	{
				setpixel(dst,i,j,(Uint8)(ipol>>16),(Uint8)(ipol>>8),(Uint8)(ipol));
				//setpixel(dst,i,j,0,255,0);
				}
			
			}	
	}

void DrawLine(SDL_Surface* screen, int x1, int y1, int x2, int y2, char r, char g, char b)
        {
        double dx,dy,x,y;
        int step,i;
        if(abs(x2-x1)>abs(y2-y1)) step=abs(x2-x1);
        else step=abs(y2-y1);
        dx=(x2-x1);
        dy=(y2-y1);
        dx/=step;
        dy/=step;
        x=x1;
        y=y1;
        for(i=0;i<step;i++)
                {
                x=x+dx;
                y=y+dy;
                setpixel(screen,(int)x,(int)y,r,g,b);
                }
        }

void rotatesurface(SDL_Surface *src, SDL_Surface *dst, int anginc)
	{
	Uint32 pix,x,y;
	double angle,ba,ca,norm;
	Uint8 r,g,b;
	SDL_Surface *tmp;
	SDL_Rect rec;
	rec.h=src->h;
	rec.w=src->w;
	rec.x=0;
	rec.y=0;
	
tmp=SDL_CreateRGBSurface(SDL_HWSURFACE, src->w, src->h, 32, 0,0,0,0);
SDL_FillRect(tmp,&rec, SDL_MapRGB(tmp->format,NULLCOLR,NULLCOLG,NULLCOLB/**/));
SDL_FillRect(dst,&rec, SDL_MapRGB(tmp->format,NULLCOLR,NULLCOLG,NULLCOLB/**/));

	for(int i=0;i<src->w;i++)
		for(int j=0;j<src->h;j++)
			{
			pix=getpixel(src,i,j);
			r=pix>>16;		// couleur R
			g=pix>>8;		// couleur G
			b=pix;			// couleur B
			ba=(src->w/2)-i;	// base
			ca=(src->h/2)-j;	// cote adjascent
			norm=sqrt(ba*ba+ca*ca);	// norme
			angle=atan(ca/ba);	// angle
			if(i>(src->w)/2) angle+=(PI); 
			angle+=(anginc*PI/180); // angle tourné
			x=(int)round((src->w/2)-(norm*cos(angle)));
			y=(int)round((src->h/2)-(norm*sin(angle)));
			setpixel(tmp, x,y, r,g,b);
			}
	pix=getpixel(src,(src->w/2),(src->h/2));
	setpixel(tmp, (src->w/2),(src->h/2), pix>>16,pix>>8,pix);
	
//SDL_BlitSurface(tmp , NULL, dst, NULL);
	interpole(tmp,dst, NULLCOL);
	}
