#include "data.h"
#include "script.h"

char vg_script_data[VG_SCRIPT_MAX_SIZE] = {0};
int vg_script_state = VG_SCRIPT_STATE_IDLE;
int vg_script_command = 0;
int vg_script_pos = 0;
int vg_script_mid_execution = 0;

char * vg_script_commands[256] =
{
	"STOPMUSIC",       // 0
	"PLAYMUSIC",       // 1
	"PAUSEMUSIC",      // 2
	"RESUMEMUSIC",     // 3
	"FADEOUT",         // 4
	"FADEIN",          // 5
	"LOADLEVEL",       // 6
	"EXITWARP",        // 7
	"UNLOCKWARP",      // 8
	NULL
};

void vg_script_execute_command(int command, char * parm)
{
	int i;
	
	vg_script_command = command;
		
	printf("Execution\n");
	switch(command)
	{
		case 0:
		{
			ncds_stop_music();
			break;
		}
		case 1:
		{
			ncds_play_music(parm, 1);
			break;
		}
		case 2:
		{
			ncds_pause_music();
			break;
		}
		case 3:
		{
			ncds_resume_music();
			break;
		}
		case 4:
		{
			fade_out(2);
			gametime_reset();
			break;
		}
		case 5:
		{
			fade_in(vg_palette, 2);
			gametime_reset();
			break;
		}
		case 6:
		{
			destroy_level(vg_level);
			vg_level = load_level(parm);
			read_level_data(vg_level);
			vg_player.sprite.x = itofix(vg_last_warp.dx);
			vg_player.sprite.y = itofix(vg_last_warp.dy);
			vg_player.sprite.state = vg_last_warp.ds;
			vg_player.sprite.frame = 0;
			gametime_reset();
			break;
		}
		case 7:
		{
			vg_player.warp_type = atoi(parm);
			switch(vg_player.warp_type)
			{
				case VG_CHARACTER_WARP_TYPE_DOWN_OUT:
				case VG_CHARACTER_WARP_TYPE_UP_OUT:
				{
					ncds_play_sample(vg_sound[VG_SOUND_PLAYER_WARP], 127, -1, -1);
					vg_player.warp_time = vg_player.sprite.sp->ap[vg_player.sprite.state]->h;
					break;
				}
				case VG_CHARACTER_WARP_TYPE_LEFT_OUT:
				case VG_CHARACTER_WARP_TYPE_RIGHT_OUT:
				{
					ncds_play_sample(vg_sound[VG_SOUND_PLAYER_WARP], 127, -1, -1);
					vg_player.warp_time = vg_player.sprite.sp->ap[vg_player.sprite.state]->w;
					break;
				}
			}
			vg_player.sprite.active = 1;
			vg_logic();
			vg_update();
			vg_draw();
			break;
		}
		case 8:
		{
			vg_progress.warp_lock[atoi(parm)] = 0;
			break;
		}
	}
}

void vg_script_execute_line(char * text)
{
	char command[64] = {0};
	int i;
	int poffset = 0;
	
	for(i = 0; text[i] != ' ' && text[i] != '\n' && text[i] != '\0'; i++)
	{
		command[i] = text[i];
	}
	command[i] = '\0';
	poffset = i + 1;
	for(i = poffset; text[i] != '\n' && text[i] != '\0'; i++)
	{
		command[i] = text[i];
	}
	command[i] = '\0';
	for(i = 0; i < 256; i++)
	{
		if(vg_script_commands[i] && !stricmp(command, vg_script_commands[i]))
		{
			printf("%s <%s>\n", command, &command[poffset]);
			vg_script_execute_command(i, &command[poffset]);
			break;
		}
	}
	printf("finished executing command %s\n", command);
}

void vg_script_logic(void)
{
	
	/* ensure no unwanted recursion */
	if(!vg_script_mid_execution)
	{
//		printf("%d %d\n", vg_script_state, vg_script_pos);
		switch(vg_script_state)
		{
			case VG_SCRIPT_STATE_IDLE:
			{
				break;
			}
			case VG_SCRIPT_STATE_PROCESSING:
			{
				vg_script_mid_execution = 1;
				vg_script_execute_line(&vg_script_data[vg_script_pos]);
				while(vg_script_data[vg_script_pos] != '\n' && vg_script_state != VG_SCRIPT_STATE_IDLE)
				{
					printf("+");
					vg_script_pos++;
					if(vg_script_data[vg_script_pos] == '\0')
					{
						strcpy(vg_script_data, "");
						vg_script_state = VG_SCRIPT_STATE_IDLE;
						vg_script_pos = 0;
						printf("Script is done!\n");
						vg_player.sprite.x = itofix(vg_last_warp.dx);
						vg_player.sprite.y = itofix(vg_last_warp.dy);
						vg_player.sprite.state = vg_last_warp.ds;
						vg_player.sprite.frame = 0;
						gametime_reset();
					}
				}
				if(vg_script_state != VG_SCRIPT_STATE_IDLE)
				{
					printf("-");
					vg_script_pos++;
				}
				vg_script_mid_execution = 0;
				break;
			}
			case VG_SCRIPT_STATE_WAITING:
			{
				break;
			}
		}
	}
}

void vg_script_append(char * text)
{
	strcat(vg_script_data, text);
	if(vg_script_state == VG_SCRIPT_STATE_IDLE)
	{
		vg_script_state = VG_SCRIPT_STATE_PROCESSING;
	}
}
