#include "menu.h"
#include <stdint.h>
#include <stdlib.h>
#include <ssd1306xled.h>
#include "../../lib/ssd1306xled/font6x8.h"
#include "state.h"
#include "../buttons.h"
#include "../power.h"
#include "counter.h"


#define MenuItemCancel 0
#define MenuItemReset 1
#define MenuCount MenuItemReset + 1


uint8_t currentIndex = 0;
uint8_t lastDrawnIndex = MenuCount;


// Forward declarations
void drawMenu();
void drawMenuItem(uint8_t itemIndex, char* caption);
void selectMenuItem();
void closeMenu();

void ssd1306_string_inverted(char *s);
void ssd1306_char_inverted(char ch);



void handleMenuScreen()
{
  if (button_is_pressed_or_repeated(&buttonUp))
  {
    if (currentIndex >= MenuCount - 1)
      currentIndex = 0;
    else
      currentIndex++;
  }
  else if (button_is_pressed_or_repeated(&buttonDown))
  {
    if (currentIndex <= 0)
      currentIndex = MenuCount - 1;
    else
      currentIndex--;
  }
  else if (button_is_released(&buttonOption))
  {
    selectMenuItem();
    return;
  }


  uint8_t invalidated = getScreenInvalidated();
  if (currentIndex != lastDrawnIndex || invalidated)
  {
    if (invalidated)
      ssd1306_clear();

    drawMenu();
    lastDrawnIndex = currentIndex;
  }
}


void drawMenu()
{
  // Since there are only two items at the moment, they're always going to be
  // involved in the change, so simply repaint them.
  drawMenuItem(MenuItemCancel, "Cancel               ");
  drawMenuItem(MenuItemReset, "Reset                ");


  // Can't use sprintf because that'll use up more than the
  // space we have left on the ATTiny.
  uint8_t intPart = vcc / 1000;
  if (intPart > 9) intPart = 9;

  uint8_t floatPart = (vcc % 1000) / 10;

  char statusText[22] = "Battery: 0-00-       \0";
  itoa(intPart, &statusText[9], 10);

  if (floatPart <= 9)
    itoa(floatPart, &statusText[12], 10);
  else
    itoa(floatPart, &statusText[11], 10);

  // itoa adds a \0 character
  statusText[10] = '.';
  statusText[13] = 'v';

  ssd1306_setpos(0, 7);
  ssd1306_string(statusText);
}


void drawMenuItem(uint8_t itemIndex, char* caption)
{
  ssd1306_setpos(0, itemIndex);

  if (itemIndex == currentIndex)
    ssd1306_string_inverted(caption);
  else
    ssd1306_string(caption);
}


void selectMenuItem()
{
  switch (currentIndex)
  {
    case MenuItemReset:
      resetCounter();
      closeMenu();
      break;

    case MenuItemCancel:
      closeMenu();
      break;
  }
}


void closeMenu()
{
  // Reset everything for the next time
  currentIndex = 0;
  lastDrawnIndex = MenuCount;

  setCurrentScreen(Counter);
}



void ssd1306_string_inverted(char *s)
{
  while (*s)
  {
    ssd1306_char_inverted(*s++);
  }
}


void ssd1306_char_inverted(char ch)
{
  uint8_t c = ch - 32;
  ssd1306_send_data_start();
  for (uint8_t i = 0; i < 6; i++)
  {
    ssd1306_send_byte(~pgm_read_byte(&ssd1306xled_font6x8[c * 6 + i]));
  }
  ssd1306_send_data_stop();
}