#include <SDL.h>
#include <SDL_image.h>
#include <time.h>
#include <iostream>
#include "sdlcommon.h"
#include "fenetre.h"
#include "shmdata.h"

using namespace std;

Fenetre::Fenetre ()
	{
	obstacle=0;
	SHOWcamera=1;
	SHOWpilot=1;
	fps=0;
	font=SFont_InitFont(IMG_Load(FONT_PATH));
	if( SDL_Init(SDL_INIT_VIDEO) < 0 ) 
		{
		fprintf(stderr, "Could not initialize SDL: %s\n", SDL_GetError());
		return ;
		}
	atexit(SDL_Quit);
	screen = SDL_SetVideoMode(800,600, 32, SDL_HWSURFACE);
					/* SDL_HWSURFACE / SDL_SWSURFACE */
		/*|SDL_ANYFORMAT*/
	if( screen==NULL ) 
		{
		fprintf(stderr, "Could not create surface: %s\n", SDL_GetError());
		return ;
		}
	return ;
	Voiture.loadImage("Cars/voiture4.bmp");
	circuit=1;
	}

Fenetre::Fenetre (int largeur = 800, int hauteur = 600, int nb_couleurs = 16, char *titre = "Fenetre SDL", char *background=NULL)
	{
	obstacle=0;
	SHOWcamera=1;
	SHOWpilot=1;
	fps=0;
	font=SFont_InitFont(IMG_Load(FONT_PATH));
	if (SDL_Init (SDL_INIT_VIDEO) < 0)
		{
		cerr << "Erreur dans l'initialisation de la librairie" << endl;
		}
	
	screen = SDL_SetVideoMode (largeur, hauteur, nb_couleurs, SDL_HWSURFACE | SDL_DOUBLEBUF);
		 //SDL_CreateRGBSurface(SDL_HWSURFACE, largeur,hauteur,32,0,0,0,0);
	if (screen == NULL)
		{
		cerr << "Erreur dans l'initialisation des modes vidéos:" <<
		SDL_GetError ();
		SDL_Quit ();
		}
	SDL_WM_SetCaption (titre, NULL);
	fond = SDL_LoadBMP (background);
	SDL_BlitSurface (fond, NULL, screen, NULL);
	SDL_Flip (screen);
	HardBG=SDL_CreateRGBSurface(SDL_HWSURFACE, largeur, hauteur, 32, 0,0,0,0);
	SDL_BlitSurface( fond, NULL, HardBG, NULL);
	Voiture.loadImage("Cars/voiture4.bmp");
	circuit=1;
	}

void Fenetre::loadBG(char *background)
	{
	fond = SDL_LoadBMP (background);
	SDL_BlitSurface (fond, NULL, /*screen*/HardBG, NULL);
	SDL_BlitSurface( fond, NULL, HardBG, NULL);
	SDL_Flip (screen);
	}

Fenetre::~Fenetre ()
	{
	/*
	if(fond) SDL_FreeSurface (fond);
	if(screen) SDL_FreeSurface (screen);
	*/
	SDL_Quit ();
	
	}
void Fenetre::showView(int x,int y)
	{
	bool* v=Voiture.getView();
	SDL_Rect r;
	r.x=x; r.y=y-1; r.h=1; r.w=4*CAMVECT;
	SDL_FillRect(screen,&r, SDL_MapRGB(screen->format, 255,0,0));
	r.x=x; r.y=y+4; r.h=1; r.w=4*CAMVECT;
	SDL_FillRect(screen,&r, SDL_MapRGB(screen->format, 255,0,0));
	for(int i=0;i<CAMVECT;i++)
		{
		if(v[i]) 
			{	
			r.x=x+(4*i);
			r.y=y;
			r.w=4;
			r.h=4;
			SDL_FillRect(screen,&r, SDL_MapRGB(screen->format, 0,0,0));
			}
		}
	}
	
void Fenetre::showObstacle()
	{
	SDL_Rect r;
	r.x=400;
	r.y=20;
	r.w=40;
	r.h=screen->h-40;
	SDL_FillRect(screen,&r, SDL_MapRGB(screen->format, 255,0,0));
	}
	
void Fenetre::showPilot(int x,int y)
	{
	if(Voiture.getVect()[0])
		for(int i=0;i<16;i++)
			{
			for(int j=y-i;j<y+i;j++)
				putPixel(x+i,j,0,0,0);
			}
	if(Voiture.getVect()[1])
		for(int i=0;i<16;i++)
			{
			for(int j=y-i;j<y+i;j++)
				putPixel(x+64-i,j,0,0,0);
			}
	if(Voiture.getVect()[2]==1)
		for(int i=0;i<16;i++)
			{
			for(int j=x-i+32;j<x+i+32;j++)
				putPixel(j,y+i-32,0,0,0);
			}
	if(Voiture.getVect()[2]==0)
		for(int i=0;i<16;i++)
			{
			for(int j=x-i+32;j<x+i+32;j++)
				putPixel(j,y-i+32,0,0,0);
			}

	}

void Fenetre::drawText()
	{
	char *bf=(char*)malloc(256);
	sprintf(bf,": %d",Voiture.APState());
	SFont_Write(screen,font,10,10,"AutoPilot (a)");
	SFont_Write(screen,font,120,10,bf);
	sprintf(bf,": %d",Voiture.neurState());
	SFont_Write(screen,font,10,25,"NeuronPilot (n)");
	SFont_Write(screen,font,120,25,bf);
	sprintf(bf,": %d",Voiture.getSpeed());
	SFont_Write(screen,font,10,40,"Speed");
	SFont_Write(screen,font,120,40,bf);
	sprintf(bf,": %d",Voiture.getAngle());
	SFont_Write(screen,font,10,55,"Angle");
	SFont_Write(screen,font,120,55,bf);
	sprintf(bf,": %d",fps);
	SFont_Write(screen,font,10,70,"Framerate");
	SFont_Write(screen,font,120,70,bf);
	sprintf(bf,": %d",Voiture.incTraineeSize(0));
	SFont_Write(screen,font,10,85,"trainee(F8,F9)");
	SFont_Write(screen,font,120,85,bf);

	sprintf(bf,": %d",Voiture.showBar(0));
	SFont_Write(screen,font,200,10,"Showbar (b)");
	SFont_Write(screen,font,300,10,bf);
	sprintf(bf,": %d",SHOWcamera);
	SFont_Write(screen,font,200,25,"Showcam (c)");
	SFont_Write(screen,font,300,25,bf);
	sprintf(bf,": %d",SHOWpilot);
	SFont_Write(screen,font,200,40,"Showpilot (p)");
	SFont_Write(screen,font,300,40,bf);
	sprintf(bf,": %d",obstacle);
	SFont_Write(screen,font,200,55,"Obstacle (o)");
	SFont_Write(screen,font,300,55,bf);
	
	sprintf(bf,": %d",Voiture.incAngleStep(0));
	SFont_Write(screen,font,200,70,"AStep (pgU-D)");
	SFont_Write(screen,font,300,70,bf);
	
	sprintf(bf,": %d",Voiture.showNetworkState());
	SFont_Write(screen,font,200,85,"NeuronIface(i)");
	SFont_Write(screen,font,300,85,bf);
	
	DrawLine(screen,0,99,319,99,0,0,128);
	}
	
void Fenetre::redraw()
	{
	#ifdef __DEBUG_TIME
		Uint32 deltatime; 
	#endif
	if(sec!=time(NULL)) { sec=time(NULL); fps=frame; frame=0; }
	frame++;
	#ifdef __DEBUG_TIME
		deltatime=SDL_GetTicks();
	#endif
	/* SDL_BlitSurface( fond, NULL, screen, NULL);	 Software Mode */
	SDL_BlitSurface( HardBG, NULL, screen , NULL); /* Hardware Mode */
	#ifdef __DEBUG_TIME
		printf("Background Blit : %d ms, ",SDL_GetTicks()-deltatime);
		deltatime=SDL_GetTicks();
	#endif
	drawText();
	if(SHOWpilot) showPilot(440,50);
	if(SHOWcamera) showView(350,10);
	if(obstacle) showObstacle();
	Voiture.updateCar(screen);
	#ifdef __DEBUG_TIME
		printf("Car Update : %d ms, ",SDL_GetTicks()-deltatime);
		deltatime=SDL_GetTicks();
	#endif
	SDL_Flip (screen);
	#ifdef __DEBUG_TIME
		printf("Screen Refresh : %d ms\n",SDL_GetTicks()-deltatime);
	#endif

	}
	
void Fenetre::putPixel(int x, int y, char r, char g, char b)
	{
	setpixel(screen,x,y,r,g,b);
	}

void Fenetre::handle()
	{
	int exitkey = 0;
	bool shownet= 0;
	int waitdel = 20;
	SDL_Event event;
	while (!exitkey)
		{
		SDL_Delay (waitdel); 
		redraw();
		
		while (SDL_PollEvent (&event))
			{
			switch (event.type)
				{
				case SDL_QUIT:
					Voiture.harakiri();
					exitkey = 1;
					break;
				case SDL_KEYDOWN:
					switch (event.key.keysym.sym)
						{
						case SDLK_ESCAPE:
							Voiture.harakiri();
							exitkey = 1;
							break;
						case SDLK_LEFT:
							Voiture.decAngle();
							break;
						case SDLK_RIGHT:
							Voiture.incAngle();
							break;
						case SDLK_DOWN:
							Voiture.decSpeed();
							break;
						case SDLK_UP:
							Voiture.incSpeed();
							break;
						case SDLK_a:
							Voiture.APToggle();
							break;	
						case SDLK_b:
							Voiture.showBar(1);
							break;
						case SDLK_c:
							SHOWcamera=(SHOWcamera+1)%2;
							break;
						case SDLK_i:
							shownet=(shownet+1)%2;
							Voiture.showNetwork(shownet);
							break;
						case SDLK_n:
							Voiture.neurToggle();
							break;
						case SDLK_o:
							obstacle=(obstacle+1)%2;
							break;
						case SDLK_p:
							SHOWpilot=(SHOWpilot+1)%2;
							break;	
						case SDLK_r:
							Voiture.reset();
							break;
						case SDLK_t:
							Voiture.turn180();
							break;
						case SDLK_w:
							Voiture.saveState();
							//SData->action=SAVE_STATE;
							break;
						case SDLK_x:
							Voiture.loadState();
							//SData->action=RELOAD_STATE;
							break;
						case SDLK_F1:
							printf("Chargement Circuit 1\n");
							circuit=1;
							loadBG("Back/bg1.bmp");
							break;
						case SDLK_F2:
							printf("Chargement Circuit 2\n");
							circuit=2;
							loadBG("Back/bg2.bmp");
							break;
						case SDLK_F3:
							printf("Chargement Circuit 3\n");
							circuit=3;
							loadBG("Back/bg3.bmp");
							break;
						case SDLK_F4:
							printf("Chargement Circuit 4\n");
							circuit=4;
							loadBG("Back/bg4.bmp");
							break;
						case SDLK_F5:
							printf("Chargement Circuit 5\n");
							circuit=5;
							loadBG("Back/bg5.bmp");
							break;
						case SDLK_F6:
							printf("Chargement Circuit 6\n");
							circuit=6;
							loadBG("Back/bg6.bmp");
							break;
						case SDLK_F7:
							Voiture.incTraineeSize(-256);
							break;
						case SDLK_F8:
							Voiture.incTraineeSize(256);
							break;
						case SDLK_F9:
							printf("Chargement Voiture 1\n");
							Voiture.loadImage("Cars/voiture1.bmp");
							break;
						case SDLK_F10:
							printf("Chargement Voiture 2\n");
							Voiture.loadImage("Cars/voiture2.bmp");
							break;
						case SDLK_F11:
							printf("Chargement Voiture 3\n");
							Voiture.loadImage("Cars/voiture3.bmp");
							break;
						case SDLK_F12:
							printf("Chargement Voiture 4\n");
							Voiture.loadImage("Cars/voiture4.bmp");
							break;
						case SDLK_PAGEUP:
							Voiture.incAngleStep(1);
							break;
						case SDLK_PAGEDOWN:
							Voiture.incAngleStep(-1);
							break;
							
						case SDLK_HOME:
							waitdel+=5;
							break;
						case SDLK_END:
							waitdel-=5;
							if(waitdel<0) waitdel=0;
							break;
							
						default :
							break;
						}
					break;
				}
			break;
			}
		}
	}
