#include "oswald.h"
#include "oswald_watch_faces.h"
#include "oswald_screens.h"
#if 0
#include "Fonts.h"
#include "LcdDisplay.h"
#endif
#include "oswald_main.h"

/*
 * some variable defining our curent state
 * these are globals in order to avoid having to pass pointers
 * through function calls thus saving stack space
 */
clock_state OswaldClk;
watch_state OswaldState;
watch_screen OswaldScreens[LAST_SCREEN];


void oswald_change_to_screen(screen_number screen_id)
{
	// we spare the update if no change happened
	if (OswaldState.screen_id != screen_id) {
		OswaldState.screen_id = screen_id;
		if ((OswaldState.screen->event_func != NULL) &&
		    (OswaldState.screen->event_mask & EVENT_SCREEN_VISIBLE))
				OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
	}
}

void oswald_set_time(u8t hour, u8t minute, u8t second)
{
	OswaldClk.hour = hour;
	OswaldClk.minute = minute;
	OswaldClk.second = second;
}

static void update_clock_state (void)
{
	OswaldClk.second += 1;
	if (OswaldClk.second > 59) {
		OswaldClk.second = 0;
		OswaldClk.minute += 1;
	} else
		return;
	if (OswaldClk.minute > 59) {
		OswaldClk.minute = 0;
		OswaldClk.hour += 1;
	} else
		return;
	if (OswaldClk.hour > 23) {
		OswaldClk.hour = 0;
		// day++
	} else
		return;
}

void oswald_one_second_tick(void)
{
	/* update our 'RTC' */
	update_clock_state();

	/* wake-up screen if interested in the one-second-event */
	if (OswaldState.screen->event_func != NULL &&
	    (OswaldState.screen->event_mask & EVENT_ONE_SEC_TIMER))
		OswaldState.screen->event_func(EVENT_ONE_SEC_TIMER, NULL);
	// oswald_update_screen();
}

void oswald_handle_button_press(watch_button button)
{
	switch (button) {
		case BUTTON_A:
		case BUTTON_B:
		case BUTTON_D:
		case BUTTON_E:
			if (OswaldState.screen->event_func != NULL &&
			    (OswaldState.screen->event_mask & EVENT_USER_BUTTONS))
				OswaldState.screen->event_func(EVENT_USER_BUTTONS, &button);
			break;
		case BUTTON_C:
			// next screen
			OswaldState.screen_id++;
			if (OswaldState.screen_id >= LAST_SCREEN) {
				OswaldState.screen_id = IDLE_SCREEN;
			};
			OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
			//oswald_update_screen();
			OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
			break;
		case BUTTON_F:
			// backlight on/off
			break;
		default:
			// should never get here
			break;
	};
}

void oswald_init(void)
{
	OswaldScreens[IDLE_SCREEN].event_mask = EVENT_ONE_SEC_TIMER;
	OswaldScreens[IDLE_SCREEN].event_func = idle_handle_events;

	OswaldScreens[ACCEL_DISPLAY_SCREEN].event_mask = EVENT_USER_BUTTONS;
	OswaldScreens[ACCEL_DISPLAY_SCREEN].event_func = accel_handle_events;
	

	OswaldScreens[DATETIME_SETTING_SCREEN].event_mask = EVENT_USER_BUTTONS | EVENT_ONE_SEC_TIMER;
	OswaldScreens[DATETIME_SETTING_SCREEN].event_func = datetime_setup_events;

	OswaldScreens[MENU_TEST_SCREEN].event_mask = EVENT_USER_BUTTONS;
	OswaldScreens[MENU_TEST_SCREEN].event_func = test_menu_handle_events;

	OswaldState.screen_id = IDLE_SCREEN;
	OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
	OswaldState.idle_show_seconds = FALSE;

	if (OswaldState.screen->event_func != NULL)
		OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
}