/*
Copyright (C) 1996-1997 Id Software, Inc.

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
// in_null.c -- for systems without a mouse

#include "quakedef.h"

#include "ds.h"

extern "C" unsigned int keysDown(void);
extern "C" unsigned int keysUp(void);
extern "C" unsigned int keysHeld(void);

void debug_msg(char *);
void get_pen_pos(short *px, short *py);

//#define USE_RECORDED_INPUT
//#define PLAYBACK_INPUT
//#define RECORD_INPUT

//#define SHOULDER_LOCK

#ifdef USE_RECORDED_INPUT
struct input_record
{
	unsigned int down;
	unsigned int up;
	unsigned int held;
	short px, py;
} recorded_input_data[1000];

unsigned int num_recorded_frames = 0;
int is_playback_loaded = 0;
#endif

extern cvar_t sensitivity;

void IN_Init (void)
{
}

void IN_Shutdown (void)
{
}

extern int mip_used;
int tex_up = 1;

unsigned int profile_begin_time = 0;
unsigned int server_hblanks = 0;
bool outa_data = false;

bool use_osk = false;

void dump_texture_state(void);
int addKeyboardEvents(void);

void enable_keyb(void);
void disable_keyb(void);

void IN_Commands (void)
{
	unsigned int down = keysDown();
	unsigned int up = keysUp();
	
#ifdef RECORD_INPUT
	extern int host_framecount;
	
	if (host_framecount >= 1000)
	{
		printf("trying to record input, but no space available\n");
		goto just_save_anyway;
	}
	
	recorded_input_data[host_framecount].down = down;
	recorded_input_data[host_framecount].up = up;
#endif

#ifdef PLAYBACK_INPUT
	if (!outa_data)
	{
		if (!is_playback_loaded)
		{
			printf("trying to open playback info...\n");
			
			FILE *fp = fopen("fat0:/input.dump", "rb");
			
			if (fp == NULL)
				Sys_Error("failed!\n");
			
			fread(&num_recorded_frames, sizeof(num_recorded_frames), 1, fp);
			fread(recorded_input_data, sizeof(recorded_input_data), 1, fp);
			fclose(fp);
			
			printf("done\n");
			
			is_playback_loaded = 1;
		}
		
		extern int host_framecount;
		
		if (host_framecount >= 1000)
			Sys_Error("trying to playback input, but no data available\n");
		
		extern unsigned int hblanks_doing_server;
		server_hblanks += hblanks_doing_server;
		
		if (host_framecount == 10)
		{
			extern unsigned int hblanks;
			profile_begin_time = hblanks;
			
			server_hblanks = 0;
		}
		
		if (host_framecount == num_recorded_frames - 1)
		{
			printf("finished playback\n");
			
			if (num_recorded_frames > 10)
			{
				extern unsigned int hblanks;
				unsigned int profile_current_time = hblanks;
				
				printf("took %d hblanks to render %d frames\n",
					profile_current_time - profile_begin_time, num_recorded_frames - 10);
				printf("average %.2f fps (%.2f ms/frame)\n",
					(float)(num_recorded_frames - 10) / (profile_current_time - profile_begin_time) * (262 * 60),
					(float)1.0f / ((float)(num_recorded_frames - 10) / (profile_current_time - profile_begin_time) * (262 * 60)) * 1000);
				printf("%.2f ms/frame on server\n",
					(float)1.0f / ((float)(num_recorded_frames - 10) / (server_hblanks) * (262 * 60)) * 1000);
			}
			else
				printf("not enough frames for an accurate result\n");
				
	//		printf("suspending execution.\n");
	//		while(1);
			outa_data = true;
		}
	
		down = recorded_input_data[host_framecount].down;
		up = recorded_input_data[host_framecount].up;
	}
#endif
	
	if (down || up)
	{
//		if ((down & 1) == 1)		//A
//		{
//			use_osk = !use_osk;
//			
//			if (use_osk)
//				enable_keyb();
//			else
//				disable_keyb();
//		}
		if ((down & 1) == 1)
			Key_Event(K_DS_A, true);
		if ((up & 1) == 1)			//A
			Key_Event(K_DS_A, false);
			
		if ((down & 2) == 2)		//B
			Key_Event(K_DS_B, true);
		if ((up & 2) == 2)			//B
			Key_Event(K_DS_B, false);
			
		if ((down & 4) == 4)		//B
			Key_Event(K_ENTER, true);
		if ((up & 4) == 4)			//B
			Key_Event(K_ENTER, false);
			
		if ((down & 8) == 8)		//B
			Key_Event(K_ESCAPE, true);
		if ((up & 8) == 8)			//B
			Key_Event(K_ESCAPE, false);
		
		if ((down & 16) == 16)		//right
			Key_Event(K_RIGHTARROW, true);
		if ((up & 16) == 16)		//right
			Key_Event(K_RIGHTARROW, false);
		
		if ((down & 32) == 32)		//left
			Key_Event(K_LEFTARROW, true);
		if ((up & 32) == 32)		//left
			Key_Event(K_LEFTARROW, false);
		
		if ((down & 64) == 64)		//up
			Key_Event(K_UPARROW, true);
		if ((up & 64) == 64)		//up
			Key_Event(K_UPARROW, false);
		
		if ((down & 128) == 128)	//down
			Key_Event(K_DOWNARROW, true);
		if ((up & 128) == 128)		//down
			Key_Event(K_DOWNARROW, false);
		
		if ((down & 256) == 256)		//R
//			tex_up++;
			Key_Event(K_DS_R, true);
		if ((up & 256) == 256)
			Key_Event(K_DS_R, false);
			
		if ((down & 512) == 512)		//L
//			tex_up--;
			Key_Event(K_DS_L, true);
		if ((up & 512) == 512)
			Key_Event(K_DS_L, false);
		
//		if (((down & 512) == 512) && ((down & 256) == 256))
//			dump_texture_state();
			
		if ((down & 1024) == 1024)		//X
			Key_Event(K_DS_X, true);
		if ((up & 1024) == 1024)
			Key_Event(K_DS_X, false);
			
		if ((down & 2048) == 2048)		//Y
			Key_Event(K_DS_Y, true);
		if ((up & 2048) == 2048)
			Key_Event(K_DS_Y, false);

#ifdef RECORD_INPUT
		if ((down & 2048) && (down & 1024))
		{
just_save_anyway:
			ds_try_exram_lock();
			
			printf("writing input recording to disk as \"input.dump\", %d frames\n", num_recorded_frames);
			FILE *fp = fopen("fat0:/input.dump", "wb");
			
			if (fp == NULL)
				Sys_Error("couldn\'t open file for writing!\n");
			
			fwrite(&num_recorded_frames, sizeof(num_recorded_frames), 1, fp);
			fwrite(recorded_input_data, sizeof(recorded_input_data), 1, fp);
			
			fclose(fp);
			
			Sys_Error("done\n");
		}
#endif	
	}
	
	if (use_osk)
	{
		int vkey_press = addKeyboardEvents();
		
		if (vkey_press >= 0)
		{
			Key_Event(vkey_press, true);
			Key_Event(vkey_press, false);
		}
	}
	
#ifdef SHOULDER_LOCK
	down = keysDown();
	if (((down & 512) == 512) && ((down & 256) == 256))
		while(1);
#endif
}

short last_px = 128;
short last_py = 96;
short first_px = 0;
short first_py = 0;

extern unsigned int blanks;
unsigned int last_down_time = 0;
void IN_Move (usercmd_t *cmd)
{
	short px, py;
	unsigned int down = keysDown();
	unsigned int held = keysHeld();
	unsigned int up = keysUp();
	get_pen_pos(&px, &py);
	
#ifdef RECORD_INPUT
	extern int host_framecount;
	
	if (host_framecount >= 1000)
		Sys_Error("trying to record input, but no space available\n");
	
	recorded_input_data[host_framecount].px = px;
	recorded_input_data[host_framecount].py = py;
	recorded_input_data[host_framecount].held = held;
	
//	printf("pen at %d %d\n", px, py);
	
	num_recorded_frames++;
#endif

#ifdef PLAYBACK_INPUT
	if (!outa_data)
	{
		if (!is_playback_loaded)
		{
			printf("trying to open playback info...\n");
			
			FILE *fp = fopen("fat0:/input.dump", "rb");
			
			if (fp == NULL)
				Sys_Error("failed!\n");
			
			fread(&num_recorded_frames, sizeof(num_recorded_frames), 1, fp);
			fread(recorded_input_data, sizeof(recorded_input_data), 1, fp);
			fclose(fp);
			
			printf("done\n");
			
			is_playback_loaded = 1;
		}
		
		extern int host_framecount;
		
		if (host_framecount >= 1000)
			Sys_Error("trying to playback input, but no data available\n");
		
		down = recorded_input_data[host_framecount].down;
		up = recorded_input_data[host_framecount].up;
		held = recorded_input_data[host_framecount].held;
		
		px = recorded_input_data[host_framecount].px;
		py = recorded_input_data[host_framecount].py;
		
	//	printf("pen at %d %d\n", px, py);
	}
#endif

	if ((down & (1 << 12)) == (1 << 12))
	{
		last_px = px;
		last_py = py;
	}
	
	if ((held & 4096) == 4096)
	{
		/*if ((down & 256) == 256)
		{
			cmd->forwardmove -= (py - 96);
			cmd->sidemove += (px - last_px);
		}
		else*/
		{
			if (m_pitch.value > 0)
				cl.viewangles[PITCH] += (((py - last_py) * 2) * sensitivity.value / 11);
			else
				cl.viewangles[PITCH] -= (((py - last_py) * 2) * sensitivity.value / 11);
				
			cl.viewangles[YAW] -= (((px - last_px) * 2) * sensitivity.value / 11);

//			if (m_pitch.value > 0)
//				cl.viewangles[PITCH] += ((py - last_py) * 0.75f);
//			else
//				cl.viewangles[PITCH] -= ((py - last_py) * 0.75f);
//				
//			cl.viewangles[YAW] -= ((px - last_px) * 0.75f);
		}
		
//		printf("sensitivity %.2f\n", sensitivity.value);
		
//		if (blanks - last_down_time < 30)
//			if ((abs(px - first_px) < 20) && (abs(py - first_py) < 20))
//			{
//				Key_Event(K_ENTER, true);
//				Key_Event(K_ENTER, false);
//			}
		
		V_StopPitchDrift();
	}
//	
//	if ((up & 4096) == 4096)
//	{
//		last_down_time = blanks;
//		first_px = px;
//		first_py = py;
//	}

	last_px = px;
	last_py = py;
	
//	Sys_Printf("vel %.2f %.2f\n", cl.velocity[0], cl.velocity[1]);
	
//	if ((keysHeld() & (1 << 12)) == (1 << 12))
//		cl.viewangles[YAW] += 1;
}

