#include <stdlib.h>
#include "SDL/SDL.h"
#include "display_scene.h"
#include "../common/structs.h"
#include "../common/debug.h"
#include "../common/buffer.h"
#include "glyphs.h"
#include <strings.h>
#include "globals.h"
#include "console.h"
#include <stdio.h>
#include "../simulation/simulation.h"

void draw_text_line(SDL_Surface *screen, const char *line, int x, int y);
void draw_buttons(SDL_Surface *screen);

extern int current_sim;
extern int sim_type;

int current_command = 0;
int history_pos = 0;

char frame_break_text[INPUT_COMMAND_LENGTH];
char command_list[NUM_SAVED_COMMANDS][INPUT_COMMAND_LENGTH];
char console_history[CONSOLE_HISTORY_LINES][INPUT_COMMAND_LENGTH];

void update_command_list()
{
	int i;

	strncpy(command_list[0], command_list[current_command], INPUT_COMMAND_LENGTH);
	for(i=NUM_SAVED_COMMANDS - 1; i >  0; i--)
	{
		strncpy(command_list[i], command_list[i-1], INPUT_COMMAND_LENGTH);
	}
}

void update_console_history(char *new_item)
{
	int i;
	
	//console history
	for(i=CONSOLE_HISTORY_LINES - 1; i >  0; i--)
	{
		strncpy(console_history[i], console_history[i-1], INPUT_COMMAND_LENGTH);
	}
	strncpy(console_history[0], new_item, INPUT_COMMAND_LENGTH);
}

void clear_input_string()
{
	int i;
	current_command = 0;
	for(i=0; i<INPUT_COMMAND_LENGTH; i++)
		command_list[current_command][i] = '\0';
}




void print_to_console(char *msg, va_list args)
{
	char buffer[5000];
	char *ptr;

	vsnprintf(buffer, 5000, msg, args);

	if((ptr = strtok(buffer, "\n\0")) != NULL)
		update_console_history(ptr);
	
	while( 	(ptr = strtok(NULL, "\n\0")) != NULL)
	{
			update_console_history(ptr);
	}
}

void print_to_bottom(char *text)
{
	char *ptr;

	if((ptr = strtok(text, "\n\0")) != NULL)
		draw_text_line(frontend->screen, text, 0, main_scene->height - LINE_HEIGHT*2 - 1);
	
//	while( 	(ptr = strtok(NULL, "\n\0")) != NULL)
//	{
//			update_console_history(ptr);
//	}
}

void save_for_frame_break(char *msg, va_list args)
{
	vsnprintf(frame_break_text, INPUT_COMMAND_LENGTH, msg, args);
}






void draw_glyph(char glyph, SDL_Surface *screen, int x, int y)
{
	Uint32* new_buffer;
	Uint32 white;
	char i,j;
	
	if(glyph == '\t')
		glyph = ' ';
	
	white = SDL_MapRGB(screen->format, 255, 255, 255);

	printd(CRAZY, "Drawing glyph\n");
	for(i=0; i < GLYPH_HEIGHT; i++)
	{
		for(j=0; j < GLYPH_WIDTH; j++)
		{
			if(glyphs[glyph-32][i*GLYPH_WIDTH+j])
			{
				if(y+i < main_scene->height && x+j < main_scene->width)
				{
					new_buffer = (Uint32*)screen->pixels + (y + i) * screen->pitch/4 + (x + j);
					*new_buffer = white;
				}
			}
		}
	}
}

void draw_text_line(SDL_Surface *screen, const char *line, int x, int y)
{
	unsigned int i;

	for(i=0; i < strlen(line); i++)
	{
		draw_glyph(line[i], screen, i * GLYPH_WIDTH + x, y);
	}
}

void draw_history(SDL_Surface *screen)
{
	int i;
	int j;
	
	j = history_pos + CONSOLE_LINES - 2;
	for(i=0; i< CONSOLE_LINES - 1; i++)
	{
		draw_text_line(screen, console_history[j], 0, i * LINE_HEIGHT);
		j--;
	}
}

void draw_current_command(SDL_Surface *screen)
{
	draw_glyph('>', screen, 0, (CONSOLE_LINES - 1) * LINE_HEIGHT + 2);
	draw_text_line(screen, command_list[current_command], GLYPH_WIDTH, (CONSOLE_LINES - 1) * LINE_HEIGHT);
}

void draw_console(SDL_Surface *screen)
{
	unsigned char* old_buffer;
	Uint32* new_buffer;
	Uint8 R, G, B;
	Uint32 sdl_color;
	int x,y;
	double scale;

	printd(CRAZY, "Drawing input\n");
	old_buffer = main_scene->frame_buffer;
	for(y=0; y < LINE_HEIGHT * CONSOLE_LINES && y < main_scene->height; y++)
	{
		for(x=0; x < main_scene->width; x++)
		{
			if(y == CONSOLE_LINES * LINE_HEIGHT - 2)
				scale = 0.50;
			else if(y == CONSOLE_LINES * LINE_HEIGHT - 1)
				scale = 0.80;
			else if(y > (CONSOLE_LINES - 1) * LINE_HEIGHT)
				scale = 0.25;
			else
				scale = 0.4;

			R = *old_buffer * scale;
			old_buffer++;
			G = *old_buffer * scale;
			old_buffer++;
			B = *old_buffer * scale;
			old_buffer++;


			sdl_color = SDL_MapRGB(screen->format, R, G, B);
			new_buffer = (Uint32*)screen->pixels + y * screen->pitch/4 + x;
			*new_buffer = sdl_color;

			printd(INSANE, "%x,%x,%x -- %x, %x\n", R,G,B,sdl_color, *new_buffer);
		}
	}

	
	draw_history(screen);
	draw_current_command(screen);
	print_to_bottom(frame_break_text);
}


void draw_buttons(SDL_Surface *screen)
{
	int length;
	char button_text[50] = "";
	unsigned char* old_buffer;
	Uint32* new_buffer;
	Uint8 R, G, B;
	Uint32 sdl_color;
	int x,y;
	double scale;


	//nice black line
	old_buffer = main_scene->frame_buffer + (main_scene->height-LINE_HEIGHT)*main_scene->width*3;
	for(y=main_scene->height-LINE_HEIGHT; y < main_scene->height; y++)
	{
		for(x=0; x < main_scene->width; x++)
		{
			scale = 0.50;

			R = *old_buffer * scale;
			old_buffer++;
			G = *old_buffer * scale;
			old_buffer++;
			B = *old_buffer * scale;
			old_buffer++;


			sdl_color = SDL_MapRGB(screen->format, R, G, B);
			new_buffer = (Uint32*)screen->pixels + y * screen->pitch/4 + x;
			*new_buffer = sdl_color;
		}
	}

	
	if(sim_type == T_CANNON)
	{
		strcpy((char*)&button_text, "grav fric tnt  mass step MODE RSET FIRE ");
		length = strlen(button_text);
		draw_text_line(screen, button_text,
				screen->w - length * GLYPH_WIDTH, screen->h - GLYPH_HEIGHT-1);
	}
	else if(sim_type == T_SPRING)
	{
		strcpy((char*)&button_text, "grav -k-  mass step damp MODE RSET GO!! ");
		length = strlen(button_text);
		draw_text_line(screen, button_text,
				screen->w - length * GLYPH_WIDTH, screen->h - GLYPH_HEIGHT-1);
	}
	else if(sim_type == T_BALLS)
	{
		strcpy((char*)&button_text, "#obj cplx size ");
		length = strlen(button_text);
		draw_text_line(screen, button_text,
					   screen->w - length * GLYPH_WIDTH, screen->h - GLYPH_HEIGHT-1);
	}
}

