/*
 * menu_entry_6.c
 * begin 20190527 true
 *
 * about menu functions
 */

#include "ui/btn.h"
#include "ui/menu.h"

#include "hw/lightsense.h"

#include "led/rgbled.h"

#include "misc/accel.h"

#include "global.h"
#include "user_config.h"

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



#define MCU_FLASH       448
#define MCU_SRAM        24+2


#define LI_ABOUT            0
#define LI_CONTACT          1
#define LI_LED_1_4          2
#define LI_LED_5_8          3
#define LI_LED_9_12         4
#define LI_ACCELEROMETER    5
#define LI_CPU_USAGE        6
#define LI_MISC_STATS       7
#define LI_ERROR_COUNTERS   8
#define LI_FONT_GLYPH_TEST  9



uint8_t font_index = 0;
uint8_t font_glyph = 0;



void menu_6_font_index(int8_t dir)
{
	font_index += dir;
	if (font_index >= (sizeof(font_table) / sizeof(font_table[0]))) {
		if (dir > 0) {
			font_index = 0;
		} else {
			font_index = (sizeof(font_table) / sizeof(font_table[0])) - 1;
		}
	}
}

void menu_6_font_glyph(int8_t dir)
{
	font_glyph += dir;
	if (font_glyph > font_table[font_index].font[FONT_CHAR_NUM_POS] - 1) {
		if (dir > 0) {
			font_glyph = 0;
		} else {
			font_glyph = font_table[font_index].font[FONT_CHAR_NUM_POS] - 1;
		}
	}
}

void menu_6_font_next(uint8_t idx)
{
    /* todo: implement button state flags
	if (btn[1].held) {
		menu_6_font_index(1);
	} else {
		menu_6_font_glyph(1);
	}
	*/
}

void menu_6_font_prev(uint8_t idx)
{
    /*
	if (btn[2].held) {
		menu_6_font_index(-1);
	} else {
		menu_6_font_glyph(-1);
	}
	*/
}

static void menu_6_accel_reset(uint8_t idx)
{
	// todo: figure out what this does
    movement_worst = 0;
}

void menu_6_btn_use()
{
	btn[1].cb_push = &menu_6_font_prev;
	btn[1].cb_hold = &menu_6_font_prev;
	btn[1].hold = 200 / HOLD_PERIOD;
	btn[1].repeat = 40 / HOLD_PERIOD;

	btn[2].cb_push = &menu_6_font_next;
	btn[2].cb_hold = &menu_6_font_next;
	btn[2].hold   = btn[1].hold;
	btn[2].repeat = btn[1].repeat;

	btn_commit_hold();
}

__HIGH_CODE
void menu_6_disp(uint8_t idx)
{
	uint8_t i;
	char txt[30];

	const uint8_t led_pos[4][2] = {
		{10, 1},
		{82, 1},
		{10, 17},
		{82, 17},		
	};

	// which item selected?
	switch (idx) {
		case LI_ABOUT: {   // about
			ssd1306fb_set_cursor(11, 0);
			ssd1306fb_draw_str(font_DSEG14_Classic_18, "GAT", 1);
			ssd1306fb_set_cursor(11, 22);
			ssd1306fb_draw_str(font_Dialog_plain_8, "Nametag", 1);

			ssd1306fb_set_cursor(64, 0);
			ssd1306fb_draw_str(font_Dialog_plain_8, "by true for", 1);

			ssd1306fb_set_cursor(64, 11);
			ssd1306fb_draw_str(font_Dialog_plain_8, "Supercon 8", 1);


			sprintf(txt, "%s", vers);
			ssd1306fb_set_cursor(62, 22);
			ssd1306fb_draw_str(font_Dialog_plain_8, "ver.", 0);
			ssd1306fb_set_cursor(78, 22);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
			

			break;
		}
		case LI_CONTACT: {   // manual
		    ssd1306fb_set_cursor(11, 0);
		    ssd1306fb_draw_str(font_Dialog_plain_8, "Manual and code at", 1);
		    ssd1306fb_set_cursor(11, 11);
		    ssd1306fb_draw_str(font_Dialog_plain_8, "basic.truecontrol.org", 1);
		    ssd1306fb_set_cursor(11, 22);
		    ssd1306fb_draw_str(font_Dialog_plain_8, "or hackaday.io / true", 0);

            break;
		}
		case LI_LED_1_4: {   // led 1-4
			ssd1306fb_set_cursor(54, 4);
			ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, "LED", 1);
			ssd1306fb_set_cursor(54, 15);
			ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, "1-4", 1);

			for (i = 0; i < 4; i++) {
				ssd1306fb_set_cursor(led_pos[i][0], led_pos[i][1]);
				sprintf(txt, "R%d h%03X", i + 1, hsv_out[rgb_map[i + 0]].h);
				ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
				sprintf(txt, "s%02X v%02X", hsv_out[rgb_map[i + 0]].s, hsv_out[rgb_map[i + 0]].v);
				oled.cursor_x = led_pos[i][0];
				oled.cursor_y += 7;
				ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
			}
			break;
		}
		case LI_LED_5_8: {   // led 5-8
			ssd1306fb_set_cursor(54, 4);
			ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, "LED", 1);
			ssd1306fb_set_cursor(54, 15);
			ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, "5-8", 1);

			for (i = 0; i < 4; i++) {
				ssd1306fb_set_cursor(led_pos[i][0], led_pos[i][1]);
				sprintf(txt, "R%d h%03X", i + 5, hsv_out[rgb_map[i + 4]].h);
				ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
				sprintf(txt, "s%02X v%02X", hsv_out[rgb_map[i + 4]].s, hsv_out[rgb_map[i + 4]].v);
				oled.cursor_x = led_pos[i][0];
				oled.cursor_y += 7;
				ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
			}
			break;
		}
		case LI_LED_9_12: {   // led 9-12
		    ssd1306fb_set_cursor(54, 4);
            ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, "LED", 1);
            ssd1306fb_set_cursor(53, 15);
            ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, "9", 1);
            ssd1306fb_set_cursor(58, 15);
            ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, "-", 1);
            ssd1306fb_set_cursor(63, 15);
            ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, "12", 1);

            for (i = 0; i < 4; i++) {
                ssd1306fb_set_cursor(led_pos[i][0], led_pos[i][1]);
                sprintf(txt, "R%1X h%03X", i + 9, hsv_out[rgb_map[i + 8]].h);
                ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
                sprintf(txt, "s%02X v%02X", hsv_out[rgb_map[i + 8]].s, hsv_out[rgb_map[i + 8]].v);
                oled.cursor_x = led_pos[i][0];
                oled.cursor_y += 7;
                ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
            }
			break;
		}
		case LI_ACCELEROMETER: {   // accelerometer
			ssd1306fb_set_cursor(10, -1);
			ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, "Accelerometer", 1);

			sprintf(txt, "X: %3d", accel.x);
			ssd1306fb_set_cursor(11, 10);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
			sprintf(txt, "Y: %3d", accel.y);
			ssd1306fb_set_cursor(11, 17);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
			sprintf(txt, "Z: %3d", accel.z);
			ssd1306fb_set_cursor(11, 24);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
			sprintf(txt, "m%i", abs(accel_get_movement()));
			ssd1306fb_set_cursor(104, 10);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
			sprintf(txt, "w%d", movement_worst);
			ssd1306fb_set_cursor(106, 17);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);

			ssd1306fb_draw_line(80, 23, 80 + (accel.x >> 1), 23 + (accel.y >> 2));

			ssd1306fb_set_color(SSD1306_STATE_INVERT_PIXEL);
			ssd1306fb_draw_circle(80 + (accel.x >> 1), 23 + (accel.y >> 2), 2);
			ssd1306fb_set_color(SSD1306_STATE_SET_PIXEL);

			break;
		}
		case LI_CPU_USAGE: {   // cpu stats
			sprintf(txt, "CPU Load: %3u%%", cpu_pct);
			ssd1306fb_set_cursor(10, -1);
			ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, txt, 1);

			sprintf(txt, "CPU  Max: %3u%%", cpu_pct_max);
			ssd1306fb_set_cursor(10, 9);
			ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, txt, 1);

			ssd1306fb_set_cursor(10, 23);
			sprintf(txt, "Up %01d:%02d:%02d", uptime_hour, uptime_min, uptime_sec);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
			break;
		}
		case LI_MISC_STATS: {   // misc stats
			ssd1306fb_set_cursor(10, -1);
			ssd1306fb_draw_str(font_Dialog_plain_8, "Light: ", 1);
			oled.cursor_x = 39;
			//sprintf(txt, "%d lo, %02d + %d", lsens_get_dark_threshold(), lsens_get_coarse(), lsens_get_fine());
			//ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
			ssd1306fb_draw_str(font_Dialog_plain_8, "not yet implemented", 0);

			ssd1306fb_set_cursor(10, 7);
			ssd1306fb_draw_str(font_Dialog_plain_8, "Temp:", 1);
			oled.cursor_x = 42;
			// todo: implement temperature sensing
			// sprintf(txt, "%d.%dC", temp_degc, temp_degc_decimal);
			ssd1306fb_draw_str(font_Dialog_plain_8, "not yet implemented", 0);
			
			oled.cursor_x = 98;
			// battery reading support is not supported on this target
			// fill this area in with something else
			// sprintf(txt, "%d.%02dV", batt_volt, batt_mv);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);

			ssd1306fb_set_cursor(10, 16);
			ssd1306fb_draw_str(font_Dialog_plain_8, "EEPROM Conf Writes: ", 0);
			sprintf(txt, "%lu", uconf.iter);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);

			ssd1306fb_set_cursor(10, 24);
			ssd1306fb_draw_str(font_Dialog_plain_8, "CH592 ", 0);
			sprintf(txt, "F%dK / R%dK", MCU_FLASH, MCU_SRAM);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);

			break;
		}
		case LI_ERROR_COUNTERS: {   // error counters
			ssd1306fb_set_cursor(10, -1);
			ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, "Error Counters", 1);

			/*
			ssd1306fb_set_cursor(10, 10);
			sprintf(txt, "i2c0: %lu  e# %02x", i2c_err_cnt[0], i2c_last_err_reason[0]);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);

			ssd1306fb_set_cursor(10, 17);
			sprintf(txt, "i2c1: %lu  e# %02x", i2c_err_cnt[1], i2c_last_err_reason[1]);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
			
			ssd1306fb_set_cursor(10, 24);
			sprintf(txt, "uart1: s%lu  i%lu", btn_short_packet_cnt, btn_invalid_packet_cnt);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);

			ssd1306fb_set_cursor(74, 10);
			sprintf(txt, "brt-pk: %04x", eyes_val_lsens);
			ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
			*/

			break;
		}
		case LI_FONT_GLYPH_TEST: {
			ssd1306fb_set_cursor(10, -1);
			ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, "Font Test", 1);

			sprintf(txt, "Index:%3u", (uint8_t)font_index);
			ssd1306fb_set_cursor(10, 9);
			ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, txt, 1);

			sprintf(txt, "Glyph:%3u", (uint8_t)(font_glyph + 0x20));
			ssd1306fb_set_cursor(10, 19);
			ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, txt, 1);

			sprintf(txt, "%c", (font_glyph + 0x20));
			ssd1306fb_draw_rect(83, 3, 116, 28);
			ssd1306fb_set_cursor(85, 5);
			ssd1306fb_draw_str(font_table[font_index].font, txt, 1);
			break;
		}
	}

	// draw extras
	menu_draw_tabs(idx);

	// buttons
	switch (idx) {
		case LI_ABOUT:
		case LI_CONTACT:
		case LI_LED_1_4:
		case LI_LED_5_8:
		case LI_LED_9_12:
		case LI_CPU_USAGE: {
			menu_btn_use_std();
			break;
		}
		case LI_ACCELEROMETER: {
			menu_btn_use_std();
			btn[2].cb_push = menu_6_accel_reset;
			break;
		}
		case LI_FONT_GLYPH_TEST: {
			menu_6_btn_use();
			menu_draw_buttons(MENU_BTNSTYLE_ABOUT, 0x0c);
			break;
		}
		default: {
			menu_btn_use_std();
			menu_draw_buttons(MENU_BTNSTYLE_ABOUT, 0x08);
			break;
		}
	}
}


