#include "Wire.h"
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

// RTC module at address 0x68
#define DS1307_ADDRESS 0x68

#define PIN 3

// MATRIX DECLARATION:
// Parameter 1 = width of NeoPixel matrix
// Parameter 2 = height of matrix
// Parameter 3 = pin number (most are valid)
// Parameter 4 = matrix layout flags, add together as needed:
//   NEO_MATRIX_TOP, NEO_MATRIX_BOTTOM, NEO_MATRIX_LEFT, NEO_MATRIX_RIGHT:
//     Position of the FIRST LED in the matrix; pick two, e.g.
//     NEO_MATRIX_TOP + NEO_MATRIX_LEFT for the top-left corner.
//   NEO_MATRIX_ROWS, NEO_MATRIX_COLUMNS: LEDs are arranged in horizontal
//     rows or in vertical columns, respectively; pick one or the other.
//   NEO_MATRIX_PROGRESSIVE, NEO_MATRIX_ZIGZAG: all rows/columns proceed
//     in the same order, or alternate lines reverse direction; pick one.
//   See example below for these values in action.
// Parameter 5 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 8, PIN,
  NEO_MATRIX_TOP  + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS + NEO_MATRIX_PROGRESSIVE,
  NEO_GRB         + NEO_KHZ800);

const uint16_t colors[] = {
  matrix.Color(255, 0, 0), matrix.Color(0, 255, 0), matrix.Color(0, 0, 255)
};

uint8_t clear = 0x00;

void setup() {
  Wire.begin();
  matrix.begin();
  matrix.setTextWrap(false);
  matrix.setBrightness(40);
  matrix.setTextColor(colors[0]);
}

int x = matrix.width();
int pass = 0;

void loop() {
  // Read the values ​​(date and time) of the DS1307 module
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(clear);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ADDRESS, 0x07);

  uint8_t seconds = bcdToDec(Wire.read());
  uint8_t minutes = bcdToDec(Wire.read());
  uint8_t hours = bcdToDec(Wire.read() & 0xff);
  uint8_t wday = bcdToDec(Wire.read());
  uint8_t mday = bcdToDec(Wire.read());
  uint8_t month = bcdToDec(Wire.read());
  uint8_t year = bcdToDec(Wire.read());

  String dt = "";

  // Adds 0 (clear) if the time is less than 10
  if (hours < 10)
    dt.concat("0");

  dt.concat(hours);

  if (seconds & 1)
    dt.concat(":");
  else
    dt.concat(" ");

  // Adds 0 (clear) if minutes are less than 10
  if (minutes < 10)
    dt.concat("0");

  dt.concat(minutes);

  // Seconds
  // if (seconds < 10)
  //   dt.concat("0");
  // dt.concat(seconds);

  // Show the day of the week
  switch(wday)
  {
    case 1:dt.concat(" Sun ");
    break;
    case 2:dt.concat(" Mon ");
    break;
    case 3:dt.concat(" Tue ");
    break;
    case 4:dt.concat(" Wed ");
    break;
    case 5:dt.concat(" Thu ");
    break;
    case 6:dt.concat(" Fri ");
    break;
    case 7:dt.concat(" Sat ");
  }

  // Adds 0 (clear) if day of the month is less than 10
  if (mday < 10)
    dt.concat("0");

  dt.concat(mday);
  dt.concat("-");

  // Add 0 (clear) if month is less than 10
  if (month < 10)
    dt.concat("0");

  dt.concat(month);
  dt.concat("-");
  dt.concat(year);

  matrix.fillScreen(0);
  matrix.setCursor(x, 1);
  matrix.print(dt);

  if (--x < -104) {
    x = matrix.width();

    if (++pass >= 3)
      pass = 0;

    matrix.setTextColor(colors[pass]);
  }

  matrix.show();
  delay(100);
}

uint8_t decToBcd(uint8_t value)
{
  // Converts the decimal number to BCD
  return ((value / 10 * 16) + (value % 10));
}

uint8_t bcdToDec(uint8_t value)
{
  // Converts from BCD to decimal
  return ((value / 16 * 10) + (value % 16));
}
FPS: 0
Power: 0.00W
GND5VSDASCLSQWRTCDS1307+