#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <SDL/SDL_mixer.h>
#include <SDL/SDL_image.h>
#include <string>
#include <deque>
#include <algorithm>

#ifdef _WIN32
#include <windows.h>
#endif
#ifdef WIN32
#pragma comment(lib, "SDL.lib")
#pragma comment(lib, "SDLmain.lib")
#pragma comment(lib, "SDL_ttf.lib")
#pragma comment(lib, "SDL_mixer.lib")
#pragma comment(lib, "SDL_image.lib")
#endif

enum {
	STATE_SELECT,		// Select the question set
	STATE_QUESTION,		// Show question
	STATE_ANSWER,		// Show answer
};

enum {
	D_LEFT,
	D_UP,
	D_RIGHT,
	D_DOWN
};

int state=STATE_SELECT;
int termfirst=1;
unsigned int batchsize=0;

void draw_text(int size,int x,int y,const char *msg);
/*
 PLEASE NOTE: the program will require SDL.dll which is located in
              dev-c++'s dll directory. You have to copy it to you
			  program's home directory or the path.
 */

/* The screen surface */
SDL_Surface *screen = NULL, *bgskin=NULL;
TTF_Font *headline, *subhead, *body, *prompt;

struct Card {
	std::string name;
	std::string def;
};

struct Topic {
	std::string name;
	std::deque<struct Card> active;
	std::deque<struct Card> complete;
	std::deque<struct Card> deck;		// When doing batches, the rest are here.
};

//static int fibonacci[]={ 3,5,8,13,21 };

std::deque<struct Topic> topics;
int count;

std::deque<struct Topic>::iterator selected;
struct Topic *currentTopic;

TTF_Font *size_to_font(int size)
{
	TTF_Font *font=headline;
	
	switch(size) {
	case 18:
		font=subhead;
		break;
	case 12:
		font=body;
		break;
	case 8:
		font=prompt;
		break;
	}
	return font;
}

void draw_text_line(int size,int x,int y,const char *msg)
{
	SDL_Surface *surf;
	TTF_Font *font=headline;
	SDL_Rect rect;

	switch(size) {
	case 18:
		font=subhead;
		break;
	case 12:
		font=body;
		break;
	case 8:
		font=prompt;
		break;
	}
	SDL_Color fg={0xff,0xff,0xff,0xff};
	SDL_Color bg={0x00,0x7f,0x7f,0xff};
	if(bgskin && (size==8 || size>18)) {
		bg.r=0; bg.g=0; bg.b=0;
	} else if(bgskin) {
		bg.r=255; bg.g=255;	bg.b=255;
	}

	if(size==18) { fg.r=0xd0; fg.g=0xd0; fg.b=0xd0; }
	if(size==8) fg.b=0x80;

	if(bgskin && size==12) { fg.r=0; fg.b=0; fg.g=0; }
	if(bgskin && size==18) { fg.r=0x60; fg.g=0x60; fg.b=0x60; }

	surf=TTF_RenderText_Shaded(font,msg,fg,bg);
	rect.x=x;
	rect.y=y;
	rect.w=0;
	rect.h=0;
	SDL_BlitSurface(surf,NULL,screen,&rect);
	SDL_FreeSurface(surf);
}

// Adds in word wrapping
void draw_text(int size,int x,int y,const char *msg,int maxWidth)
{
	TTF_Font *font=size_to_font(size);
	int w,h;
	int offset=0;
	char *line=(char *)malloc(strlen(msg)+1);
	char *buf=(char *)malloc(strlen(msg)+1);

	offset=0;
	int i=0;
	do { 
		int len=strlen(msg);
		// Add words until too long.
		while(i<len && msg[i]!=' ') {
			buf[i]=msg[i];
			i++;
		}
		while(msg[i]==' ') {
			buf[i]=msg[i];
			i++;
		}
		buf[i]=0;
		w=0;
		h=0;
		TTF_SizeText(font,buf,&w,&h);
		if(w>=maxWidth || i==len) {
			strcpy(line,msg);
			if(w>=maxWidth) line[offset]=0;
			draw_text_line(size,x,y,line);
			y+=h;
			msg+=offset;
			if(i==len && w<maxWidth) msg+=i-offset;
			i=0;
			offset=0;
		} else {
			offset=i;
		}
	} while(strlen(msg)>0);

	free(line);
	free(buf);
}

void draw_text(int size,int x,int y,const char *msg)
{
	draw_text(size,x,y,msg,460-x);
}

SDL_Surface *termSurface=0;
std::string termSurfacePath;
Mix_Chunk *termSound=0;
std::string termSoundPath;

void draw_term()
{
	SDL_Rect rect;

	rect.x=10;
	rect.y=10;
	rect.w=220;
	rect.h=220;
	if(bgskin) SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
	draw_text(18,rect.x+5,rect.y,"Term:");
	std::string name=currentTopic->active.front().name;
	char ch=name[0];
	if(ch=='$') {	// image requested.
		if(termSurfacePath.compare(name.c_str()+1)!=0) { // Need to load it.
			termSurfacePath=name.c_str()+1;
			if(termSurface) SDL_FreeSurface(termSurface);
			termSurface=IMG_Load(termSurfacePath.c_str());
			if(!termSurface) {
				std::string path=(std::string)"Image Cards/"+termSurfacePath;
				termSurface=IMG_Load(path.c_str());
			}
		}
		if(termSurface) {
			SDL_BlitSurface(termSurface,0,screen,&rect);
		} else {
			std::string msg=(std::string)"Image "+termSurfacePath+" not found.";
			draw_text(12,rect.x+10,rect.y+30,msg.c_str(),200);
		}
	} else if(ch=='@') {
		if(termSoundPath.compare(name.c_str()+1)!=0) {
			termSoundPath=name.c_str()+1;
			if(termSound) Mix_FreeChunk(termSound);
			termSound=Mix_LoadWAV(termSoundPath.c_str());
			if(!termSound) {
				std::string path=(std::string)"Audio Cards/"+termSoundPath;
				termSound=Mix_LoadWAV(path.c_str());
			}
		}
		if(termSound) {
			Mix_PlayChannel(1,termSound,0);
			std::string msg=(std::string)"Audio Clue.";
			draw_text(12,rect.x+10,rect.y+30,msg.c_str(),200);
		} else {
			std::string msg=(std::string)"Sound '"+termSoundPath+"' not found.";
			std::string path=(std::string)"Audio Cards/"+termSoundPath;
			termSound=Mix_LoadWAV(path.c_str());
			
			FILE *fh=fopen(path.c_str(),"rb");
			if(fh) {
				msg+="  Path verified okay though.";
				fclose(fh);
			}
			draw_text(12,rect.x+10,rect.y+30,msg.c_str(),200);
		}
	} else {
		draw_text(12,rect.x+10,rect.y+30,currentTopic->active.front().name.c_str(),200);
	}

}

SDL_Surface *defSurface=0;
std::string defSurfacePath;
Mix_Chunk *defSound=0;
std::string defSoundPath;

void draw_definition()
{
	SDL_Rect rect;

	rect.x=250;
	rect.y=10;
	rect.w=220;
	rect.h=220;
	if(bgskin) SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
	draw_text(18,rect.x+5,rect.y,"Definition:");
	std::string def=currentTopic->active.front().def;
	char ch=def[0];
	if(ch=='$') {	// image requested.
		if(defSurfacePath.compare(def.c_str()+1)!=0) { // Need to load it.
			defSurfacePath=def.c_str()+1;
			if(defSurface) SDL_FreeSurface(defSurface);
			defSurface=IMG_Load(defSurfacePath.c_str());
			if(!defSurface) {
				std::string path=(std::string)"Image Cards/"+defSurfacePath;
				defSurface=IMG_Load(path.c_str());
			}
		}
		if(defSurface) {
			SDL_BlitSurface(defSurface,0,screen,&rect);
		} else {
			std::string msg=(std::string)"Image "+defSurfacePath+" not found.";
			draw_text(12,rect.x+10,rect.y+30,msg.c_str(),200);
		}
	} else if(ch=='@') {
		if(defSoundPath.compare(def.c_str()+1)!=0) {
			defSoundPath=def.c_str()+1;
			if(defSound) Mix_FreeChunk(defSound);
			defSound=Mix_LoadWAV(defSoundPath.c_str());
			if(!defSound) {
				std::string path=(std::string)"Audio Cards/"+defSoundPath;
				defSound=Mix_LoadWAV(path.c_str());
			}
		}
		if(defSound) {
			Mix_PlayChannel(1,defSound,0);
			std::string msg=(std::string)"Audio Clue.";
			draw_text(12,rect.x+10,rect.y+30,msg.c_str(),200);
		} else {
			std::string msg=(std::string)"Sound "+defSoundPath+" not found.";
			draw_text(12,rect.x+10,rect.y+30,msg.c_str(),200);
		}
	} else {
		draw_text(12,rect.x+10,rect.y+30,currentTopic->active.front().def.c_str(),200);
	}


}

const char *batchlabel[]={"Full set,","5 at a time.","10 at a time.","20 at a time."};
void draw_mode()
{
	SDL_Rect rect;
	int bid;
	char buf[256];

	rect.x=10;
	rect.y=238;
	rect.w=460;
	rect.h=12;
	if(bgskin) SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));

	strcpy(buf,termfirst?"Term mode. / ":"Definition mode. / ");

	switch(batchsize) {
	default: bid=0; break;
	case 5: bid=1; break;
	case 10: bid=2; break;
	case 20: bid=3; break;
	}
	strcat(buf,batchlabel[bid]);

	draw_text(8,20,240,buf);
}

/* This function draws to the screen; replace this with your own code! */
static void draw()
{
	char msg[256];
	SDL_Rect rect;

	SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0x00, 0x7f, 0x7f));
	if(bgskin) SDL_BlitSurface(bgskin,0,screen,0);

	Mix_HaltChannel(1);
	draw_mode();
	//printf("Drawing::state=%d\n",state);
	switch(state) {
	case STATE_SELECT:
		rect.x=10;
		rect.y=10;
		rect.w=460;
		rect.h=40;
		if(bgskin) SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));
		draw_text(24,20,10,"Choose a Flash Card Set");
		rect.x=10;
		rect.y=120;
		rect.w=460;
		rect.h=50;
		if(bgskin) SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
		draw_text(12,20,130,selected->name.c_str());
		sprintf(msg,"with %d questions",selected->active.size()+selected->complete.size());
		draw_text(12,20,145,msg);
		rect.x=10;
		rect.y=248;
		rect.w=460;
		rect.h=24;
		if(bgskin) SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));
		draw_text(8,20,250,"Press X to start.  Press up and down to change.");
		draw_text(8,20,260,"L to switch order.  R to change batch size.  Press SELECT to quit.");
		break;
	case STATE_QUESTION:
		if(currentTopic && currentTopic->active.size()>0) {
			if(termfirst)
				draw_term();
			else
				draw_definition();

			rect.x=10;
			rect.y=248;
			rect.w=460;
			rect.h=24;
			if(bgskin) SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));
			draw_text(8,20,250,"Press X or O to see the answer.  Triangle for menu.");
			sprintf(msg,"%d questions remain out of %d in set (%d waiting)",currentTopic->active.size(),currentTopic->active.size()+currentTopic->complete.size()+currentTopic->deck.size(),currentTopic->deck.size());
			draw_text(8,20,260,msg);
		} else {
			rect.x=70;
			rect.y=94;
			rect.w=340;
			rect.h=40;
			if(bgskin) SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
			draw_text(18,75,100,"Flash card set complete.");
			rect.x=10;
			rect.y=248;
			rect.w=460;
			rect.h=24;
			if(bgskin) SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));
			draw_text(8,20,250,"Press O to select a new set");
			draw_text(8,20,260,"Press X to select the same set");
			state=STATE_SELECT;
		}
		break;
	case STATE_ANSWER:
		if(currentTopic && currentTopic->active.size()>0) {
			draw_term();

			draw_definition();

			rect.x=10;
			rect.y=248;
			rect.w=460;
			rect.h=24;
			if(bgskin) SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));
			draw_text(8,20,250,"X if you got it. O to drill it more. Triangle for menu.");
			sprintf(msg,"%d questions remain out of %d in set (%d waiting)",currentTopic->active.size(),currentTopic->active.size()+currentTopic->complete.size()+currentTopic->deck.size(),currentTopic->deck.size());
			draw_text(8,20,260,msg);
		} else {
			draw_text(18,75,0,"Flash card set complete.");
			draw_text(8,20,250,"Press O to select a new set");
			state=STATE_SELECT;
		}
		break;
	}

    /* Make sure everything is displayed on screen */
    SDL_Flip (screen);
    /* Don't run too fast */
    SDL_Delay (17);
}

void next_question()
{
	int i;
	int pos;
	// To make it less likely to cheat by memorizing the order of the cards:
	int max=currentTopic->active.size();
	if(max>1) max--;
	if(max<=1) return;	// Always predictable.
	pos=rand()%max;	// Our winner
	if(pos==0) return;
	std::deque<struct Card>::iterator p;
	for(p=currentTopic->active.begin(),i=0;i<pos;i++,p++) 
		;
	struct Card card=*p;
	currentTopic->active.erase(p);
	currentTopic->active.push_front(card);

}

void do_cross()
{
	//printf("Cross!\n");
	switch(state) {
	case STATE_SELECT:
		state=STATE_QUESTION;
		// Now make sure that the completed move back to active list.
		currentTopic=&*selected;
		while(!currentTopic->complete.empty()) {
			if(batchsize==0 || currentTopic->active.size()<batchsize)
				currentTopic->active.push_back(currentTopic->complete.front());
			else 
				currentTopic->deck.push_back(currentTopic->complete.front());
			currentTopic->complete.pop_front();
		}
		// Select random one and pull to front
		next_question();
		break;
	case STATE_QUESTION:
		state=STATE_ANSWER;
		break;
	case STATE_ANSWER:
		// Move out of active list.
		currentTopic->complete.push_back(currentTopic->active.front());
		currentTopic->active.pop_front();
		while(!currentTopic->deck.empty() && (batchsize==0 || currentTopic->active.size()<batchsize)) {
			currentTopic->active.push_back(currentTopic->deck.front());
			currentTopic->deck.pop_front();
		}
		state=STATE_QUESTION;
		next_question();
		break;
	}
}

void do_circle()
{
	//printf("Circle!\n");
	switch(state) {
	case STATE_QUESTION:
		state=STATE_ANSWER;
		break;
	case STATE_ANSWER:
		// Move to back of active list.
		currentTopic->active.push_back(currentTopic->active.front());
		currentTopic->active.pop_front();
		state=STATE_QUESTION;
		next_question();
		break;
	}
}

void do_triangle()		// Exit to menu
{
	state=STATE_SELECT;
}

void do_ltrigger()
{
	termfirst= !termfirst;
}

void do_rtrigger()
{
	switch(batchsize) {
	case 0: batchsize=5; break;
	case 5: batchsize=10; break;
	case 10: batchsize=20; break;
	default: batchsize=0; break;
	}
	if(batchsize>0 && currentTopic && currentTopic->active.size()>batchsize) {
		std::random_shuffle(currentTopic->active.begin(),currentTopic->active.end());
		while(currentTopic->active.size()>batchsize) {
			currentTopic->deck.push_back(currentTopic->active.front());
			currentTopic->active.pop_front();
		}
	}
	if((batchsize==0 || currentTopic->active.size()<batchsize) && currentTopic->deck.size()>0) {
		std::random_shuffle(currentTopic->deck.begin(),currentTopic->deck.end());
		while((batchsize==0 || currentTopic->active.size()<batchsize) && currentTopic->deck.size()>0) {
			currentTopic->active.push_back(currentTopic->deck.front());
			currentTopic->deck.pop_front();
		}
	}
}

void move_character(int dir)
{
	if(state==STATE_SELECT) {
		if(dir==D_DOWN || dir==D_RIGHT) {
			selected++;
			if(selected==topics.end()) {
				selected=topics.begin();
			}
			//Topic *t=&*selected;
			//printf("Next topic: %s\n",t->name.c_str());
		} else if(dir==D_UP || dir==D_LEFT) {
			if(selected==topics.begin()) {
				selected=topics.end();
			}
			selected--;
			//Topic *t=&*selected;
			//printf("Prev topic: %s\n",t->name.c_str());
		}
	}
}

int load_cards()
{
	char buf[1024];
	buf[1023]=0;
	Topic *topic=NULL;

	topics.clear();	// Just in case.
	count=0;

	DIR *dir=opendir(".");
	struct dirent *ent=0;
	while((ent=readdir(dir))!=0) {
		if((strstr(ent->d_name,"card")==0 && strstr(ent->d_name,"CARD")==0) || (strstr(ent->d_name,".txt")==0 && strstr(ent->d_name,".TXT")==0)) continue;
		
		FILE *file=fopen(ent->d_name,"r");
 		if(!file) continue;
		while(fgets(buf,1023,file)) {
			char *name=0;
			char *value=0;
			if(strstr(buf,"=")) {
				struct Card card;
				char *s;
				name=buf;
				value=strstr(buf,"=");
				if(value[-1]==' ') value[-1]=0;
				value[0]=0;
				value++;
				while(value[0]==' ') value++;
				s=strstr(value,"\n");
				if(s) s[0]=0;
				s=strstr(value,"\r");
				if(s) s[0]=0;
				card.name=name;
				card.def=value;
				if(!topic || strcmp(name,"#SET")==0) {
					Topic t;
					topics.push_back(t);
					topic=&topics.back();
					topic->name=value;
				}
				if(strcmp(name,"#SET")!=0) {
					topic->active.push_back(card);
					count++;
				}
			}
		}
		fclose(file);
	}
	
	return count;
}


extern "C" {
int main (int argc, char *argv[]);
}

int main (int argc, char *argv[])
{
    int done;
	int start=0;
	int dir=-1;
#ifdef _WIN32
	char msg[256];
#endif

    /* Initialize SDL */
    if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_JOYSTICK) < 0)
    {
#ifdef _WIN32
        sprintf (msg, "Couldn't initialize SDL: %s\n", SDL_GetError ());
        MessageBox (0, msg, "Error", MB_ICONHAND); 
        free (msg);
#endif
        exit (1);
    }
    atexit (SDL_Quit);

	TTF_Init();
	if(Mix_OpenAudio(44100,AUDIO_S16SYS, 2, 2048)<0) {
		printf("Coulding init audio: %s\n",SDL_GetError());
	}

    /* Set 640x480 16-bits video mode */
    screen = SDL_SetVideoMode (480, 272, 32, SDL_SWSURFACE);
    if (screen == NULL)
    {
#ifdef _WIN32
        sprintf (msg, "Couldn't set 480x272x16 video mode: %s\n",
          SDL_GetError ());
        MessageBox (0, msg, "Error", MB_ICONHAND); 
        free (msg);
#endif
        exit (2);
    }
    SDL_WM_SetCaption ("PSPFlashcard SDL by HardHat", NULL);

	SDL_Joystick *joy=0;
	if(SDL_NumJoysticks()>0)
	   joy=SDL_JoystickOpen(0);

    

    done = 0;
	SDL_Rect rect;
//	SDL_Delay(3000);	
	SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 255, 255));
	headline=TTF_OpenFont("Arial Black.TTF",24);
	subhead=TTF_OpenFont("Arial Black.TTF",18);
	SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 255));
	body=TTF_OpenFont("Bookman Old Style.TTF",12);
	SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 0, 255));
	prompt=TTF_OpenFont("BoomBox.TTF",9);
    SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0x7f, 0x7f));
	bgskin=SDL_LoadBMP("bg.bmp");

	if(bgskin) SDL_BlitSurface(bgskin,0,screen,0);
	/* Check for events */
	if(bgskin) {
		rect.x=10;
		rect.y=5;
		rect.w=460;
		rect.h=40;
		SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));
		draw_text(24,40,10,"PSPFlashcard by HardHat");
	} else {
		draw_text(24,150,10,"PSPFlashcard");
		draw_text(18,150,45,"by HardHat");
	}

	rect.x=10;
	rect.y=120;
	rect.w=460;
	rect.h=50;
	if(bgskin) SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
	draw_text(12,50,125,"Loading flash card sets '*card*.txt'...");
	load_cards();
	char buf[256];
	sprintf(buf,"Loaded %d cards in %d topics.",count,topics.size());
	draw_text(12,50,140,buf);
	rect.x=10;
	rect.y=255;
	rect.w=460;
	rect.h=20;
	if(bgskin) SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));
	draw_text(8,20,260,"Press X to start.");
    SDL_Flip (screen);

	selected=topics.begin();
	srand(SDL_GetTicks());

	//printf("Waiting...\n");
	SDL_Event event;
    while (start==0 && SDL_WaitEvent (&event))
    {
        switch (event.type)
        {
        case SDL_KEYDOWN:
			start=1;
            break;
        case SDL_JOYBUTTONDOWN:
			start=1;
			break;
        case SDL_QUIT:
            done = 1;
            break;
        default:
            break;
        }
        if(start || done) break;
    }
	//printf("Starting game...\n");

	while (!done)
    {
        SDL_Event event;

        /* Check for events */
        while (!done && SDL_WaitEvent (&event) )
        {
		//printf("Draw\n");
				/* Draw to screen */
				draw ();
            switch (event.type)
            {
            case SDL_KEYDOWN:
//printf("Key Down\n");
                if(event.key.keysym.sym == SDLK_ESCAPE) done=1;
                if(event.key.keysym.sym == SDLK_SPACE) do_cross();
                if(event.key.keysym.sym == SDLK_LALT) do_circle();
                if(event.key.keysym.sym == SDLK_LCTRL) do_triangle();
				if(event.key.keysym.sym == SDLK_LEFT) dir=0;
				if(event.key.keysym.sym == SDLK_UP) dir=1;
				if(event.key.keysym.sym == SDLK_RIGHT) dir=2;
				if(event.key.keysym.sym == SDLK_DOWN) dir=3;
				if(event.key.keysym.sym == ',') do_ltrigger();
				if(event.key.keysym.sym == '.') do_rtrigger();
		        if(dir>=0) move_character(dir);
				dir=-1;
                break;
            case SDL_KEYUP:
				if(event.key.keysym.sym == SDLK_LEFT && dir==0) dir=-1;
				if(event.key.keysym.sym == SDLK_UP && dir==1) dir=-1;
				if(event.key.keysym.sym == SDLK_RIGHT && dir==2) dir=-1;
				if(event.key.keysym.sym == SDLK_DOWN && dir==3) dir=-1;
				break;
            case SDL_JOYBUTTONDOWN:
                if(event.jbutton.button == 10 /* SELECT */) done=1;
                if(event.jbutton.button == 0 /* TRIANGLE */) do_triangle();
                if(event.jbutton.button == 2 /* CROSS */) do_cross();
                if(event.jbutton.button == 1 /* CIRCLE */) do_circle();
                if(event.jbutton.button == 4 /* LTRIGGER */) do_ltrigger();
                if(event.jbutton.button == 5 /* RTRIGGER */) do_rtrigger();
				if(event.jbutton.button == 7 /* LEFT */) dir=0;
				if(event.jbutton.button == 8 /* UP */) dir=1;
				if(event.jbutton.button == 9 /* RIGHT */) dir=2;
				if(event.jbutton.button == 6 /* DOWN */) dir=3;
		        if(dir>=0) move_character(dir);
				dir=-1;
				break;
            case SDL_JOYBUTTONUP:
				if(event.jbutton.button == 7 /* LEFT */ && dir==0) dir=-1;
				if(event.jbutton.button == 8 /* UP */ && dir==1) dir=-1;
				if(event.jbutton.button == 9 /* RIGHT */ && dir==2) dir=-1;
				if(event.jbutton.button == 6 /* DOWN */ && dir==3) dir=-1;
				break;
            case SDL_QUIT:
                done = 1;
                break;
            default:
                break;
            }
        }

    }

    return 0;
}
