/*
 * menu_entry_2.c
 * begin 20190612 true
 *
 * led setup menu functions
 */

#include "ui/menu.h"

#include "render/font.h"

#include "led/rgbled.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_PROGRAM_SELECT   0
#define LI_PROGRAM_EDIT     1
#define LI_FAVCOLOR_HUE     2
#define LI_FAVCOLOR_SAT     3
#define LI_FAVCOLOR_VAL     4
#define LI_ALTCOLOR_HUE     5
#define LI_ALTCOLOR_SAT     6
#define LI_ALTCOLOR_VAL     7



static uint8_t edit_mode = MENU_BTNSTYLE_MENU;
static uint8_t edit_idx;
static uint8_t prog_data_idx = 0;



static void menu_2_val_inc(uint8_t *val, uint8_t loop)
{
	if (!loop && *val == 0xff) return;
	(*val)++;
}

static void menu_2_val_dec(uint8_t *val, uint8_t loop)
{
	if (!loop && *val == 0x00) return;
	(*val)--;
}

void menu_2_btn_next(uint8_t idx)
{
	switch (edit_idx) {
		case LI_PROGRAM_EDIT: {
			switch (edit_mode) {
				case MENU_BTNSTYLE_PROGSIMPLE_IDLE: {
					prog_data_idx++;
					if (prog_data_idx > 15) {
						prog_data_idx = 0;
					}
					break;
				}
				case MENU_BTNSTYLE_PROGSIMPLE_EDIT: {
					uint8_t e;
					uint8_t *x;
					uint8_t *s;

					s = uconf.ledprog_rgb_data[uconf.ledprog_rgb_idx];
					x = &s[prog_data_idx >> 1];

					if (prog_data_idx & 0x01) {
						e = *x & 0xf;
						e++; if (e >= 0x10) e = 0;
						*x &= 0xf0;
						*x |= e & 0xf;
					} else {
						e = *x >> 4;
						e++; if (e >= 0x10) e = 0;
						*x &= 0x0f;
						*x |= e << 4;
					}
					break;
				}
			}
			break;
		}
		case LI_FAVCOLOR_HUE: menu_2_val_inc(&uconf.favcolor_hue, 1); return;
		case LI_FAVCOLOR_SAT: menu_2_val_inc(&uconf.favcolor_sat, 0); return;
		case LI_FAVCOLOR_VAL: menu_2_val_inc(&uconf.favcolor_val, 0); return;
		case LI_ALTCOLOR_HUE: menu_2_val_inc(&uconf.altcolor_hue, 1); return;
		case LI_ALTCOLOR_SAT: menu_2_val_inc(&uconf.altcolor_sat, 0); return;
		case LI_ALTCOLOR_VAL: menu_2_val_inc(&uconf.altcolor_val, 0); return;
	}
}

void menu_2_btn_prev(uint8_t idx)
{
	switch (edit_idx) {
		case LI_PROGRAM_EDIT: {
			switch (edit_mode) {
				case MENU_BTNSTYLE_PROGSIMPLE_IDLE: {
					if (prog_data_idx) {
						prog_data_idx--;
					} else {
						prog_data_idx = 15;
					}
					break;
				}
				case MENU_BTNSTYLE_PROGSIMPLE_EDIT: {
					uint8_t e;
					uint8_t *x;
					uint8_t *s;

					s = uconf.ledprog_rgb_data[uconf.ledprog_rgb_idx];
					x = &s[prog_data_idx >> 1];

					if (prog_data_idx & 0x01) {
						e = *x & 0xf;
						if (!e) e = 0xf; else e--;
						*x &= ~0xf;
						*x |= e & 0xf;
					} else {
						e = *x >> 4;
						if (!e) e = 0xf; else e--;
						*x &= ~0xf0;
						*x |= e << 4;
					}
					break;
				}
			}
			break;
		}
		case LI_FAVCOLOR_HUE: menu_2_val_dec(&uconf.favcolor_hue, 1); return;
        case LI_FAVCOLOR_SAT: menu_2_val_dec(&uconf.favcolor_sat, 0); return;
        case LI_FAVCOLOR_VAL: menu_2_val_dec(&uconf.favcolor_val, 0); return;
        case LI_ALTCOLOR_HUE: menu_2_val_dec(&uconf.altcolor_hue, 1); return;
        case LI_ALTCOLOR_SAT: menu_2_val_dec(&uconf.altcolor_sat, 0); return;
        case LI_ALTCOLOR_VAL: menu_2_val_dec(&uconf.altcolor_val, 0); return;
	}
}

void menu_2_btn_exit(uint8_t idx)
{
	edit_mode = MENU_BTNSTYLE_MENU;
	menu_btn_use_std();
}

void menu_2_btn_use(uint8_t idx)
{
	btn[0].cb_push = &menu_2_btn_prev;
	btn[0].cb_hold = &menu_2_btn_prev;
	btn[0].cb_release = 0;
	btn[0].hold = 200 / HOLD_PERIOD;
	btn[0].repeat = 40 / HOLD_PERIOD;

	btn[1].cb_push = &menu_2_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_2_btn_exit;
	btn[2].cb_hold = 0;
	btn[2].cb_release = 0;
	btn[2].hold = 0;
	btn[2].repeat = 0;

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

	btn_commit_hold();
}

void menu_2_edit_enter(uint8_t idx)
{
	if (edit_mode == MENU_BTNSTYLE_PROGSIMPLE_IDLE) {
		edit_mode = MENU_BTNSTYLE_PROGSIMPLE_EDIT;
	} else {
		edit_mode = MENU_BTNSTYLE_PROGSIMPLE_IDLE;
	}
}

void menu_2_edit_exit(uint8_t idx)
{
	if (edit_mode == MENU_BTNSTYLE_PROGSIMPLE_IDLE) {
		edit_mode = MENU_BTNSTYLE_MENU;
		menu_btn_use_std();
	} else {
		prog_data_idx++;
		prog_data_idx %= 16;
	}
}

void menu_2_edit_use(uint8_t idx)
{
	btn[0].cb_push = &menu_2_btn_prev;
	btn[0].cb_hold = &menu_2_btn_prev;
	btn[0].cb_release = 0;
	btn[0].hold = 280 / HOLD_PERIOD;
	btn[0].repeat = 160 / HOLD_PERIOD;

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

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

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

	btn_commit_hold();
}


__HIGH_CODE
void menu_2_disp(uint8_t idx)
{
	int i;
	int8_t w, x;
	uint8_t f;
	char txt[20];

	if (edit_mode == MENU_BTNSTYLE_LED_EDIT) {
		menu_2_btn_use(idx);
	}

	ssd1306fb_set_cursor(10, 7);

	if (idx >= LI_FAVCOLOR_HUE && idx <= LI_ALTCOLOR_VAL) {
		f = (idx - LI_FAVCOLOR_HUE) / 3;
		ssd1306fb_draw_str(font_table[0].font, (f == 0) ? "Favorite " : "Alternate ", 1);
	}

	// which item selected?
	switch (idx) {
		case LI_PROGRAM_SELECT: {
			ssd1306fb_draw_str(font_table[0].font, "RGB Program", 1);
			ssd1306fb_set_cursor(16, 15);
			ssd1306fb_draw_str(font_table[0].font, rgb_pgm[uconf.ledprog_rgb_idx].name, 1);

			goto MENU_2_DRAW_TEXT_DONE;
		}
		case LI_PROGRAM_EDIT: {
			uint8_t *s;
			uint8_t *topline;
			int8_t left;

            s = uconf.ledprog_rgb_data[uconf.ledprog_rgb_idx];

			if (edit_mode == MENU_BTNSTYLE_MENU) {
				ssd1306fb_draw_str(font_table[0].font, "RGB Settings", 1);
			} else {
			    if (rgb_pgm[uconf.ledprog_rgb_idx].edit_disp) {
			            topline = (uint8_t *)rgb_pgm[uconf.ledprog_rgb_idx].edit_disp(prog_data_idx);
			    } else {
			        strcpy(txt, "Hex Editor");
			        topline = txt;
			    }

			    w = ssd1306fb_get_str_width(font_table[1].font, topline, strlen(topline), 0);
                left = (oled.width >> 1) - (w >> 1);

				ssd1306fb_set_cursor(left - 4, 1);
				ssd1306fb_draw_str(font_table[1].font, topline, 1);

				// ssd1306fb_draw_rect(left - 2, 0, w + left + 1, 13);
			}			
			
			w = 16;
			x = 0;
			for (i = 0; i < 8; i++) {	
				sprintf(txt, "%01X", s[i] >> 4);
				ssd1306fb_set_cursor(w, 15);
				ssd1306fb_draw_str(font_table[0].font, txt, 0);
				if (prog_data_idx == x++) {
					if (edit_mode == MENU_BTNSTYLE_PROGSIMPLE_EDIT ||
					    edit_mode == MENU_BTNSTYLE_PROGSIMPLE_IDLE) {
						ssd1306fb_draw_hline(w, w+4, 25);
					}
					if (edit_mode == MENU_BTNSTYLE_PROGSIMPLE_EDIT) {
						ssd1306fb_draw_hline(w, w+4, 14);
					}
				}

				w += 5;
				sprintf(txt, "%01X", s[i] & 0xf);
				ssd1306fb_set_cursor(w, 15);
				ssd1306fb_draw_str(font_table[0].font, txt, 0);
				if (prog_data_idx == x++) {
					if (edit_mode == MENU_BTNSTYLE_PROGSIMPLE_EDIT ||
					    edit_mode == MENU_BTNSTYLE_PROGSIMPLE_IDLE) {
						ssd1306fb_draw_hline(w, w+4, 25);
					}
					if (edit_mode == MENU_BTNSTYLE_PROGSIMPLE_EDIT) {
						ssd1306fb_draw_hline(w, w+4, 14);
					}
				}

				w += 8;
			}			

			if (edit_mode == MENU_BTNSTYLE_PROGSIMPLE_EDIT) {

			}

			goto MENU_2_DRAW_TEXT_DONE;
		}
		case LI_FAVCOLOR_HUE:
		case LI_ALTCOLOR_HUE: {
			ssd1306fb_draw_str(font_table[0].font, "Color Hue", 1);

			// bar position
			f = (idx == LI_FAVCOLOR_HUE) ? uconf.favcolor_hue : uconf.altcolor_hue;

			// draw hue markers
			ssd1306fb_draw_vline(36 + 21, 19, 21);
			ssd1306fb_draw_vline(36 + 42, 19, 21);

			goto MENU_2_EDIT_COLOR_LINE;
		}
		case LI_FAVCOLOR_SAT:
		case LI_ALTCOLOR_SAT: {
			ssd1306fb_draw_str(font_table[0].font, "Color Sat.", 1);

			// bar position
			f = (idx == LI_FAVCOLOR_SAT) ? uconf.favcolor_sat : uconf.altcolor_sat;

			goto MENU_2_PCT_COLOR_TEXT;
		}
		case LI_FAVCOLOR_VAL:
		case LI_ALTCOLOR_VAL: {
			ssd1306fb_draw_str(font_table[0].font, "Color Value", 1);

			// bar position
			f = (idx == LI_FAVCOLOR_VAL) ? uconf.favcolor_val : uconf.altcolor_val;

MENU_2_PCT_COLOR_TEXT:
			// percentage text
			sprintf(txt, "%3u%%", ((uint16_t)f * 100) / 255);
			ssd1306fb_set_cursor(50, 24);
			ssd1306fb_draw_str(font_table[0].font, txt, 1);

MENU_2_EDIT_COLOR_LINE:
			// draw value line
			f >>= 2;
			f += 36;
			ssd1306fb_draw_hline(36, 99, 20);

			// draw end markers
			ssd1306fb_draw_vline(36,      19, 21);
			ssd1306fb_draw_vline(36 + 63, 19, 21);

			// draw position triangle
			ssd1306fb_draw_hline(f - 2, f + 2, 16);
			ssd1306fb_draw_line(f + 2, 16, f, 19);
			ssd1306fb_draw_line(f - 2, 16, f, 19);

			if (edit_mode == MENU_BTNSTYLE_LED_EDIT) {
				if (idx == LI_FAVCOLOR_HUE || idx == LI_ALTCOLOR_HUE) {
					// RGBR indicators
					ssd1306fb_set_cursor(33, 21);
					ssd1306fb_draw_str(font_table[0].font, "R", 0);

					oled.cursor_x = 33 + 21;
					ssd1306fb_draw_str(font_table[0].font, "G", 0);

					oled.cursor_x = 33 + 42;
					ssd1306fb_draw_str(font_table[0].font, "B", 0);

					oled.cursor_x = 33 + 63;
					ssd1306fb_draw_str(font_table[0].font, "R", 0);
				} else {
					// 0 - 100% indicators
					ssd1306fb_set_cursor(28 + 7, 21);
					ssd1306fb_draw_str(font_table[0].font, "0%", 0);

					oled.cursor_x = 28 + 63 - 14;
					ssd1306fb_draw_str(font_table[0].font, "100%", 0);
				}
			}

			goto MENU_2_DRAW_TEXT_DONE;
		}
	}

	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_2_DRAW_TEXT_DONE:
	// draw extras
	menu_draw_tabs(idx);

	menu_draw_buttons(edit_mode, 0x0f);
}

void menu_2_enter(uint8_t idx)
{
	uint8_t a;

	edit_idx = idx;

	switch (idx) {
		case 0: {
			a = (sizeof(rgb_pgm) / sizeof(rgb_pgm[0]));
			uconf.ledprog_rgb_idx++;
			if (uconf.ledprog_rgb_idx >= a) {
				uconf.ledprog_rgb_idx = 0;
			}
			break;
		}
		case 1: {
			edit_mode = MENU_BTNSTYLE_PROGSIMPLE_IDLE;
			menu_2_edit_use(idx);
			break;
		}
		default: {
			if (edit_mode == MENU_BTNSTYLE_LED_EDIT) {
				edit_mode = MENU_BTNSTYLE_MENU;
				menu_btn_use_std();
			} else {
				edit_mode = MENU_BTNSTYLE_LED_EDIT;
			}
		}
	}
}
