#include "leds.h"
#include <stdint.h>
#include <utils.h>
#include <hal_gpio.h>

const static led_t leds_data[] = {
  {PIN_LEDS4, PIN_LEDS2},
  {PIN_LEDS2, PIN_LEDS4},
  {PIN_LEDS1, PIN_LEDS4},
  {PIN_LEDS4, PIN_LEDS1},
  {PIN_LEDS2, PIN_LEDS1},
  {PIN_LEDS1, PIN_LEDS2},
  {PIN_LEDS3, PIN_LEDS2},
  {PIN_LEDS2, PIN_LEDS3},
  {PIN_LEDS1, PIN_LEDS3},
  {PIN_LEDS3, PIN_LEDS1},
  {PIN_LEDS3, PIN_LEDS4},
  {PIN_LEDS4, PIN_LEDS3}
};

static uint8_t leds_state[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 

inline void leds_turn_on(uint8_t pos) {
  leds_state[pos % 12] = 1;
}

inline void leds_turn_off(uint8_t pos) {
  leds_state[pos % 12] = 0;
}

void leds_toggle(uint8_t pos) {
  leds_state[pos % 12] = !leds_state[pos % 12];
}

void leds_reset() {
  // all pins as inputs
  gpio_set_pin_direction(PIN_LEDS1, GPIO_DIRECTION_IN);
  gpio_set_pin_direction(PIN_LEDS2, GPIO_DIRECTION_IN);
  gpio_set_pin_direction(PIN_LEDS3, GPIO_DIRECTION_IN);
  gpio_set_pin_direction(PIN_LEDS4, GPIO_DIRECTION_IN);
  // all pins on one level
  gpio_set_pin_level(PIN_LEDS1, 0);
  gpio_set_pin_level(PIN_LEDS2, 0);
  gpio_set_pin_level(PIN_LEDS3, 0);
  gpio_set_pin_level(PIN_LEDS4, 0);
}

void leds_set_pins(led_t l) {
  gpio_set_pin_direction(l.pin_high, GPIO_DIRECTION_OUT);
  gpio_set_pin_direction(l.pin_low, GPIO_DIRECTION_OUT);
  gpio_set_pin_level(l.pin_high, 1);
  gpio_set_pin_level(l.pin_low, 0);
}

void leds_draw() {
  int i;
  for (i = 0; i < ARRAY_SIZE(leds_data); i++) {
    leds_reset();
    // check if led needs to be lit
    if (leds_state[i]) {
      leds_set_pins(leds_data[i]);
    }
  }
}
