/********************************************************
Calendar
by Chris Rouse Aug 2015
Displays a calendar for the current month
Connections:
RTC and OLED Display in parallel
Vcc to Arduino 5 volts
Gnd to Arduino Gnd
SDA to Arduino pin A4 (UNO) or Mega pin 20
SCL to Arduino A5 (UNO) or Mega pin 21
***************************************************************/

 #include "U8glib.h"
 #include <SPI.h>
 #include <Wire.h>
 #include "RTClib.h" 
 // setup u8g object
  U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);  // I2C 
 //
 RTC_DS1307 RTC;
//
  int startDay = 0; // Sunday's value is 0, Saturday is 6
  String week1 ="";
  String week2 ="";
  String week3 ="";
  String week4 ="";
  String week5 ="";
  int newWeekStart = 0; // used to show start of next week of the month
  char monthString2[37]= {"JanFebMarAprMayJunJulAugSepOctNovDec"};
  int  monthIndex2[122] ={0,3,6,9,12,15,18,21,24,27,30,33};
  char monthName2[3]="";
  int monthLength = 0;
//


void setup() {
  Serial.begin(9600);
// Setup RTC
  Wire.begin();
  RTC.begin();
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
  }
  RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
  RTC.adjust(DateTime(2023, 8, 6, 11, 57, 0));
  //
}

void loop() {
  
  u8g.firstPage();      
  do {
    drawCalendar(); 
  } while( u8g.nextPage() ); 

}
//
 void drawCalendar(){
  // display a full month on a calendar 
  u8g.setFont(u8g_font_profont12);
  u8g.drawStr(2,9, "Su Mo Tu We Th Fr Sa"); 
  // display this month
  DateTime now = RTC.now();
  //
  // get number of days in month
  if (now.month() == 1 || now.month() == 3 || now.month() == 5 || now.month() == 7 || now.month() == 8 || now.month() == 10 || now.month() == 12){
    monthLength = 31;
  }
  else {monthLength = 30;}
  if(now.month() == 2){monthLength = 28;}
  startDay = startDayOfWeek(now.year(),now.month(),1); // Sunday's value is 0
  // now build first week string
  switch (startDay){
    case 0:
      // Sunday
      week1 = " 1  2  3  4  5  6  7";
      break;
    case 1:
      // Monday
      week1 = "    1  2  3  4  5  6";
      break;      
     case 2:
      // Tuesday
      week1 = "       1  2  3  4  5";
      break;           
     case 3:
      // Wednesday
      week1 = "          1  2  3  4";
      break;  
     case 4:
      // Thursday
      week1 = "             1  2  3";
      break; 
     case 5:
      // Friday
      if(monthLength == 28 || monthLength == 30){week1 = "                1  2";}      
      if(monthLength == 31){week1 = "31              1  2";}      
      break; 
     case 6:
      // Saturday
      if(monthLength == 28){week1 = "                   1";}
      if(monthLength == 30){week1 = "30                 1";}      
      if(monthLength == 31){week1 = "30 31              1";}       
      
      break;           
  } // end first week
  newWeekStart = (7-startDay)+1;
  const char* newWeek1 = (const char*) week1.c_str();  
  u8g.drawStr(2,19,newWeek1); 
  // display week 2
  week2 ="";
  for (int f = newWeekStart; f < newWeekStart + 7; f++){
    if(f<10){
      week2 = week2 +  " " + String(f) + " ";
    }  
    else{week2 = week2 + String(f) + " ";}    
  }
  const char* newWeek2 = (const char*) week2.c_str();  
  u8g.drawStr(2,29,newWeek2); 
  // display week 3
  newWeekStart = (14-startDay)+1; 
  week3 ="";
  for (int f = newWeekStart; f < newWeekStart + 7; f++){
    if(f<10){
      week3 = week3 +  " " + String(f) + " ";
    }  
    else{week3 = week3 + String(f) + " ";}    
  }
  const char* newWeek3 = (const char*) week3.c_str();  
  u8g.drawStr(2,39,newWeek3);     
  // display week 4
  newWeekStart = (21-startDay)+1; 
  week4 ="";
  for (int f = newWeekStart; f < newWeekStart + 7; f++){
    if(f<10){
      week4 = week4 +  " " + String(f) + " ";
    }  
    else{week4 = week4 + String(f) + " ";}    
    }
   const char* newWeek4 = (const char*) week4.c_str();  
   u8g.drawStr(2,49,newWeek4); 
   // do we need a fifth week
   week5="";
   newWeekStart = (28-startDay)+1;   
   // is is February?
   if(newWeekStart > 28 && now.month() == 2){
   // do nothing unless its a leap year
     if (now.year()==(now.year()/4)*4){ // its a leap year
       week5 = "29";
     }       
   }
   else{ // print up to 30 anyway
     if(now.month() == 2){  // its February
       for (int f = newWeekStart; f < 29; f++){
         week5 = week5 + String(f) + " ";  
       }  
       // is it a leap year
       if (now.year()==(now.year()/4)*4){ // its a leap year
         week5 = week5 + "29";
       }        
     }
     else{
       for (int f = newWeekStart; f < 31; f++){
         week5 = week5 + String(f) + " ";
       }
       // are there 31 days
       if (monthLength == 31 && week5.length() <7){
         week5 = week5 + "31"; 
       } 
     } 
   }
   const char* newWeek5 = (const char*) week5.c_str();  
   u8g.drawStr(2,59,newWeek5);
   //
   // To print to Serial Monitor instead of OLED un-REM the following
   // if data is sent to Serial Monitor the OLED will not display data!!!
   /*
   Serial.println("Su Mo Tu We Th Fr Sa");
   Serial.println(week1);  
   Serial.println(week2);  
   Serial.println(week3); 
   Serial.println(week4);    
   Serial.println(week5);  
   while(1);  // wait indefinitly
   */
 } 
/********************************************************/

// calculate first day of month
int startDayOfWeek(int y, int m, int d){
  static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
  y -= m < 3;
  return (y +y/4 -y/100 + y/400 + t[m-1] + d)% 7; 
}
GND5VSDASCLSQWRTCDS1307+