
/**
 * @file Menu.c
 *
 * This displays a menu structure on a 4 line LCD display
 *
 */
 
//#define PC 
 
#define LEFTKEY 	0x0a
#define RIGHTKEY	0x0b
#define UPKEY		0x0c
#define DOWNKEY		0x0d
#define ENTERKEY	0x0e

#define MAINMENU	0x10
#define TIMEMENU	0x20	
#define DATEMENU	0x30
#define SETTIMEMENU 0x40

#include <reg52.h>
#include <stdio.h>
#include "../../src/uniboard.h"
#include "../../src/lcd.h"
#include "../../src/pia.h"
#include "../../src/i2c.h"
#include "../../src/rtclock.h"

unsigned char x;
unsigned char y;
unsigned int IRVal = 0;		///< Contains ths received IR value if valid
unsigned char bitCount = 0;	///< Counts the number of bits received per command
bit IRValid = 0;        	///< status bit if the received byte is valid
sbit IRscan = P3^3;    		///< IR receiver pin


unsigned char hours=0, minutes=0, seconds=0,  h_seconds=0;


code char displaytitle[4][17] =
							{
								{"...Main Menu...0"},
								{"...Time Menu...1"},
								{"...Bla  Menu..10"},
								{"...Set Time..1.1"}
							};

#define MAXMAINITEMS 10
code char displayMainItem [MAXMAINITEMS][17]=
							{
								{"[  Time Menu 1 >"},
								{"<  Menu 2      >"},
								{"<  Menu 3      >"},
								{"<  Menu 4      >"},
								{"<  Menu 5      >"},
								{"<  Games!!!  6 >"},
								{"<  Menu 7      >"},
								{"<  Menu 8      >"},
								{"<  Menu 9      >"},
								{"<  Bla menu 10 ]"}
							};

code char displayTimeItem [2][17] =
							{
								{"[  Set Time    >"},
								{"<  Set Date    ]"}
							};

code char displayDateItem [2][17] =
							{
								{"[  bla bla 1   >"},
								{"<  bla bla 2   ]"}
							};


void DisplayMenu(unsigned char menu, unsigned char item, unsigned char cursorpos);
void Menu(unsigned char key);
unsigned char decodeIR(unsigned int value);




void Menu(unsigned char key)
{
	static unsigned char menu = MAINMENU;
	static unsigned char item = 0;
	static unsigned char subState=0;

	 
	switch(menu+key)
	{
		case MAINMENU+LEFTKEY:	if (item>0)item--; else item=MAXMAINITEMS-1; break;
		case MAINMENU+RIGHTKEY: if (item<MAXMAINITEMS-1)item++; else item=0; break;
		case MAINMENU+ENTERKEY: if      (item == 0){menu = TIMEMENU; item=0;}
								else if (item == 9){menu = DATEMENU; item=0;}
								break;
								
	 	case TIMEMENU+LEFTKEY:	item = 0; break;
		case TIMEMENU+RIGHTKEY: item = 1; break;
	 	case TIMEMENU+UPKEY:	menu = MAINMENU; item = 0; break;
	 	case TIMEMENU+ENTERKEY: if (item==0){ menu = SETTIMEMENU; item=0; } break;

	 	case DATEMENU+UPKEY:	menu = MAINMENU; item = 9; break;
		case DATEMENU+LEFTKEY:	item = 0; break;
		case DATEMENU+RIGHTKEY: item = 1; break;	
		

		case SETTIMEMENU+ENTERKEY:	menu=TIMEMENU; item=0; subState = 0; x=1; y=1; break; 	
		case SETTIMEMENU+UPKEY: if (subState==0 && hours   < 23) hours++; 
								if (subState==1 && minutes < 59) minutes++; 
								if (subState==2 && seconds < 59) seconds++; 
								break;
		case SETTIMEMENU+DOWNKEY: if (subState==0 && hours > 0) hours--;
								if (subState==1 && minutes > 0) minutes--; 
								if (subState==2 && seconds > 0) seconds--; 
								break;
		case SETTIMEMENU+RIGHTKEY: if( subState < 2) subState++; break;
		case SETTIMEMENU+LEFTKEY:  if( subState > 0) subState--; break;

	 	default: break;
	}
									
	DisplayMenu(menu,item,subState);						 
}



/**
 * this function displays what has to be displayed on the display.
 */
void DisplayMenu(unsigned char menu, unsigned char item, unsigned char cursorpos)
{
	SetCursorXYLCD(1,3);
	SetStringLCD(displaytitle[(menu/16)-1]);
	SetCursorXYLCD(1,4);
	switch(menu)
	{
		case MAINMENU:	SetStringLCD(displayMainItem[item]); break;
		case TIMEMENU:	SetStringLCD(displayTimeItem[item]); break;
		case DATEMENU:	SetStringLCD(displayDateItem[item]); break;	
		case SETTIMEMENU: 	FormatLCD("  %B02u:%B02u:%B02u      ",hours,minutes,seconds) ; 
							if (cursorpos==0){SetCursorXYLCD(4,4); x=4; y=4;}
							if (cursorpos==1){SetCursorXYLCD(7,4); x=7; y=4;}
							if (cursorpos==2){SetCursorXYLCD(10,4); x=10; y=4;}
							SetTime(hours,minutes,seconds, h_seconds);
							break;	
	}
}

void Delay(unsigned int time)
{
	while(time) time--;
}


unsigned char GetKey()
{
	unsigned char ch;
	static unsigned char state=1;

	Delay(1000);

	if(IRValid)
	{
		return decodeIR(IRVal);
	}	

	ch = GetPIA(PIA_PORT_C);	
	switch(ch)
		{
			case ~0x02: if(state == 1){ state = 0; return LEFTKEY;} else break;
			case ~0x01: if(state == 1){ state = 0; return RIGHTKEY;} else break;
			case ~0x08: if(state == 1){ state = 0; return UPKEY;} else break;
			case ~0x04: if(state == 1){ state = 0; return DOWNKEY;} else break;
			case ~0x10: if(state == 1){ state = 0; return ENTERKEY;} else break;
			case  0xff: if (state == 0) state = 1; break;
		}
	
	return 0;


}


void main()
{
	unsigned char ch;
	unsigned char old_Sec;
	ResetPIA();
	ControlPIA(PIA_PORT_C_LOW, PIA_INPUT, PIA_MODE_0);
	ControlPIA(PIA_PORT_C_HIGH, PIA_INPUT, PIA_MODE_0);
	InitLCD();
	ClearLCD();	
	Menu(0);
	while(1)
	{
		ch = GetKey();
		if (ch != 0) Menu(ch);
	}
}
