/* 
    TowBowlTactics: Strategy game for X11

    Copyright (C) 2001 Pascal Bourut (toweld@rocketmail.com)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "Console.h"

static void clear(ConsoleInformation*,char*);
static void quit(ConsoleInformation*,char*);
static void set(ConsoleInformation*,char*);
static void show_dices_roll(ConsoleInformation*,char*);
static void help(ConsoleInformation*,char*);
static void save_game(ConsoleInformation*,char*);
static void pause_game(ConsoleInformation*,char*);
static void weather_info(ConsoleInformation*,char*);
static void refresh(ConsoleInformation*,char*);
static void msg(ConsoleInformation*,char*);

Console::Console(SDL_Surface *screen, int x,int y,int w,int h, int type){
	load_images();
	focus = false;
	SDL_Rect console_rect;
	console_rect.x = x;
	console_rect.y = y;
	console_rect.w = w;
	console_rect.h = h;
	console_info = CON_Init(console_font, screen, MAX_LINES, console_rect);

	if(type==CLIENT || type==SERVER){
		CON_Alpha(console_info,100);

		CON_AddCommand(&clear, "/clear");
		CON_AddCommand(&help, "/help");
		CON_AddCommand(&msg,"/msg");

		CON_Out(console_info, "Welcome to tbt network console. (/help for command list)\n");
	}
	else {
		CON_Alpha(console_info,CONSOLE_ALPHA_OFF);

		CON_AddCommand(&clear, "/clear");
		CON_AddCommand(&quit, "/quit");
		CON_AddCommand(&set, "/set");
		CON_AddCommand(&save_game, "/save_game");
		CON_AddCommand(&show_dices_roll,"/show_dices_roll");
		CON_AddCommand(&refresh, "/refresh");
		CON_AddCommand(&help, "/help");
		CON_AddCommand(&pause_game, "/pause_game");
		CON_AddCommand(&weather_info,"/weather_info");
#ifndef NONET
		CON_AddCommand(&msg,"/msg");
#endif

		CON_Out(console_info, "Welcome to tbt console. (/help for command list)\n");
	}

	prompted = false;
}

Console::~Console(void){
	free_images();
	CON_Destroy(console_info);
}

void Console::load_images(void){
	console_font = IMG_Load(ADD_IMG_PATH("general/console_font.png"));
}

void Console::free_images(void){
	SDL_FreeSurface(console_font);
}

void Console::draw(void){
	CON_DrawConsole(console_info);
}

void Console::set_visible(bool b){
	visible = b;
	if(visible) set_focus(true);
	else if(focus) set_focus(false);
}

bool Console::get_visible(void){
	return visible;
}

void Console::toggle_visibility(void){
	visible = !visible;
	if(visible) set_focus(true);
	else if(focus) set_focus(false);
}

void Console::set_focus(bool b){
	focus = b;
	if(focus) {
		CON_Topmost(console_info);
		SDL_EnableUNICODE(1);
		CON_Alpha(console_info,console_info->ConsoleAlpha*CONSOLE_ALPHA_DIFF);
	}
	else {
		CON_Topmost(NULL);
		SDL_EnableUNICODE(0);	
		CON_Alpha(console_info,console_info->ConsoleAlpha/CONSOLE_ALPHA_DIFF);
	}
}

int Console::get_y(void){
	return console_info->DispY;
}

int Console::get_height(void){	 
	return console_info->OutputScreen->h;
}

int Console::get_x(void){
	return console_info->DispX;
}

int Console::get_width(void){	 
	return console_info->OutputScreen->w;
}

bool Console::get_focus(void){
	return focus;
}

void Console::handle_event(SDL_Event *event){
	if(event->type == SDL_KEYDOWN){
		switch (event->key.keysym.sym){
		case SDLK_RETURN:
			
			if(console_info->ConsoleLines[0] && prompted) {
				response = (char *)malloc(sizeof(char)*strlen(console_info->ConsoleLines[0]));
				sprintf(response, "%s",console_info->ConsoleLines[0]);
				console_info->ConsoleLines[0][0] = '\0';
				prompted = false;
			}
			else if(console_info->ConsoleLines[0] && 
				strlen(console_info->ConsoleLines[0]) > 0 &&
				console_info->ConsoleLines[0][0] != '/' ){
				char *tmp = (char *)malloc(sizeof(char)*strlen(console_info->ConsoleLines[0])+5);
				sprintf(tmp, "/msg %s",console_info->ConsoleLines[0]);
				sprintf(console_info->ConsoleLines[0],"%s",tmp);
			}
			break;
		default:
			break;
		}
	}

	CON_Events(event);
}

void Console::print(char *str, ...){ 
	va_list marker;
	char temp[256];

	va_start(marker, str);
	vsprintf(temp, str, marker);
	va_end(marker);

	CON_Out(console_info, "%s", temp);
}

void Console::prompt(char *str, ...){ 
	va_list marker;
	char temp[256];

	va_start(marker, str);
	vsprintf(temp, str, marker);
	va_end(marker);

	CON_OutNoNewLine(console_info, "%s", temp);
	prompted = true;
	response_avaiable = true;
	response = NULL;
}

char* Console::get_response(){
	response_avaiable = false;
	if(response) return response;
	return NULL;
}

bool Console::is_response_available(){
	return response_avaiable;
}

/////////////////////////      Command List       ////////////////////////

static void set(ConsoleInformation *console_info,char *str){
	char var[16];
	char param[4][16];
	int param_nb;
	int n;
	n = sscanf(str, "%s %s %s %s %s", var,param[0],param[1],param[2],param[3]);
	if(n > 0){
		param_nb = n-1;
		if(strcmp(var,"square")==0){
			if(param_nb==1){
				if( strcmp(param[0],"visible")==0 ) set_ticks_drawing_mode(true);
				else if( strcmp(param[0],"hidden")==0 ) set_ticks_drawing_mode(false);
				else CON_Out(console_info, "! square param must be visible or hidden.");
			}
			else {
				CON_Out(console_info, "! square param must be visible or hidden.");
			}	
		}
		else if(strcmp(var,"number")==0){
			if(param_nb==1){
				if( strcmp(param[0],"visible")==0 ) set_number_drawing_mode(true);
				else if( strcmp(param[0],"hidden")==0 ) set_number_drawing_mode(false);
				else CON_Out(console_info, "! number param must be visible or hidden.");
			}
			else {
				CON_Out(console_info, "! number param must be visible or hidden.");
			}	
		}
		else if(strcmp(var,"tackle_zone")==0){
			if(param_nb==1){
				if( strcmp(param[0],"none")==0 ) set_tackle_zone_drawing_mode(NONE);
				else if( strcmp(param[0],"home")==0 ) set_tackle_zone_drawing_mode(HOME);
				else if( strcmp(param[0],"visitor")==0 ) set_tackle_zone_drawing_mode(VISITOR);
				else if( strcmp(param[0],"both")==0 ) set_tackle_zone_drawing_mode(BOTH);
				
				else CON_Out(console_info, "! tackle_zone param must be none, home, visitor or both.");
			}
			else {
				CON_Out(console_info, "! tackle_zone param must be visible or hidden.");
			}	
		}
		else if(strcmp(var,"infos")==0){
			if(param_nb==1){
				if( strcmp(param[0],"visible")==0 ) set_contextual_info_mode(true);
				else if( strcmp(param[0],"hidden")==0 ) set_contextual_info_mode(false);
				else CON_Out(console_info, "! infos param must be visible or hidden.");
			}
			else {
				CON_Out(console_info, "! infos param must be visible or hidden.");
			}	
		}
		else if(strcmp(var,"alpha")==0){
			if(param_nb==1){
				int alpha = atoi(param[0]);
				if(alpha>=50 && alpha<=255){
					CON_Alpha(console_info, alpha);
					CON_Out(console_info, "! alpha set to %i.", alpha);
				}
				else {
					CON_Out(console_info, "! alpha value must be between 50 and 255.");
				}
			}
			else {
				CON_Out(console_info, "! alpha value must be between 50 and 255.");
			}
		}
		else if(strcmp(var,"lines")==0){
			if(param_nb==1){
				int lines = atoi(param[0]);
				if(lines>=1 && lines<=MAX_DISPLAYED_LINES){
					SDL_Rect rect;
					rect.x = 0;
					rect.w = CONSOLE_WIDTH;
					rect.h = LINE_HEIGHT*lines;
					if(console_info->DispY==0) // top
						rect.y = 0;
					else {
						rect.y = HEIGHT-rect.h;
					}
					CON_Resize(console_info, rect);
					CON_Alpha(console_info,console_info->ConsoleAlpha);
					CON_Out(console_info, "lines number set to %i\n",lines);

				}
				else {
					CON_Out(console_info, "! lines value must be between 2 and %i.",MAX_DISPLAYED_LINES);
				}
			}
			else {
				CON_Out(console_info, "! lines value must be between 2 and %i.",MAX_DISPLAYED_LINES);
			}
		}
		else if(strcmp(var,"debug")==0){
			if(param_nb==1){
				if( strcmp(param[0],"true")==0 ) {
					set_debug(true);
					CON_Out(console_info, "! debug set to true");
				} 
				else if( strcmp(param[0],"false")==0 ) {
					set_debug(false);
					CON_Out(console_info, "! debug set to false");
				}
				else CON_Out(console_info, "! debug param must be true or false.");
			}
			else {
				CON_Out(console_info, "! debug param must be true or false.");
			}	
		}
		else if(strcmp(var,"position")==0){
			if(param_nb==1){
				if( strcmp(param[0],"top")==0 ) CON_Position(console_info, console_info->DispX, 0); 
				else if( strcmp(param[0],"bottom")==0 ) CON_Position(console_info, console_info->DispX, HEIGHT - console_info->ConsoleSurface->h);
				else CON_Out(console_info, "! position param must be top or bottom.");
			}
			else {
				CON_Out(console_info, "! position param must be top or bottom.");
			}
		}

#ifndef NOSOUND

		else if(strcmp(var,"sound")==0){
			if(param_nb==1){
				if( strcmp(param[0],"enable")==0 ) sp_enable(true);
				else if( strcmp(param[0],"disable")==0 ) sp_enable(false);
				else CON_Out(console_info, "! sound param must be enable or disable.");
			}
			else {
				CON_Out(console_info, "! sound param must be enable or disable.");
			}	
		}
		else if(strcmp(var,"volume")==0){
			if(param_nb==1){
				int vol = atoi(param[0]);
				if(vol>=0 && vol<=100){
					sp_volume(vol);
					CON_Out(console_info, "! volume set to %i",vol);
				}
				else {
					CON_Out(console_info, "! volume must be between 0 and 100.");
				}
			}
			else {
				CON_Out(console_info, "! volume must be between 0 and 100.");
			}	
		}

#endif
		
		else CON_Out(console_info, "! Unknown argument for set command.");
	}
	else CON_Out(console_info, "! You must specified an argument for set command.");
}

static void help(ConsoleInformation *console_info,char *){
	CON_ListCommands(console_info);
}

static void quit(ConsoleInformation *,char *){
	quit_game_box();
}

static void show_dices_roll(ConsoleInformation *console_info,char *str){
	if(strcmp(str,"true")==0) show_dices_roll(true);
	else if(strcmp(str,"false")==0) show_dices_roll(false);
	else CON_Out(console_info, "! show_dices_roll param must be true or false.");
}

static void clear(ConsoleInformation *console_info,char *){
	int i;
	for(i=0;i<(console_info->ConsoleSurface->h/LINE_HEIGHT);i++){
		CON_Out(console_info, " ");
	}
}

static void save_game(ConsoleInformation* console_info,char *str){

	if( !strlen(str) ) 
		CON_Out(console_info, "! You must specified a filename for this command.");
	else { // checker que le nom fasse moins de 14 caracteres et pas des caracteres de merdes!!!
		bool ok = true;
		for(unsigned int i=0;i<strlen(str);i++){
			ok = (ok && isalpha(str[i]));
		}
		if(ok && strlen(str)<=14 ) {
			if(save_game(str)!=-1) 
				CON_Out(console_info, "! Game '%s' successfully saved.", str);
			else 
				CON_Out(console_info, "! Failed to save game '%s'.", str);
		}
		else {
			CON_Out(console_info, "! Failed to save game '%s'.", str);
			CON_Out(console_info, "  U must enter a 14 max alpha name long.");
		}	
	}
}

static void pause_game(ConsoleInformation*,char *){
	toggle_pause(true);
}

static void refresh(ConsoleInformation*,char *){
	draw_all(true);
}

static void weather_info(ConsoleInformation* console_info,char*){
	switch(get_weather()){
	case GOOD:
		CON_Out(console_info, "! Nice : Perfect Blood Bowl weather");
		break; 
	case DOGDAYS:
		CON_Out(console_info, "! Sweltering heat : It's very hot and extremely humid.");
		CON_Out(console_info, "     Each player on the pitch may suffer for heat exhaustion");
		CON_Out(console_info, "     after a touchdown is scored."); 
		break;
	case SUNNY:
		CON_Out(console_info, "! Very sunny : A glorious day.");
		CON_Out(console_info, "     But the blinding sunshine causes a -1 modifier on all"); 
		CON_Out(console_info, "     attempts to pass the ball.");
		break;
	case SHOWER:
		CON_Out(console_info, "! Pouring rain : It's raining making the ball slippery and");
		CON_Out(console_info, "     difficult to hold. This causes a -1 modifier on all attempts"); 
		CON_Out(console_info, "      to catch the ball, picking it up and handing it off.");
		break;
	case BLIZZARD:
		CON_Out(console_info, "! Blizzard : It's cold and snowing !");
		CON_Out(console_info, "     The ice on the pitch means that any player attempting to"); 
		CON_Out(console_info, "     move an extra square will slip and fall on a roll of 1-2,");
		CON_Out(console_info, "     while the snow means that only quick and short passes can");
		CON_Out(console_info, "     be attempted.");
		break;
	}
	CON_Out(console_info, "                              ---");
}

static void msg(ConsoleInformation* console_info,char* msg_to_send){
#ifndef NONET
	net_send_msg(msg_to_send);
#endif
}

