/**
 * menu_radio.c: cool radio tricks
 * 2015 by true
**/

#include <pirate.h>

#include "../device/radio/nrf.h"

#include "lcd_menu.h"
#include "menu_radio.h"

  // radio comms
char comm_str[12];

  // pingpong
uint8_t comm_ping_idx;
uint8_t comm_pingpong_timeout;
uint8_t comm_pong_last_idx;
uint8_t comm_pong_timeout;

  // radio menu forward declaration
MenuItem menu_comm_pingitem;
const MenuItem menu_comm_dc23item[5];


/* special functions */
void menu_comm_dc23cmd(uint16_t id)
{
	if (id < 255) {
		// music
		nrf_tx_buf[0] = NRF_CMD_MUSICLIBRARY;
		nrf_tx_buf[1] = (id > 127) ? 22 : 23;
		if (id > 127) id -= 128;
		nrf_tx_buf[2] = id & 0xff;
		nrf_tx_buf[3] = 0;
		nrf_tx_buf[4] = 0;
		nrf_tx_buf[5] = 60000 >> 8;
		nrf_tx_buf[6] = 60000 & 0xff;
		nrf_tx_buf[7] = nrf_checksum(nrf_tx_buf, 7, 0) & 0xff;
		nRF24_packet_tx(nrf_tx_buf, NRF_PAYLOAD_LEN, 1);
	} else {
		switch (id) {
			case 301: {
				// cawks go a-flyin'
				nrf_tx_buf[0] = NRF_CMD_ANIMATION;
				nrf_tx_buf[1] = 22;
				nrf_tx_buf[2] = 0x00;
				nrf_tx_buf[3] = 'B';
				nrf_tx_buf[4] = 'K';
				nrf_tx_buf[5] = '<';
				nrf_tx_buf[6] = '3';
				nrf_tx_buf[7] = nrf_checksum(nrf_tx_buf, 7, 0) & 0xff;
				nRF24_packet_tx(nrf_tx_buf, NRF_PAYLOAD_LEN, 1);
				break;
			}
			case 401: {
				// name auto-tx mode, timeout in minutes
				dc23_nametx++;
				dc23_nametx %= 16;
				break;
			}
		}
	}
}

/* external program functions */
char * menu_comm_disp(uint16_t id)
{
	switch (id) {
		case COMM_TEST_PING: {
			if (!comm_pingpong_timeout) {
				// set our timeout to start this process again
				comm_pingpong_timeout = 100;

				// increment our ping output index
				comm_ping_idx++;
				if (comm_ping_idx == 0) comm_ping_idx++;

				// and build and send a ping command packet
				// 1 byte command, 1 byte class/sub, 1 byte byte index, 4 bytes data, 1 byte checksum
				nrf_tx_buf[0] = NRF_CMD_PING;
				nrf_tx_buf[1] = 22;
				nrf_tx_buf[2] = comm_ping_idx;
				nrf_tx_buf[3] = nrf_tx_buf[4] = nrf_tx_buf[5] = nrf_tx_buf[6] = 0;
				nrf_tx_buf[7] = nrf_checksum(nrf_tx_buf, 7, 0) & 0xff;
				nRF24_packet_tx(nrf_tx_buf, NRF_PAYLOAD_LEN, 1);
			} else {
				comm_pingpong_timeout--;
			}

			// show our address and index on the screen
			strcpy(comm_str, pirate_itoa(nrf_myaddr, 16, 2));
			strcat(comm_str, pirate_itoa(comm_ping_idx, 16, 2));

			// fix up then return
			if (comm_str[0] == 0x00 || comm_str[0] == 0x20) comm_str[0] = 0x30;
			if (comm_str[2] == 0x00 || comm_str[2] == 0x20) comm_str[2] = 0x30;
			comm_str[4] = 0;
			return comm_str;
		}
		case COMM_TEST_PONG: {
			if (!comm_pingpong_timeout) {
				// set our timeout to start this process again
				comm_pingpong_timeout = 25;

				// clear ping receipt variables
				if (nrf_last_ping_idx) {
					// mismatch or unset?
					if ((nrf_last_ping_idx != comm_pong_last_idx) || (comm_pong_last_idx == 0)) {
						// ok, then start over
						comm_pong_timeout = 6;
						comm_pong_last_idx = nrf_last_ping_idx;
					} else if (!comm_pong_timeout) {
						nrf_last_ping_idx = comm_pong_last_idx = 0;
					} else {
						comm_pong_timeout--;
					}
				}
			} else {
				comm_pingpong_timeout--;
			}

			if (!nrf_last_ping_idx) {
				return "----";
			} else {
				// show received address and index on the screen
				strcpy(comm_str, pirate_itoa(nrf_last_ping_id, 16, 2));
				strcat(comm_str, pirate_itoa(nrf_last_ping_idx, 16, 2));

				// fix up then return
				if (comm_str[0] == 0x00 || comm_str[0] == 0x20) comm_str[0] = 0x30;
				if (comm_str[2] == 0x00 || comm_str[2] == 0x20) comm_str[2] = 0x30;
				comm_str[4] = 0;
				return comm_str;
			}
		}

		case COMM_RADIOSTATUS: { 	// radio detected?
			if (nrf_detected) return "Radio OK";
			else              return "No Radio";
		}

		case COMM_DC23NAMETX: {
			strncpy(comm_str, pirate_itoa(dc23_nametx, 10, 2), 2);
			comm_str[8] = 0;
			return comm_str;
		}
	}

	return "";
}


/* menu construction */
  // main menu
const MenuData menu_comm_rdata[] = {
	{"DC22Page",        NULL,                0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0},
	{"DC23Page",        NULL,                0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0},
	{"DC23Cmds",        NULL,                0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0},
	{"Ping",  menu_comm_disp,   COMM_TEST_PING, 0, LCD_DEF_SPACING,                 100,                100, NULL, 0},
	{"Pong",  menu_comm_disp,   COMM_TEST_PONG, 0, LCD_DEF_SPACING,                 100,                100, NULL, 0},
	{"",      menu_comm_disp, COMM_RADIOSTATUS, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0} 	// radio-detect
};
const MenuItem menu_comm_ritem[] = {
	{&menu_ritem[LCD_MENU_ROOT_COMMS],                   0, &menu_comm_ritem[1],                   NULL, &menu_comm_rdata[0]},
	{&menu_ritem[LCD_MENU_ROOT_COMMS], &menu_comm_ritem[0], &menu_comm_ritem[2],                   NULL, &menu_comm_rdata[1]},
	{&menu_ritem[LCD_MENU_ROOT_COMMS], &menu_comm_ritem[1], &menu_comm_ritem[3], &menu_comm_dc23item[0], &menu_comm_rdata[2]},
	{&menu_ritem[LCD_MENU_ROOT_COMMS], &menu_comm_ritem[2], &menu_comm_ritem[4],                   NULL, &menu_comm_rdata[3]},
	{&menu_ritem[LCD_MENU_ROOT_COMMS], &menu_comm_ritem[3], &menu_comm_ritem[5],                   NULL, &menu_comm_rdata[4]},
	{&menu_ritem[LCD_MENU_ROOT_COMMS], &menu_comm_ritem[4],                   0,                   NULL, &menu_comm_rdata[5]}
};

  // pinger
const MenuData menu_comm_pingdata = {"", NULL, 0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0};

  // dc23 stuff
const MenuData menu_comm_dc23data[5] = {
	{"S:URAPr8",         NULL,               0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, menu_comm_dc23cmd,   0},
	{"M:URAPrL",         NULL,               0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, menu_comm_dc23cmd, 129},
	{"S:PwrRgr",         NULL,               0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, menu_comm_dc23cmd,   2},
	{"CawkSpam",         NULL,               0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, menu_comm_dc23cmd, 301},
	{"NameTx", menu_comm_disp, COMM_DC23NAMETX, 0, LCD_DEF_SPACING,                  10,                 10, menu_comm_dc23cmd, 401},
};
const MenuItem menu_comm_dc23item[5] = {
	{&menu_comm_ritem[2],                      0, &menu_comm_dc23item[1], 0, &menu_comm_dc23data[0]},
	{&menu_comm_ritem[2], &menu_comm_dc23item[0], &menu_comm_dc23item[2], 0, &menu_comm_dc23data[1]},
	{&menu_comm_ritem[2], &menu_comm_dc23item[1], &menu_comm_dc23item[3], 0, &menu_comm_dc23data[2]},
	{&menu_comm_ritem[2], &menu_comm_dc23item[2], &menu_comm_dc23item[4], 0, &menu_comm_dc23data[3]},
	{&menu_comm_ritem[2], &menu_comm_dc23item[3],                      0, 0, &menu_comm_dc23data[4]},
};
