#include <Adafruit_SSD1306.h>
#include <Wire.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// 'icons8-bitcoin-24', 24x24px
const unsigned char bitcoinIcon [] PROGMEM = {
0x00, 0x7e, 0x00, 0x03, 0xff, 0xc0, 0x07, 0x81, 0xe0, 0x0e, 0x00, 0x70, 0x18, 0x28, 0x18, 0x30, 
0x28, 0x0c, 0x70, 0xfc, 0x0e, 0x60, 0xfe, 0x06, 0x60, 0xc7, 0x06, 0xc0, 0xc3, 0x03, 0xc0, 0xc7, 
0x03, 0xc0, 0xfe, 0x03, 0xc0, 0xff, 0x03, 0xc0, 0xc3, 0x83, 0xc0, 0xc1, 0x83, 0x60, 0xc3, 0x86, 
0x60, 0xff, 0x06, 0x70, 0xfe, 0x0e, 0x30, 0x28, 0x0c, 0x18, 0x28, 0x18, 0x0e, 0x00, 0x70, 0x07, 
0x81, 0xe0, 0x03, 0xff, 0xc0, 0x00, 0x7e, 0x00
};

#define icon_height 12
#define icon_width 12

static const unsigned char PROGMEM swirl[] = {
  B00000000, B00000000,
  B00111110, B00000000,
  B01000001, B00000000,
  B10000000, B10000000,
  B10000000, B10000000,
  B10000000, B10000000,
  B10000000, B10000000,
  B10000000, B10000000,
  B10000000, B10000000,
  B01000001, B00000000,
  B00111110, B00000000,
  B00000000, B00000000,
};

static const unsigned char PROGMEM star[] = {
  B00000000, B00000000,
  B00001000, B00000000,
  B00011100, B00000000,
  B00101110, B00000000,
  B01000001, B00000000,
  B10000000, B10000000,
  B01000001, B00000000,
  B00101110, B00000000,
  B00011100, B00000000,
  B00001000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
};

static const unsigned char PROGMEM heart[] = {
  B00000000, B00000000,
  B00000000, B00000000,
  B00100010, B00000000,
  B01110111, B00000000,
  B11111111, B10000000,
  B11111111, B10000000,
  B01111110, B00000000,
  B00111100, B00000000,
  B00011000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
};

static const unsigned char PROGMEM sun[] = {
  B00000000, B00000000,
  B00100100, B00000000,
  B00100100, B00000000,
  B00011000, B00000000,
  B01011010, B10000000,
  B01011010, B10000000,
  B00011000, B00000000,
  B00100100, B00000000,
  B00100100, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
};


static const unsigned char PROGMEM smiley[] = {
  B00000000, B00000000,
  B00000000, B00000000,
  B00111100, B00000000,
  B01000010, B10000000,
  B10100101, B01000000,
  B10000001, B01000000,
  B10100101, B01000000,
  B10011001, B01000000,
  B01000010, B10000000,
  B00111100, B00000000,
  B00000000, B00000000,
  B00000000, B00000000,
};


class IncrementTimer {
  public:
    IncrementTimer();
    IncrementTimer(long g, long inc);
    void start();
    void stop();
    void refresh();
    String repr();
    String reprg();
    String reprinc();
  private:
    long _g;
    long _inc;
    long _init_inc;
    unsigned long _start;
};

IncrementTimer::IncrementTimer(){}

IncrementTimer::IncrementTimer(long g, long inc){
  _g = g * 1000;
  _inc = inc * 1000;
  _init_inc = _inc;
}

void IncrementTimer::start(){
  _start = millis();
  Serial.println(F("Starting"));
}

String IncrementTimer::repr(){
  return "G/" + String(_g / 1000) + ";inc" + (_inc / 1000);
  //Serial.print(_g / 1000);
  //Serial.print(F(";inc"));
  //Serial.println(_inc / 1000);
}
String IncrementTimer::reprg(){
  return String(_g / 1000);

}
String IncrementTimer::reprinc(){
  return String(_inc / 1000);
}

void IncrementTimer::refresh(){
  long elapsed = (millis() - _start);
  _start = millis();
  _inc -= elapsed;
  if (_inc <= 0) {
    _g += _inc;
    _inc = 0;
  }
  if (_g < 0) {
    _g = 0;
    digitalWrite(BUILTIN_LED, LOW);
  } else {
    digitalWrite(BUILTIN_LED, HIGH);
  }
}

void IncrementTimer::stop(){
  refresh();
  _g += _inc;
  _inc = _init_inc;
}

#define MAX_CARDS 5
IncrementTimer incrementTimers[MAX_CARDS];

static const unsigned char* all_icons[] = {sun, smiley, heart, star, swirl};

int active_player = 3;


void setup() {
  Serial.begin(115200);

  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);      
  display.setCursor(0,0);
  for (int i = 0; i < MAX_CARDS; i ++){
    incrementTimers[i] = IncrementTimer(10, 5);
  }
}

void loop() {
  display.clearDisplay();
  // display.drawBitmap((128/2) - (24/2), 0, bitcoinIcon, 24, 24, WHITE);
  for (int i = 0; i < MAX_CARDS; i ++){
      display.drawBitmap(0, icon_height*i, all_icons[i], icon_width, icon_height, WHITE);
      display.setCursor(icon_width, icon_height*i);
      if (i == active_player) {
        incrementTimers[i].refresh();
        display.print("<-----");
        display.setTextSize(1);
        display.setCursor(SCREEN_WIDTH/1.5, 0);
        display.print("-G-");
        display.setTextSize(2);
        display.setCursor(SCREEN_WIDTH/1.5, 10);
        display.print(incrementTimers[i].reprg());
        display.setTextSize(1);
        display.setCursor(SCREEN_WIDTH/1.5, 30);
        display.print("-INC-");
        display.setTextSize(2);
        display.setCursor(SCREEN_WIDTH/1.5, 40);
        display.print(incrementTimers[i].reprinc());
      } else {
        display.print(incrementTimers[i].repr());
      }
      display.setTextSize(1);
  }
  display.display();
  delay(1000);
}

void printCenter(const String buf, int x, int y)
{
  int16_t x1, y1;
  uint16_t w, h;
  display.getTextBounds(buf, x, y, &x1, &y1, &w, &h); //calc width of new string
  display.setCursor((x - w / 2) + (128 / 2), y);
  display.print(buf);
}
esp:0
esp:1
esp:2
esp:3
esp:4
esp:5
esp:6
esp:7
esp:8
esp:9
esp:10
esp:18
esp:19
esp:GND.1
esp:3V3.1
esp:3V3.2
esp:GND.2
esp:RST
esp:GND.3
esp:GND.4
esp:5V.1
esp:5V.2
esp:GND.5
esp:GND.6
esp:GND.7
esp:GND.8
esp:GND.9
esp:RX
esp:TX
esp:GND.10
Loading
ssd1306