/* $Id: playermenu.c,v 1.2 2004/05/20 16:55:30 stpohle Exp $ 
 *
 */

#include "bomberclone.h"
#include "menu.h"
#include "menugui.h"
#include "player.h"
#include "network.h"
#include "keyb.h"
#include "single.h"
#include "ogcache-client.h"


/*
 * prototype definitions
 */
static int playermenu_gfxaviable (int gfx);
static void playermenu_selgfx_drawplayer (int selgfx, _menu *menu);
#define PLAYERMENU_GFXSEL_Y 130


/*
 * check if the gfx is still aviable
 */
static int playermenu_gfxaviable (int gfx) {
	int i;
	
	for (i = 0; i < MAX_PLAYERS && gfx != players[i].gfx_nr; i++);
	if (i == MAX_PLAYERS)
		return 1;
	
	return 0;
};



/*
 * draw a list of all stil aviable players and the
 * selection border of where we are at the moment
 * ! menu == NULL, in this case just delete the gfx_aviable
 *                 buffer to force an repaint of all gfx.
 */
static void playermenu_selgfx_drawplayer (int selgfx, _menu *menu) {
	static int gfx_aviable[2][MAX_PLAYERS]; // old and new state, 1 if gfx is aviable
	static int old_gfxsel = -1;
	static int changed = 0;
	SDL_Rect rect, srcrect;
	int i;

	/*
	 * delete old state, to force an update of all playergfx
	 */
	if (menu == NULL) {
		for (i = 0; i < MAX_PLAYERS; i++)
			gfx_aviable[1][i] = -1;
		changed = 1;
		return;
	}

	/*
	 * check changes in the playerselections
	 * 1. copy current state into the old state and set all 
	 * gfx as aviable. 
	 */
	for (i = 0; i < MAX_PLAYERS; i++) {
		gfx_aviable[0][i] = gfx_aviable[1][i] & 1;
		gfx_aviable[1][i] = 1;
	}
	/*
	 * 2. delete the aviable flag from all selected player gfx
	 * set another bit to mark our selection, set the changedc flag if
	 * there was any change
	 */
	for (i = 0; i < MAX_PLAYERS; i++) {
		if (PS_IS_used (players[i].state) && players[i].gfx_nr >= 0 && players[i].gfx_nr < MAX_PLAYERS)
			gfx_aviable[1][players[i].gfx_nr] = 0;
	}
	for (i = 0; i < MAX_PLAYERS && changed == 0; i++) if (players[i].gfx_nr >= 0) changed = 1;
	if (selgfx >= 0 && selgfx < MAX_PLAYERS) // do the selection
		gfx_aviable[1][selgfx] += 2;
	if (selgfx != old_gfxsel)
		changed = 1;
	old_gfxsel = selgfx;
	/*
	 * 3. draw changes from the last loop
	 */
	if (changed) {
		rect.x = 0;
		rect.w = menu->oldscreenpos.w - 2 * menuimages[0]->w;
		rect.y = PLAYERMENU_GFXSEL_Y;
		rect.h = 4 * GFX_IMGSIZE;
		menu_draw_background (menu, &rect);
		
		for (i = 0; i < MAX_PLAYERS; i++) {
			srcrect.h = rect.h = gfx.players[i].ani.h;
			srcrect.w = rect.w = gfx.players[i].ani.w;
			rect.x = GFX_IMGSIZE * (i % 4) + ((menu->oldscreenpos.w - 2 * menuimages[0]->w) -(4 * GFX_IMGSIZE)) / 2 ;
			rect.y = GFX_IMGSIZE * (i / 4) + PLAYERMENU_GFXSEL_Y;
			if (gfx_aviable[1][i] & 1) {
				/* gfx is aviable */
				srcrect.x = gfx.players[i].ani.w * down;
				srcrect.y = 0;
				rect.x += menu->oldscreenpos.x + menuimages[0]->w;
				rect.y += menu->oldscreenpos.y + menuimages[0]->h;
		        gfx_blit (gfx.players[i].ani.image, &srcrect, gfx.screen, &rect, 10002);
			}
			if (gfx_aviable[1][i] & 2) {
				/* draw the select border */
				srcrect.x = 0;
				srcrect.y = 0;
				srcrect.h = rect.h = GFX_IMGSIZE;
				srcrect.w = rect.w = GFX_IMGSIZE;
				rect.x = GFX_IMGSIZE * (i % 4) + ((menu->oldscreenpos.w - 2 * menuimages[0]->w) -(4 * GFX_IMGSIZE)) / 2;
				rect.y = GFX_IMGSIZE * (i / 4) + PLAYERMENU_GFXSEL_Y;
				rect.x += (gfx.players[i].ani.w - gfx.menuselect.image->w) / 2; // center the playergfx
				rect.x += menu->oldscreenpos.x + menuimages[0]->w;
				rect.y += menu->oldscreenpos.y + menuimages[0]->h;
		        gfx_blit (gfx.menuselect.image, &srcrect, gfx.screen, &rect, 10001);
			}
		}
	}
}



/*

+------------------------------------------------+
|  Name Lokaler Player 1 : ________________      |
|  Name Lokaler Player 2 : ________________      |
|                                                |
|  Button USE Lok. Pl.2  <--- if this is pressed a second local
|  Button Add AI Player       player will join.. still working on
|                                                |
|  List of Connected Players                     |
|  |                       |   Button Kick       |
|  |                       |                     |
|  |                       |   Button Info       |
|  |                       |                     |
|  |                       |    Button OK        |
|  +-----------------------+                     |
+------------------------------------------------+

 */
void playermenu () {
	_menu *menu;
	_menuitem *btn_SecondPlayer;
	_menuitem *list_PlayerList;
	_charlist playerlist[MAX_PLAYERS + 1];
	_charlist *playerlist_sel = &playerlist[0];
	int i, menuselect = 0, done = 0, eventstate, pl_nr;
	SDL_Event event;

	for (i = 0; i < MAX_PLAYERS; i++)
		if (PS_IS_used(players[i].state))
			sprintf (playerlist[i].text, "%2d. %15s", i+1, players[i].name);
		else
			sprintf (playerlist[i].text, "%2d. %15s", i+1, "");
	charlist_fillarraypointer (playerlist, MAX_PLAYERS);
	menu = menu_new ("Playermenu", 400, 350);
	
	menu_create_entry (menu, " Player 1 Name: ", -1, 50, 350, &bman.playername, LEN_PLAYERNAME, MENU_entrytext, 2);
	menu_create_entry (menu, " Player 2 Name: ", -1, 80, 350, &bman.player2name, LEN_PLAYERNAME, MENU_entrytext, 3);
	if (IS_LPLAYER2)
		btn_SecondPlayer = menu_create_button (menu, "Quit Second Player", 25, 130, 190, 4);
	else
		btn_SecondPlayer = menu_create_button (menu, "Use Second Player", 25, 130, 190, 4);
	
	if (GT_SP || GT_MP_PTPM)
		menu_create_button (menu, "Add AI Player", 25, 160, 190, 5);
	
	menu_create_label (menu, "Connected Players", 20, 210, 0, COLOR_brown); 
	list_PlayerList = menu_create_list (menu, "playerlist", 15, 230, 200, 120, playerlist, &playerlist_sel, 6);
	
	if (GT_SP || GT_MP_PTPM)
		menu_create_button (menu, "Kick Player", 240, 230, 150, 7); 
	
	// menu_create_button (menu, "Playerinfo", 240, 275, 150, 8); 
	menu_create_button (menu, "OK", 240, 320, 150, 1); 
	
	/* prepare everything for the menu_loop */
	menu_focus_id (menu, 1);
	menu->looprunning = 1;
	menu_draw (menu);
	
	/* the menu loop */
	do {
		for (i = 0; i < MAX_PLAYERS; i++) {
			if (PS_IS_used(players[i].state))
				sprintf (playerlist[i].text, "%2d. %15s", i+1, players[i].name);
			else
				sprintf (playerlist[i].text, "%2d. %15s", i+1, "");
		}
		list_PlayerList->changed = 1;
		menu_draw_menuitem (list_PlayerList);

		gfx_blitdraw ();
		eventstate = SDL_PollEvent (&event);
		if (bman.sock != -1)
			network_loop ();

		done = menu_event_loop (menu, &event, eventstate);
		/* 
		 * check if one of the buttons was pressed
		 */
		if (done == 1 && menu->focus->id == 4) {	/* second local player want to join */
			if (IS_LPLAYER2)
				player_delete (bman.p2_nr);
			else
				player2_join ();
			
			if (IS_LPLAYER2)
				sprintf (btn_SecondPlayer->label, "Quit Second Player");
			else
				sprintf (btn_SecondPlayer->label,"Use Second Player");
			
			menu_draw_button (btn_SecondPlayer);
		}

		if (done == 1 && menu->focus->id == 5) {	/* create ai player */
			single_create_ai (1);
			done = 0;
		}

		if (done == 1 && menu->focus->id == 6)		/* playerlist */
			done = 0;

		if (done == 1 && menu->focus->id == 7) {	/* kick player */
			pl_nr = playerlist_sel - &playerlist[0];
			if (pl_nr >= 0 && pl_nr < MAX_PLAYERS && pl_nr != bman.p_servnr)
				player_delete (pl_nr);
			else
				menu_displaymessage ("No", "You can't kick yourself from the game.\n");
			done = 0;
		}

		if (done == 1 && menu->focus->id == 8) {	/* player info */
			// playermenu_info ();
			done = 0;
		}

		s_calctimesync ();
	} while ((done == 0 || menu->focus->id != 1) && done != -1 && menuselect != -1 && menuselect != 1);

	if (menu->focus->id == 1 && done == 1) {
		/*
		 * ok button pressed, so save all settings
		 */
		config_write ();
	}

	menu_delete (menu);
};



/*
 * draw a small menu where the player has to select his gfx 
 */
void playermenu_selgfx (int pl_nr) {
	_menu *menu;
	int selgfx, eventstate;
    SDL_Event event;
    Uint8 *keys;
	int done = 0;

	if (pl_nr < 0 || pl_nr >= MAX_PLAYERS)
		return;

	selgfx = players[pl_nr].gfx_nr;
	if (selgfx < 0) 
		selgfx = 1;

	playermenu_selgfx_drawplayer (-1, NULL);
	player_set_gfx (&players[pl_nr], -1);
	
	menu = menu_new ("Player Selection", 400, 270);
	menu_create_text (menu, "playergfxsel", -1, 50, 40, 5, COLOR_yellow, "%s, please select your Player and press ENTER/RETURN or press ESCAPE for no player (that means you will only watch the next game).", players[pl_nr].name);

    menu->looprunning = 1;
	menu_draw (menu);
	

	while (!done && bman.state != GS_quit) {
        /* do the network loop if we have to */
        if (bman.sock > 0) {
            network_loop ();
            if (bman.notifygamemaster)
                ogc_loop ();
        }
		
        eventstate = SDL_PollEvent (&event);

        if (eventstate) {
            switch (event.type) {
            case (SDL_QUIT):
                bman.state = GS_quit;
                done = 1;
				menu_delete (menu);
				return;
                break;
            case (SDL_KEYDOWN): 
				/* 
				 * go to the next gfx or the preview one 
				 */
                if (event.key.keysym.sym == SDLK_TAB) {
                    keys = SDL_GetKeyState (NULL);
                    if (keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT]) {
                        if ((--selgfx) < 0)
							selgfx = MAX_PLAYERS-1;
					}
                    else {
                        if ((++selgfx) >= MAX_PLAYERS)
							selgfx = 0;
					}
                    break;
                }
				/*
				 * cursor keys for gfx selection
				 */
                if (event.key.keysym.sym == SDLK_UP && selgfx >= 4)
					selgfx -= 4;
                if (event.key.keysym.sym == SDLK_DOWN && selgfx < MAX_PLAYERS-4)
					selgfx += 4;
                if (event.key.keysym.sym == SDLK_RIGHT && selgfx < MAX_PLAYERS-1)
					selgfx++;
                if (event.key.keysym.sym == SDLK_LEFT && selgfx > 0)
					selgfx--;
				/*
				 * do not select any gfx
				 */
                else if (event.key.keysym.sym == SDLK_ESCAPE) {
                    selgfx = -1;
					done = 1;
					break;
                }
				/*
				 * select the current gfx if aviable
				 */
				else if (event.key.keysym.sym == SDLK_RETURN
					|| event.key.keysym.sym == SDLK_LCTRL || event.key.keysym.sym == SDLK_RCTRL 
					|| event.key.keysym.sym == keyb_gamekeys.keycode[BCPK_drop] || event.key.keysym.sym == keyb_gamekeys.keycode[BCPK_special] 
					|| event.key.keysym.sym == keyb_gamekeys.keycode[BCPK_max + BCPK_drop] || event.key.keysym.sym == keyb_gamekeys.keycode[BCPK_max + BCPK_special]) {
					if (playermenu_gfxaviable (selgfx))
						done = 1;
					break;
				}
            }
        }

		playermenu_selgfx_drawplayer (selgfx, menu);
		gfx_blitdraw ();

        s_calctimesync ();
	};
	menu_delete (menu);
	player_set_gfx (&players[pl_nr], selgfx);
};
