#include "pad.h"
#include "main.h"
#include "ed_host_int.h"
#include "ed_slave_int.h"
#include "ed_pad_int.h"
#include <string.h>
#include "util.h"

void pad_waitForAck(void);

extern unsigned char pad_ack_flag;

#define PADTIMEOUT 100L

void pad_waitForAck()
{
	long starttime=sleepcounter;
	
	pad_ack_flag=0;
	
	while (!pad_ack_flag)
	{
		if ((sleepcounter-starttime)>PADTIMEOUT)
		{
			commerror(4);
			break;
		}
		idle();
	}
	
	pad_ack_flag=0;
}

void pad_LcdPrintC(unsigned char x, unsigned char y, unsigned char font, const char *cstr)
{
	unsigned char chk=0;
	unsigned char len=cstrlen(cstr);
	
	pad_ack_flag=0;
	
	chk = pad_chksend(chk, 237);
	chk = pad_chksend(chk, len+8);
	chk = pad_chksend(chk, 0xc0);
	chk = pad_chksend(chk, 'T');
	chk = pad_chksend(chk, x);
	chk = pad_chksend(chk, y);
	chk = pad_chksend(chk, font);
	chk = pad_chksend_cstring(chk, cstr);
	chk = pad_chksend(chk, chk);

	pad_waitForAck();
}

void pad_LcdPrint(unsigned char x, unsigned char y, unsigned char font,  char *str)
{
	unsigned char chk=0;
	unsigned char len=strlen(str);
	
	pad_ack_flag=0;
	
	chk = pad_chksend(chk, 237);
	chk = pad_chksend(chk, len+8);
	chk = pad_chksend(chk, 0xc0);
	chk = pad_chksend(chk, 'T');
	chk = pad_chksend(chk, x);
	chk = pad_chksend(chk, y);
	chk = pad_chksend(chk, font);
	chk = pad_chksend_string(chk, str);
	chk = pad_chksend(chk, chk);

	pad_waitForAck();
}


void pad_LcdClear()
{
	unsigned char chk=0;

	pad_ack_flag=0;
		
	chk = pad_chksend(chk, 237);
	chk = pad_chksend(chk, 5);
	chk = pad_chksend(chk, 0xc0);
	chk = pad_chksend(chk, 'C');
	chk = pad_chksend(chk, chk);

	pad_waitForAck();
}


void pad_ConsoleWriteC(const char *cstr)
{
	unsigned char chk=0;
	unsigned char len=cstrlen(cstr);
	
	chk = pad_chksend(chk, 237);
	chk = pad_chksend(chk, len+5);
	chk = pad_chksend(chk, 0xc0);
	chk = pad_chksend(chk, 'W');
	chk = pad_chksend_cstring(chk, cstr);
	pad_chksend(chk, chk);
}

void pad_ConsoleWrite(char *str)
{
	unsigned char chk=0;
	unsigned char len=strlen(str);
	
	chk = pad_chksend(chk, 237);
	chk = pad_chksend(chk, len+5);
	chk = pad_chksend(chk, 0xc0);
	chk = pad_chksend(chk, 'W');
	chk = pad_chksend_string(chk, str);
	pad_chksend(chk, chk);
}

void pad_ConsoleWriteInt(int v, unsigned char len)
{
	unsigned char buf[5];
	unsigned char chk=0;
	
	formatInt(v, buf, len);

	chk = pad_chksend(chk, 237);
	chk = pad_chksend(chk, len+5);
	chk = pad_chksend(chk, 0xc0);
	chk = pad_chksend(chk, 'W');
	chk = pad_chksend_string(chk, buf);
	pad_chksend(chk, chk);
}

unsigned char pad_chksend(unsigned char chk, unsigned char c)
{
	ED_PAD_putData(c);
	return (chk<<1)+c+(chk&0x80 ? 1: 0);
}

unsigned char pad_chksend_cstring(unsigned char chk, const char *s)
{
	unsigned char i=0;
	
	while (s[i]!=0)
	{
		chk = pad_chksend(chk, s[i]);
		i++;
	}
	
	return chk;
}

unsigned char pad_chksend_string(unsigned char chk, char *s)
{
	unsigned char i=0;
	
	while (s[i]!=0)
	{
		chk = pad_chksend(chk, s[i]);
		i++;
	}
	
	return chk;
}

void pad_waitButtonRelease()
{
	while (pad_buttons!=0)
		idle();
}

unsigned char pad_gets()
{
	unsigned char old_up, old_down, old_right, old_left;
	unsigned char b;
	
	pad_waitButtonRelease();
	
	old_up=pad_move_up;
	old_down=pad_move_down;
	old_left=pad_move_left;
	old_right=pad_move_right;
	
	while (1)
	{
		idle();
		
		if (pad_move_up!=old_up)
			return PAD_UP | (pad_buttons<<4);
		if (pad_move_down!=old_down)
			return PAD_DOWN | (pad_buttons<<4);
		if (pad_move_left!=old_left)
			return PAD_LEFT | (pad_buttons<<4);
		if (pad_move_right!=old_right)
			return PAD_RIGHT | (pad_buttons<<4);
		
		b=pad_pollButtons();
		if (b)
			return b;
	}
	
	return 0;
}

// This doesn't call idle, so you must do so somewhere
unsigned char pad_currentButtons()
{
	return pad_buttons<<4;
}

unsigned char pad_pollButtons()
{
	idle();
	return pad_buttons<<4;
}

extern int usrange[2];
extern unsigned char uslastport;

/*// we call this function whenever we're waiting for something on the pad
void pad_idle(void)
{
	updateAnalog();

	if (pad_allowhost)
	{
 		if (ED_HOST_isData())
			doHost();
 	}
 			
 	if (ED_PAD_isData())
 		doPad();
 			
 	if (ED_SLAVE_isData())
 		doSlave();
 		
	usrange[uslastport]=0xffff-Timer16_SONAR_wReadCompareValue();
}
*/