/*
 * $Id: menu_1_fn.c 459 2019-06-17 02:26:39Z true $
 * begin 20190612 true
 *
 * name setup menu functions
 */

#include "ui/menu.h"
#include "disp/font.h"

#include "user_config.h"

#include <stdio.h>
#include <string.h>


#define EDIT_MODE_OFF		0x00
#define EDIT_MODE_IDLE		0x01
#define EDIT_MODE_EDIT		0x02


static uint8_t xdata menu_last;
static uint8_t xdata edit_mode = 0;
static uint8_t xdata edit_pos;


uint8_t menu_1_get_offset()
{
	uint8_t a;

	if (edit_pos < strlen(uconf.name)) {
		a = uconf.name[edit_pos];

		if (a < 0x30) {
			return 0x30;
		} else if (a < 0x40) {
			return 0x40;
		} else if (a < 0x60) {
			return 0x60;
		}
	}

	return 0x20;
}

void menu_1_btn_next()
{
	uint8_t first, last, len;

	if (edit_mode == EDIT_MODE_IDLE) {
		edit_pos++;
		if (edit_pos > strlen(uconf.name) || edit_pos > UCONF_NAME_MAXLEN) {
			edit_pos = 0;
		}
	} else {
		first = font_table[uconf.font_idx].font[FONT_FIRST_CHAR_POS];
		last  = font_table[uconf.font_idx].font[FONT_CHAR_NUM_POS] + first;
		len   = strlen(uconf.name);

		if (edit_pos < UCONF_NAME_MAXLEN ) {
			uconf.name[edit_pos]++;
			if ((uconf.name[edit_pos] < first) || (uconf.name[edit_pos] >= last)) {
				uconf.name[edit_pos] = first;
			}

			if (edit_pos == len) {
				uconf.name[edit_pos + 1] = 0x00;
			}
		}
	}
}

void menu_1_btn_prev()
{
	uint8_t first, last, len;

	if (edit_mode == EDIT_MODE_IDLE) {
		if (edit_pos == 0) {
			edit_pos = strlen(uconf.name) + 1;
		}
		edit_pos--;
	} else {
		first = font_table[uconf.font_idx].font[FONT_FIRST_CHAR_POS];
		last  = font_table[uconf.font_idx].font[FONT_CHAR_NUM_POS] + first;
		len   = strlen(uconf.name);

		if (edit_pos < UCONF_NAME_MAXLEN) {
			if (uconf.name[edit_pos] <= first) {
				uconf.name[edit_pos] = last;
			}
			uconf.name[edit_pos]--;

			if (edit_pos == len) {
				uconf.name[edit_pos + 1] = 0x00;
			}
		}
	}
}

void menu_1_btn_enter()
{
	if (edit_mode == EDIT_MODE_IDLE) {
		edit_mode = EDIT_MODE_EDIT;
	} else {
		edit_mode = EDIT_MODE_IDLE;
	}
}

void menu_1_btn_exit()
{
	uint8_t i;

	if (edit_mode == EDIT_MODE_IDLE) {
		edit_mode = EDIT_MODE_OFF;
		menu_btn_use_std();
	} else {
		// delete
		/*
		if (strlen(uconf.name)) {
			if (edit_pos) {
				for (i = edit_pos; i < strlen(uconf.name) - 1; i++) {
					uconf.name[i] = uconf.name[i+1];
				}
				uconf.name[i] = 0x00;
			}
		}*/

		// backspace
		if (edit_pos && (uconf.name[0] != 0)) {
			for (i = edit_pos - 1; i < strlen(uconf.name); i++) {
				uconf.name[i] = uconf.name[i + 1];
			}
			uconf.name[i] = 0x00;
			edit_pos--;
		}
	}
}

void menu_1_btn_use()
{
	btn[0].push_cb = &menu_1_btn_prev;
	btn[0].held_cb = &menu_1_btn_prev;
	btn[0].release_cb = 0;
	btn[0].hold_time = 12;
	btn[0].hold_retrig = (edit_mode == EDIT_MODE_IDLE) ? 256 : 64;

	btn[1].push_cb = &menu_1_btn_exit;
	btn[1].held_cb = 0;
	btn[1].release_cb = 0;

	btn[2].push_cb = &menu_1_btn_enter;
	btn[2].held_cb = 0;
	btn[2].release_cb = 0;

	btn[3].push_cb = &menu_1_btn_next;
	btn[3].held_cb = &menu_1_btn_next;
	btn[3].release_cb = 0;
	btn[3].hold_time = 12;
	btn[3].hold_retrig = btn[0].hold_retrig;
}

void menu_1_name_edit()
{
	uint8_t w, x;
	char xdata txt[10];

	ssd1306fb_set_cursor(10, 8);
	ssd1306fb_draw_str(font_table[1].font, uconf.name, 0);

	ssd1306fb_draw_circle(oled.cursor_x + 4, oled.cursor_y + 7, (mtick & 0x04) ? 2 : 1);

	// draw underline
	if (edit_mode == EDIT_MODE_IDLE || (edit_mode == EDIT_MODE_EDIT && (mtick & 0x08))) {
		x = font_table[1].font[FONT_WIDTH_POS];
		w = x - 1;

		x *= edit_pos;
		x += 10;
		w += x;

		ssd1306fb_draw_hline(x + 1, w, 21);
	}

	// draw character count and limits

	sprintf(txt, "%2Bu / %02Bu", (uint8_t)strlen(uconf.name), (uint8_t)UCONF_NAME_MAXLEN);
	ssd1306fb_set_cursor((oled.width >> 1) - (ssd1306fb_get_str_width(font_table[0].font, txt, strlen(txt), 0) >> 1), 24);
	ssd1306fb_draw_str(font_table[0].font, txt, 0);
}

void menu_1_font_next()
{
	do {
		uconf.font_idx++;
		if (uconf.font_idx >= (sizeof(font_table) / sizeof(font_table[0]))) {
			uconf.font_idx = 0;
		}
	} while (!font_table[uconf.font_idx].tag_allowed);
}

void menu_1_disp(uint8_t idx)
{
	int8_t w, x;
	char xdata txt[16];

	if (edit_mode != EDIT_MODE_OFF) {
		menu_1_btn_use();	// this also sets button speed as necessary
		menu_1_name_edit();
		goto MENU_0_DRAW_TEXT_DONE;
	}

	ssd1306fb_set_cursor(10, 7);

	// which item selected?
	switch (idx) {
		case 0: {
			ssd1306fb_draw_str(font_table[0].font, "Set Your Name", 1);
			strcpy(txt, "Set>");
			break;
		}
		case 1: {
MENU_0_ORIENTATION:
			ssd1306fb_draw_str(font_table[0].font, "Nametag Orientation", 1);
			switch (uconf.nameconf & UCONF_NAME_DISP_MASK) {
				case UCONF_NAME_DISP_STATIC_HORIZ: {
					strcpy(txt, "Horiz");
					break;
				}
				case UCONF_NAME_DISP_STATIC_VERT: {
					strcpy(txt, "Vert");
					break;
				}
				case UCONF_NAME_DISP_WIGGLE: {
					strcpy(txt, "Wiggle");
					break;
				}
				case UCONF_NAME_DISP_CHAR_ROTATE: {
					oled.state |= SSD1306_STATE_STR_HALFWIDTH;
					strcpy(txt, "Always UP");
					break;
				}
			}
			break;
		}
		case 2: {
			if ((uconf.nameconf & UCONF_NAME_DISP_MASK) != UCONF_NAME_DISP_CHAR_ROTATE) {
				ssd1306fb_draw_str(font_table[0].font, "Nametag Flip", 1);

				if (uconf.nameconf & UCONF_NAME_MODE_ROTATE180) {
					strcpy(txt, "Flip");
				} else if (uconf.nameconf & UCONF_NAME_MODE_AUTOROTATE) {
					strcpy(txt, "Auto");
				} else {
					strcpy(txt, "Normal");
				}

				break;
			} else {
				if (menu_last > menu_idx) {
					menu_idx--;
					goto MENU_0_ORIENTATION;
				} else {
					menu_idx++;
					goto MENU_0_FONT;
				}
			}
			break;
		}
		case 3: {
MENU_0_FONT:
			ssd1306fb_draw_str(font_table[0].font, "Font", 1);

			ssd1306fb_set_cursor(10, 15);
			ssd1306fb_draw_str(font_table[0].font, font_table[uconf.font_idx].name, 1);

			ssd1306fb_set_cursor(69,
					2 + oled.height - ssd1306fb_get_font_height(font_table[uconf.font_idx].font));
			ssd1306fb_draw_str(font_table[uconf.font_idx].font, "ab", 1);

			goto MENU_0_DRAW_TEXT_DONE;
			break;
		}
		case 4: {
			ssd1306fb_draw_str(font_table[0].font, "Character Spacing (px)", 1);
			sprintf(txt, "%Bd", (int8_t)uconf.char_spacing);
			break;
		}
		case 5: {
			ssd1306fb_draw_str(font_table[0].font, "Render at Half Width?", 1);
			strcpy(txt, (uconf.nameconf & UCONF_NAME_MODE_HALFWIDTH) ? "Yes" : "No");
			break;
		}
		case 6: {
			ssd1306fb_draw_str(font_table[0].font, "Pixel Draw Mode", 1);
			strcpy(txt, (uconf.nameconf & UCONF_NAME_MODE_COLOR_INVERT) ? "Invert" : "Bright");
			break;
		}
	}

	w = ssd1306fb_get_str_width(font_table[1].font, txt, strlen(txt), 1);
	x = 68 - (w >> 1);
	ssd1306fb_set_cursor(x, 18);
	ssd1306fb_draw_str(font_table[1].font, txt, 1);

	// draw box
	ssd1306fb_draw_rect(x - 2, 18, x + w + 2, 31);

MENU_0_DRAW_TEXT_DONE:
	oled.state &= ~SSD1306_STATE_STR_HALFWIDTH;

	// draw extras
	menu_draw_tabs(idx);

	if (edit_mode == EDIT_MODE_OFF) {
		w = MENU_BTNSTYLE_MENU;
	} else {
		w = 0x10 + edit_mode;
	}

	menu_draw_buttons(w, 0x0f);

	// remember this for skipping
	menu_last = menu_idx;
}

void menu_1_enter(uint8_t idx)
{
	int8_t a;

	switch (idx) {
		case 0: {
			// start the name editor...
			edit_mode = EDIT_MODE_IDLE;
			edit_pos = 0;
			return;
		}
		case 1: {	// display mode
			a = (uconf.nameconf & UCONF_NAME_DISP_MASK) >> UCONF_NAME_DISP_OFFSET;

			if (++a >= UCONF_NAME_DISP_COUNT) {
				a = 0;
			}

			uconf.nameconf &= ~UCONF_NAME_DISP_MASK;
			uconf.nameconf |= (a << UCONF_NAME_DISP_OFFSET) & UCONF_NAME_DISP_MASK;

			return;
		}
		case 2: {	// char flip mode
			if ((uconf.nameconf & UCONF_NAME_DISP_MASK) != UCONF_NAME_DISP_CHAR_ROTATE) {
				if (uconf.nameconf & UCONF_NAME_MODE_AUTOROTATE) {
					uconf.nameconf &= ~(UCONF_NAME_MODE_ROTATE180 | UCONF_NAME_MODE_AUTOROTATE);
				} else if (uconf.nameconf & UCONF_NAME_MODE_ROTATE180) {
					uconf.nameconf &= ~UCONF_NAME_MODE_ROTATE180;
					uconf.nameconf |= UCONF_NAME_MODE_AUTOROTATE;
				} else {
					uconf.nameconf |= UCONF_NAME_MODE_ROTATE180;
				}
			}

			return;
		}
		case 3: {	// font
			menu_1_font_next();
			break;
		}
		case 4: {
			if (++uconf.char_spacing > 9) {
				uconf.char_spacing = -1;
			}

			break;
		}
		case 5: {
			if (uconf.nameconf & UCONF_NAME_MODE_HALFWIDTH) {
				uconf.nameconf &= ~UCONF_NAME_MODE_HALFWIDTH;
			} else {
				uconf.nameconf |=  UCONF_NAME_MODE_HALFWIDTH;
			}
			break;
		}
		case 6: {
			if (uconf.nameconf & UCONF_NAME_MODE_COLOR_INVERT) {
				uconf.nameconf &= ~UCONF_NAME_MODE_COLOR_INVERT;
			} else {
				uconf.nameconf |=  UCONF_NAME_MODE_COLOR_INVERT;
			}
			break;
		}
	}
}
