#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>

//Pinouts as mapped from the schematic
#define D0 6
#define D1 5
#define D2 9
#define D3 8
#define D4 7
#define D5 A3
#define D6 A2
#define D7 4
#define D8 3
#define D9 2
#define DP A0
#define C  A1

#define PushButtonPin 13

void display_number(const char *p); //The function that handles the displayed string and converts it to single charcaters to get displayed
void display_digit(char digit); //The final display output function

int hour_data = 0;
int minute_data = 0;
int second_data = 0;

int day_data = 0;
int month_data = 0;
int year_data = 0;

char time_data[7];
char date_data[7];

//Variables needed to make a 10 seconds delay for the display without using delay();
long start_count_millis = 0;
int maximum_millis_delay = 9700;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);

pinMode(D0, OUTPUT); digitalWrite(D0, LOW);
pinMode(D1, OUTPUT); digitalWrite(D1, LOW);
pinMode(D2, OUTPUT); digitalWrite(D2, LOW);
pinMode(D3, OUTPUT); digitalWrite(D3, LOW);
pinMode(D4, OUTPUT); digitalWrite(D4, LOW);
pinMode(D5, OUTPUT); digitalWrite(D5, LOW);
pinMode(D6, OUTPUT); digitalWrite(D6, LOW);
pinMode(D7, OUTPUT); digitalWrite(D7, LOW);
pinMode(D8, OUTPUT); digitalWrite(D8, LOW);
pinMode(D9, OUTPUT); digitalWrite(D9, LOW);
pinMode(DP, OUTPUT); digitalWrite(DP, LOW);
pinMode(C,  OUTPUT); digitalWrite(C,  LOW);

pinMode(PushButtonPin, INPUT_PULLUP);

display_digit('C'); //Clear the display before the main function starts
delay(500);
}

void loop() {
  // put your main code here, to run repeatedly:
  
// Store RTC data into variables and display them every 10 seconds
if ( (millis() - start_count_millis > maximum_millis_delay)||(millis()<=1500) ){
start_count_millis = millis();
tmElements_t tm;
  if (RTC.read(tm)) {
    hour_data = tm.Hour;
    (hour_data > 12) ? (hour_data -= 12) : (hour_data = hour_data); //comment this line to display in 24H mode
    minute_data = tm.Minute;
    second_data = tm.Second/10; //display seconds in multiples of 10
    day_data = tm.Day;
    month_data = tm.Month;
    year_data = tmYearToCalendar(tm.Year)-2000;
    
    //Format all the time collected data into a char array named (time_data) then display this array on the VFD Display
    sprintf(time_data,"%02d.%02d0%d",hour_data,minute_data,second_data);
    Serial.println(time_data);
    display_digit('C');
    display_number(time_data);

    //Format all the date collected data into a char array named (date_data) then display this array on the VFD Display when the date button is pressed
    sprintf(date_data,"%02d.%02d%02d",day_data,month_data,tmYearToCalendar(tm.Year)-2000);
    Serial.println(date_data);
  }
}

if (!digitalRead(PushButtonPin)){ //If date display button is pressed
    display_digit('C');
    display_number(date_data);
    delay(3000); //for the date data to stay on to read then return to display time data
    display_number(time_data);
}

}

void display_number(const char *p){
  while(*p!='\0')
  {
    display_digit(*p);
    p++;
  }
}

void display_digit(char digit){
  switch(digit){
    case '0': digitalWrite(D0, HIGH); delay(20); digitalWrite(D0, LOW); delay(20); break;
    case '1': digitalWrite(D1, HIGH); delay(20); digitalWrite(D1, LOW); delay(20); break;
    case '2': digitalWrite(D2, HIGH); delay(20); digitalWrite(D2, LOW); delay(20); break;
    case '3': digitalWrite(D3, HIGH); delay(20); digitalWrite(D3, LOW); delay(20); break;
    case '4': digitalWrite(D4, HIGH); delay(20); digitalWrite(D4, LOW); delay(20); break;
    case '5': digitalWrite(D5, HIGH); delay(20); digitalWrite(D5, LOW); delay(20); break;
    case '6': digitalWrite(D6, HIGH); delay(20); digitalWrite(D6, LOW); delay(20); break;
    case '7': digitalWrite(D7, HIGH); delay(20); digitalWrite(D7, LOW); delay(20); break;
    case '8': digitalWrite(D8, HIGH); delay(20); digitalWrite(D8, LOW); delay(20); break;
    case '9': digitalWrite(D9, HIGH); delay(20); digitalWrite(D9, LOW); delay(20); break;
    case '.': digitalWrite(DP, HIGH); delay(20); digitalWrite(DP, LOW); delay(20); break;
    case 'C': digitalWrite(C,  HIGH); delay(20); digitalWrite(C,  LOW); delay(20); break;
    default : digitalWrite(D0, HIGH); delay(20); digitalWrite(D0, LOW); delay(20); break;
  }
  Serial.println(digit);
}

