#include <LiquidCrystal.h>
#include <Button.h>


/* Display */
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

Button button1(4);  // player A button
Button button2(5);  // player B button
int iPlayerA_timer = 0;
int iPlayerB_timer = 0;
int iTotaltime = 400;
int iBarSubDivision = 0;
bool bSideSelect = true;
char output[16];
char buffer[16];
char bar[8];
unsigned long previousMillis = 0;   // var to store the last timer
const long interval = 50;
String showbar(int);   // prototype showbar
uint8_t barchar1[8] = {
  0b10000,
  0b10000,
  0b10000,
  0b10000,
  0b10000,
  0b10000,
  0b10000,
  0b10000,
};
uint8_t barchar2[8] = {
  0b11000,
  0b11000,
  0b11000,
  0b11000,
  0b11000,
  0b11000,
  0b11000,
  0b11000,
};
uint8_t barchar3[8] = {
  0b11100,
  0b11100,
  0b11100,
  0b11100,
  0b11100,
  0b11100,
  0b11100,
  0b11100,
};
uint8_t barchar4[8] = {
  0b11110,
  0b11110,
  0b11110,
  0b11110,
  0b11110,
  0b11110,
  0b11110,
  0b11110,
};
uint8_t barchar5[8] = {
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
};
uint8_t barchar6[8] = {
  0b01111,
  0b01111,
  0b01111,
  0b01111,
  0b01111,
  0b01111,
  0b01111,
  0b01111,
};
uint8_t barchar7[8] = {
  0b00111,
  0b00111,
  0b00111,
  0b00111,
  0b00111,
  0b00111,
  0b00111,
  0b00111,
};
uint8_t barchar8[8] = {
  0b00011,
  0b00011,
  0b00011,
  0b00011,
  0b00011,
  0b00011,
  0b00011,
  0b00011,
};
uint8_t barchar9[8] = {
  0b00001,
  0b00001,
  0b00001,
  0b00001,
  0b00001,
  0b00001,
  0b00001,
  0b00001,
};

// setup the LCD and all used pins
void setup() {

  Serial.begin(9600);
  Serial.println("begin");

  // set the outputs for driving leds
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  // setup the buttons
  button1.begin();
  button2.begin();
  // set up the LCD
  lcd.begin(16, 2);
  lcd.createChar(0, barchar1);  // counting up    l....
  lcd.createChar(1, barchar2);  // counting up    ll...
  lcd.createChar(2, barchar3);  // counting up    lll..
  lcd.createChar(3, barchar4);  // counting up    llll.
  lcd.createChar(4, barchar5);  // counting up    lllll

  lcd.createChar(5, barchar9);  // counting down  .llll
  lcd.createChar(6, barchar8);  // counting down  ..lll
  lcd.createChar(7, barchar7);  // counting down  ...ll
  lcd.createChar(8, barchar6);  // counting down  ....l
  lcd.clear();
  waitForReset();
}

// wait until reset is pressed
void waitForReset() {
  while (button1.released() == false) {
    delay(10);
  }
  //while(button2.released() == false){
  //  delay(10);
  //}
}

// handle the keys
void handleKeys() {
  if (button1.pressed()) {
    bSideSelect = true;

  }
  if (button2.pressed()) {
    bSideSelect = false;
  }
}


// main loop
void loop() {
  // put your main code here, to run repeatedly:
  unsigned long currentMillis = millis();
  char buffer[40];

  if ((iPlayerA_timer < iTotaltime) and (iPlayerB_timer < iTotaltime)) {
    lcd.setCursor(0, 0);
    lcd.print(showtime(iTotaltime - iPlayerA_timer));
    lcd.setCursor(0, 1);
    lcd.print(showbar(iTotaltime - iPlayerA_timer));

    lcd.setCursor(9,0);
    lcd.print(showtime(iTotaltime - iPlayerB_timer));
    lcd.setCursor(8,1);
    lcd.print(showbarreverse(iTotaltime - iPlayerB_timer));

    //sprintf(buffer,"itot=%d iPlA=%d iPlB=%d",iTotaltime,iPlayerA_timer,iPlayerB_timer);
    //Serial.println(buffer);
  }

  handleKeys();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    switch (bSideSelect) {
      case (true):
        iPlayerA_timer++;     // increase player A timer
        digitalWrite(7, LOW); // and set the LED to player A
        digitalWrite(6, HIGH);
        break;
      case (false):
        iPlayerB_timer++;     // increase player B timer
        digitalWrite(6, LOW); // and indicate player B
        digitalWrite(7, HIGH);
        break;
    }
  }
}



// convert an integer to a time string
String showtime(int n) {

  int day = n / (24 * 3600);

  n = n % (24 * 3600);
  int hour = n / 3600;

  n %= 3600;
  int minutes = n / 60 ;

  n %= 60;
  int seconds = n;
  sprintf(output, "%01u:%02u:%02u", hour, minutes, seconds);

  return (output);
}


String showbar(int n) {
  char output[16];                // an array to store the output
  int divisor = iTotaltime /8;    // calculate the amount of time in one character
  int progress = n / divisor;     // calculate the percentage of the total progress
  int remain = (n % divisor)/10;  // and calculate the rest, the procentage of the last digit
  
  for(int i=0;i<8;i++){
    if(i<progress){
      output[i]=0x04;
    } else if(i==progress){
      output[i]=remain;
    } else {
      output[i]=' ';
    }
  }
  output[8]=0;                    // add the trailing zero (end of string)
  return(output);
}

// convert a timer to a string (bar with subdivisions)
String showbar2(int n) {
  char a[16];
  int divisor = iTotaltime / 8;
  int test;
  int remain;

  dtostrf((n / divisor), 6, 3, output);
  test = n / divisor;
  remain = n % divisor;
  //Serial.print(output);
  sprintf(a, " int:%d rem:%d", test, remain);
  //Serial.println(a);

  //iCount = iTotaltime/8; //iCount is increment of one full segment
  for (int i = 0; i < 8; i++) {
    if (i < test) {
      bar[i] = 0x04;
      //Serial.print(" bar0x04");
    }
    else {
      if (remain<10){
        bar[i] = " ";
        //Serial.print(" bar0x00");
        break;
      }
      else if ((remain>9) && (remain<20)){
        bar[i] = 0x01;
        //Serial.print(" bar0x01");
      break;
      }
      else if ((remain>19) && (remain<30)){
        bar[i] = 0x02;
        //Serial.print(" bar0x02");
        break;
      }
      else if ((remain>29) && (remain<40)){
        bar[i] = 0x03;
        //Serial.print(" bar0x03");
        break;
      }
      else if ((remain>39) && (remain<50)){
        bar[i] = 0x04;
        //Serial.print(" bar0x04");
        break;
      }
    }
  }
  return (bar);
}

// convert a timer to a string (bar with subdivisions)
String showbarreverse(int n) {
  char a[16];
  int divisor = iTotaltime / 8;
  int test;
  int remain;

  dtostrf((n / divisor), 6, 3, output);
  test = n / divisor;
  remain = n % divisor;
  //Serial.print(output);
  sprintf(a, " int:%d rem:%d", test, remain);
  //Serial.println(a);

  //iCount = iTotaltime/8; //iCount is increment of one full segment
  for (int i = 0; i < 8; i++) {
    if (i < test) {
      bar[7-i] = 0x04;
      //Serial.print(" bar0x04");
    }
    else {
      if (remain<10){
        bar[7-i] = " ";
        //Serial.print(" bar0x00");
        break;
      }
      else if ((remain>9) && (remain<20)){
        bar[7-i] = 0x05;
        //Serial.print(" bar0x01");
      break;
      }
      else if ((remain>19) && (remain<30)){
        bar[7-i] = 0x06;
        //Serial.print(" bar0x02");
        break;
      }
      else if ((remain>29) && (remain<40)){
        bar[7-i] = 0x07;
        //Serial.print(" bar0x03");
        break;
      }
      else if ((remain>39) && (remain<50)){
        bar[7-i] = 0x08;
        //Serial.print(" bar0x04");
        break;
      }
    }
  }
  return (bar);
}