/*
 * menu_base.c
 * begin 20190527 true
 */

#include "menu.h"
#include "user_config.h"

#include <string.h>



MenuItem *menu;
uint8_t menu_idx = 0;

uint8_t mtick;



__HIGH_CODE
void menu_tick()
{
	if (menu) {
		// display
		if (menu->dispfn) {
			menu->dispfn(menu_idx);

			// // do we flip the display?
			if ((menu == &menu_6_about) && (menu_idx == 5)) { 	// about > accelerometer
                // accelerometer page never flips
				ssd1306_set_flipmirror(0);
			} else if (menu != &menu_none) {				    // not nametag
				if (sysflags & SYS_OLED_ROTATE_X) {
					ssd1306_set_flipmirror(1);
				} else {
					ssd1306_set_flipmirror(0);
				}
			}
		}
	}

	mtick++;
}

void menu_start(uint8_t x)
{
	(void)(x);

	menu = (MenuItem *)&menu_0;
	menu_idx = 0;

	uconf.framemod = UCONF_FRAMERATE_FULL;

	menu_btn_use_std();
}

void menu_stop(uint8_t x)
{
    (void)(x);

	menu = (MenuItem *)&menu_none;

	menu_btn_use_none();
}


void menu_btn_next(uint8_t idx)
{
	menu_idx++;
	if (menu_idx >= menu->count) {
		menu_idx = 0;
	}
}

void menu_btn_prev(uint8_t idx)
{
	if (menu_idx == 0) {
		menu_idx = menu->count - 1;
	} else {
		menu_idx--;
	}
}

void menu_btn_enter(uint8_t idx)
{
	if (menu->entryfn) {
		menu->entryfn(menu_idx);
	}
}

void menu_btn_exit(uint8_t idx)
{
	if (menu->root) {
		// save data to flash if necessary
		if (menu->flags & MENU_FLAG_SAVE_ON_EXIT) {
			uconf_write();
		}

		// change menu
		menu_idx = menu->root_idx;
		menu = menu->root;
	}

	// some menu entries override the enter button.
	// make sure we're set back up to known values
	menu_btn_use_std();

	// if any menu disabled LEDs, re-enable them
	uconf.flags &= ~UCONF_FLAGS_LEDS_DISABLE;
}

void menu_btn_use_std()
{
	btn[0].cb_push = &menu_btn_next;
	btn[0].cb_hold = &menu_btn_next;
	btn[0].cb_release = 0;
	btn[0].hold = 400 / HOLD_PERIOD;
	btn[0].repeat = 180 / HOLD_PERIOD;

	btn[1].cb_push = &menu_btn_exit;
	btn[1].cb_hold = 0;
	btn[1].cb_release = 0;
	btn[1].hold = 0;
	btn[1].repeat = 0;

	btn[2].cb_push = &menu_btn_enter;
	btn[2].cb_hold = 0;
	btn[2].cb_release = 0;
	btn[2].hold = 0;
	btn[2].repeat = 0;

	btn[3].cb_push = &menu_btn_prev;
	btn[3].cb_hold = &menu_btn_prev;
	btn[3].cb_release = 0;
    btn[3].hold = btn[0].hold;
    btn[3].repeat = btn[0].repeat;

    btn_commit_hold();
}

void menu_btn_use_none()
{
	uint8_t i;

	for (i = 0; i < MENU_BTN_COUNT; i++) {
		btn[i].cb_push = &menu_btn_enter;
		btn[i].hold = 0;
		btn[i].repeat = 0;
	}

	btn_commit_hold();
}


__HIGH_CODE
void menu_draw_buttons(uint8_t mode, uint8_t mask)
{
	uint8_t w;
	uint8_t i, j;

	char button_txt[4][12];

	// text
	if (menu->flags & MENU_FLAG_SCROLL) {
		strcpy(button_txt[0], "Scroll");
		strcpy(button_txt[2], "Scroll");
	} else {
		button_txt[0][0] = 0;
		button_txt[2][0] = 0;
	}

	switch (mode) {
		case MENU_BTNSTYLE_MAIN: {
			switch (mask) {
				case 0:		strcpy(button_txt[1], "Resume"); break;
				//case 3:
				//case 4:	strcpy(button_txt[1], "Play"); break;
				default:	strcpy(button_txt[1], "Select"); break;
			}
			strcpy(button_txt[3], " ");

			mask = 0x07;

			break;
		}

		case MENU_BTNSTYLE_MENU: {
			strcpy(button_txt[1], "Set/Chg");
			strcpy(button_txt[3], "Back");
			break;
		}

		case MENU_BTNSTYLE_NAME_IDLE: {
			strcpy(button_txt[0], "Next");
			strcpy(button_txt[1], "Edit");
			strcpy(button_txt[2], "Prev");
			strcpy(button_txt[3], "Done");
			break;
		}

		case MENU_BTNSTYLE_NAME_EDIT: {
			strcpy(button_txt[0], "Next");
			strcpy(button_txt[1], "Char Done");
			strcpy(button_txt[2], "Prev");
			strcpy(button_txt[3], "Backsp");
			break;
		}

		case MENU_BTNSTYLE_LED_EDIT:
		case MENU_BTNSTYLE_OPTION_EDIT: {
			strcpy(button_txt[0], "+");
			strcpy(button_txt[1], "OK");
			strcpy(button_txt[2], "-");
			strcpy(button_txt[3], "OK");
			break;
		}

		case MENU_BTNSTYLE_PROGSIMPLE_IDLE: {
			strcpy(button_txt[0], "->");
			strcpy(button_txt[1], "Edit");
			strcpy(button_txt[2], "<-");
			strcpy(button_txt[3], "Exit Editor");
			break;
		}
		case MENU_BTNSTYLE_PROGSIMPLE_EDIT: {
			strcpy(button_txt[0], "+");
			strcpy(button_txt[1], "Done");
			strcpy(button_txt[2], "-");
			strcpy(button_txt[3], "Next ->");
			break;
		}

		case MENU_BTNSTYLE_ABOUT: {
			for (i = 0; i < 4; i++) {
				button_txt[i][0] = 0x20;
				button_txt[i][1] = 0x00;
			}
			if (mask == 0x08) {
				strcpy(button_txt[3], "Back");
			}
			break;
		}
	}

	for (i = 0; i < 4; i++) {
		if (button_txt[i][0] == 0) {
			strcpy(button_txt[i], "----");
		}
	}

	ssd1306fb_set_cursor(18, -2);
	ssd1306fb_draw_str(font_Dialog_plain_8, button_txt[0], 0);

	w = ssd1306fb_get_str_width(font_Dialog_plain_8, button_txt[1], strlen(button_txt[1]), 0);
	ssd1306fb_set_cursor(116 - w, -2);
	ssd1306fb_draw_str(font_Dialog_plain_8, button_txt[1], 0);

	ssd1306fb_set_cursor(18, 24);
	ssd1306fb_draw_str(font_Dialog_plain_8, button_txt[2], 0);

	w = ssd1306fb_get_str_width(font_Dialog_plain_8, button_txt[3], strlen(button_txt[3]), 0);
	ssd1306fb_set_cursor(116 - w, 24);
	ssd1306fb_draw_str(font_Dialog_plain_8, button_txt[3], 0);

	// indicators
	i = 16; j = 0;		// lower and upper left
	while (j < 6) {
		if (mask & 0x02) ssd1306fb_draw_hline(11, i, 31 - j);
		if (mask & 0x01) ssd1306fb_draw_hline(11, i, j);
		i--; j++;
	}

	i = 118; j = 0;		// lower and upper right
	while (j < 6) {
		if (mask & 0x08) ssd1306fb_draw_hline(i, 123, 31 - j);
		if (mask & 0x04) ssd1306fb_draw_hline(i, 123, j);
		i++; j++;
	}
}

__HIGH_CODE
void menu_draw_tabs(uint8_t active_idx)
{
	uint8_t h;
	uint8_t i;

	uint8_t x, y, s;

	uint8_t count = menu->count;

	h = (SSD1306_HEIGHT - 1) / count;				// individual height
	y = ((SSD1306_HEIGHT - (h * count)) >> 1);		// starting offset
	s = y;											// memorized offset

	for (i = 0; i < count; i++) {
		x = (i == active_idx) ? 0 : 2;

		ssd1306fb_draw_hline(x, 6, y);
		ssd1306fb_draw_vline(x, y, y + h);

		y += h;

		if (i == active_idx) {
			ssd1306fb_draw_hline(0, 6, y);
		}

		if (y >= SSD1306_HEIGHT) {
			y = SSD1306_HEIGHT - 1;
		}
	}

	ssd1306fb_draw_hline(2, 6, y);

	ssd1306fb_draw_vline(6, s, y); 			// right line
}
