#include "counter.h"
#include <stdint.h>
#include <ssd1306xled.h>
#include "state.h"
#include "../buttons.h"


uint16_t lastDrawnCounter = 9999;
uint16_t counter = 0;


// Forward declarations
void drawCounter(uint16_t value);
void drawDigit(uint8_t* column, uint8_t digit);
void blankDigitColumn(uint8_t* column, uint8_t width);


void handleCounterScreen()
{
  if (button_is_pressed_or_repeated(&buttonUp))
  {
    if (counter < 999)
      counter++;
  }
  else if (button_is_pressed_or_repeated(&buttonDown))
  {
    if (counter > 0)
      counter--;
  }

  if (counter != lastDrawnCounter || getScreenInvalidated())
  {
    drawCounter(counter);
    lastDrawnCounter = counter;
  }
}


void drawCounter(uint16_t value)
{
  if (value > 999) value = 999;
  uint8_t column = DigitFullOffset;

  if (value < 10)
  {
    // Single digit, blank left and right (prevents flicker)
    blankDigitColumn(&column, SpacingLeft1);
    drawDigit(&column, value);
    blankDigitColumn(&column, SpacingRight1);
  }
  else if (value < 100)
  {
    // Two digits, similar but also blank the spacing
    blankDigitColumn(&column, SpacingLeft2);

    drawDigit(&column, value / 10);
    blankDigitColumn(&column, DigitSpacing);
    drawDigit(&column, value % 10);

    blankDigitColumn(&column, SpacingRight2);
  }
  else
  {
    // Three digits, you know the drill by now
    drawDigit(&column, value / 100);
    blankDigitColumn(&column, DigitSpacing);
    drawDigit(&column, (value % 100) / 10);
    blankDigitColumn(&column, DigitSpacing);
    drawDigit(&column, value % 10);
  }
}


void drawDigit(uint8_t* column, uint8_t digit)
{
  if (digit > 9) return;

  uint8_t yEnd = DigitPage + DigitRows;
  uint16_t bitmapOffset = digit * DigitBytesPerChar;

  for (uint8_t y = DigitPage; y < yEnd; y++)
  {
    ssd1306_setpos(*column, y);
    ssd1306_send_data_start();

    for (uint8_t x = 0; x < DigitWidth; x++)
    {
      ssd1306_send_byte(pgm_read_byte(&Digits[bitmapOffset]));
      bitmapOffset++;
    }

    ssd1306_send_data_stop();
  }

  (*column) += DigitWidth;
}


void blankDigitColumn(uint8_t* column, uint8_t width)
{
  uint8_t yEnd = DigitPage + DigitRows;
  for (uint8_t y = DigitPage; y < yEnd; y++)
  {
    ssd1306_setpos(*column, y);
    ssd1306_send_data_start();

    for (uint8_t i = 0; i < width; i++)
      ssd1306_send_byte(0);

    ssd1306_send_data_stop();
  }

  (*column) += width;
}