/*
 * menu_entry_1.c
 * begin 20190612 true
 *
 * name setup menu functions
 */

#include "menu.h"

#include "render/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

#define LI_NAME_SET         0
#define LI_ORIENTATION      1
#define LI_FLIP             2
#define LI_FONT             3
#define LI_CHAR_SPACING     4
#define LI_Y_OFFSET         5
#define LI_HALFWIDTH        6
#define LI_PIXEL_DRAWMODE   7


static uint8_t menu_last;
static uint8_t edit_mode = 0;
static uint8_t 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 idx)
{
	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 idx)
{
	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(uint8_t idx)
{
	if (edit_mode == EDIT_MODE_IDLE) {
		edit_mode = EDIT_MODE_EDIT;
	} else {
		edit_mode = EDIT_MODE_IDLE;
	}
}

void menu_1_btn_exit(uint8_t idx)
{
	uint8_t i;

	if (edit_mode == EDIT_MODE_IDLE) {
		edit_mode = EDIT_MODE_OFF;
		menu_btn_use_std();
	} else {
		// 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].cb_push = &menu_1_btn_prev;
	btn[0].cb_hold = &menu_1_btn_prev;
	btn[0].cb_release = 0;
	btn[0].hold = 280 / HOLD_PERIOD;
	btn[0].repeat = ((edit_mode == EDIT_MODE_IDLE) ? 240 : 60) / HOLD_PERIOD;

	btn[1].cb_push = &menu_1_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_1_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_1_btn_next;
	btn[3].cb_hold = &menu_1_btn_next;
	btn[3].cb_release = 0;
	btn[3].hold   = btn[0].hold;
	btn[3].repeat = btn[0].repeat;

	btn_commit_hold();
}

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

	ssd1306fb_set_cursor(10, 8);
	ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, 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_DejaVu_Sans_Mono_Bold_11[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, "%2u / %02u", (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);
}

__HIGH_CODE
void menu_1_disp(uint8_t idx)
{
	int8_t w, x;
	char 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 LI_NAME_SET: {
			ssd1306fb_draw_str(font_table[0].font, "Set Your Name", 1);
			strcpy(txt, "Set>");
			break;
		}
		case LI_ORIENTATION: {
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;
				}
				case UCONF_NAME_DISP_DEMOWAVE1: {
				    strcpy(txt, "Waves1");
				    break;
				}
				case UCONF_NAME_DISP_DEMOWAVE2: {
                    strcpy(txt, "Waves2");
                    break;
                }
			}
			break;
		}
		case LI_FLIP: {
			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 LI_FONT: {
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 LI_CHAR_SPACING: {
			ssd1306fb_draw_str(font_table[0].font, "Character Spacing (px)", 1);
			sprintf(txt, "%d", (int8_t)uconf.char_spacing);
			break;
		}
		case LI_Y_OFFSET: {
		    ssd1306fb_draw_str(font_table[0].font, "Render Y Offset (px)", 1);
            sprintf(txt, "%d", (int8_t)uconf.y_offset);
            break;
		}
		case LI_HALFWIDTH: {
			ssd1306fb_draw_str(font_table[0].font, "Render at Half Width?", 1);
			strcpy(txt, (uconf.nameconf & UCONF_NAME_MODE_HALFWIDTH) ? "Yes" : "No");
			break;
		}
		case LI_PIXEL_DRAWMODE: {
			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_DejaVu_Sans_Mono_Bold_11, txt, strlen(txt), 1);
	x = 68 - (w >> 1);
	ssd1306fb_set_cursor(x, 18);
	ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, 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 LI_NAME_SET: {
			// start the name editor...
			edit_mode = EDIT_MODE_IDLE;
			edit_pos = 0;
			return;
		}
		case LI_ORIENTATION: {	// display mode
			a = (uconf.nameconf & UCONF_NAME_DISP_MASK) >> UCONF_NAME_DISP_OFFSET;

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

			// currently unimplemented modes
			switch (a) {
                case 4: a++; break;
                case 7: a = 0; break;
			}

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

			return;
		}
		case LI_FLIP: {	// 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 LI_FONT: {	// font
			menu_1_font_next();
			break;
		}
		case LI_CHAR_SPACING: {
			if (++uconf.char_spacing > 9) {
				uconf.char_spacing = -1;
			}

			break;
		}
		case LI_Y_OFFSET: {
            if (++uconf.y_offset > 8) {
                uconf.y_offset = -4;
            }

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