// Update 24.03.2024
// Compiler UECIDE 0.11.10

// Sketch uses 24,664 bytes of program storage space.
// Maximum is 32,256 bytes.

// Global variables use 961 bytes of dynamic memory,
// Maximum is 2,048 bytes.

#include <RTClib.h>
//#include <Adafruit_BME280.h>
#include <U8g2lib.h>

//Adafruit_BME280 bme; // I2C
//RTC_DS3231 rtc;
RTC_DS1307 rtc;
//U8G2_ST7920_128X64_1_SW_SPI u8g2(U8G2_R0, /* clock=*/ 12, /* data=*/ 11, /* CS=*/ 10, /* reset=*/ 8);
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);   // All Boards without Reset of the Display

//#define bigFont u8g2_font_profont29_tn
#define bigFont u8g2_font_osr18_tn
#define smallFont u8g2_font_6x13_tr
#define bigbigFont u8g2_font_osr29_tn

#define CITY "Karachi"
#define LATITUDE 24.860966  // Latitude of Karachi.
#define LONGITUDE 66.990501  // Longitude of Karachi.

//#define CITY "Lahore"
//#define LATITUDE 31.582045  // Latitude of Lahore.
//#define LONGITUDE 74.329376  // Longitude of Lahore.

//#define CITY "Islamabad"
//#define LATITUDE 33.738045  // Latitude of Islamabad.
//#define LONGITUDE 73.084488  // Longitude of Islamabad.

#define degRad 57.296
#define TIMEZONE +5.0 // GMT timezone of Pakistan.
#define TAU 2.0 // Correction in minutes.

//#define MASLAK "Shaafai"
//#define maslak 1.0

#define MASLAK "Hanbali"
#define maslak 2.0

const String SALAH[6] = {"-", "Fajr", "Zuhar", "Asr", "Maghrb", "Isha"};
float TSalah[5];
float TRemaining;

char L1[25], L2[25], L3[25], L4[25];

int d; //# of days from Jan 1 of current year.
float delta;  // inclination of sun in degrees.
float D;  // Used in deltaT (EoT).
float deltaT;  // equation of time EoT in minutes.
int Salah;  // Salah number, 1=Fajr, ... , 5=Isha.

float TNow;  // Current time in decimal.
int DAY, MONTH, YEAR;  // // Current date, month, year.

int Counter = 0;
bool colon = true;
bool MODE = false;

void setup() {
  // put your setup code here, to run once:
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  Serial.begin(9600);

  u8g2.begin();
  rtc.begin();
  //bme.begin(0x76);

  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));  // Set date and time of RTC at the compile time of the project.

  //rtc.adjust(DateTime(2024, 3, 25, 11, 53, 0));  // YYYY, MM, DD, hh, mm, ss

}

void loop() {
  // put your main code here, to run repeatedly:

  DateTime now = rtc.now();

  TNow = now.hour() + (now.minute() / 60.0);  // Current time in decimal.

  int hh = int(TNow);
  int mm = (TNow - hh) * 60.0;

  if (hh == 0) hh = 12;
  sprintf(L1, "%d%s%02d", hh > 12 ? hh - 12 : hh, colon ? " " : ":", mm);
  colon = !colon;

  char buf1[] = "DDD, DD MMM YYYY";
  sprintf(L2, "%s", now.toString(buf1));


  

Serial.println(Counter);


  //if ((Counter % 5) == 0) {

  //float humidity = bme.readHumidity(); // % relative humidity.
  //humidity = -0.0144 * humidity * humidity + 1.81 * humidity + 4.5; // humidity correction.
  //if (humidity > 99) humidity = 99;

  //sprintf(L3, "%dC %d%s %dmb", int(bme.readTemperature()), int(humidity), "%", int(bme.readPressure() / 100.0));
  //sprintf(L3, "%dC %d%s %dmb", int(31.45), int(52.3), "%", int(1012.6));
  //char a[5], b[5], c[7];
  //sprintf(L3, "%sC %s %smb", dtostrf(temperature, 4, 1, a), dtostrf(humidity, 4, 1, b), 37, dtostrf(pressure, 6, 1, c));

  //}


Serial.println(Counter);
Serial.println(" ");

  if ((Counter % 30) == 0) {

    DAY = now.day();
    MONTH = now.month();
    YEAR = now.year();

    d = DAY + 30.4 * (MONTH - 1);
    delta = -23.45 * cos((360.0 / 365.0) * (d + 10.0) / degRad);
    D = 6.24004077 + 0.017220197 * (365.25 * (YEAR - 2000) + d);
    deltaT = 9.863 * sin((2 * D + 3.5932) / degRad) - 7.659 * sin(D / degRad);
    TSalah[2] = 12.0 + (TIMEZONE - LONGITUDE / 15.0) - (deltaT / 60.0) + (TAU / 60.0); // time of zuhar in decimals.
    TSalah[1] = TSalah[2] - Talpha(-18.0, delta);  // time of fajr in decimals.
    //TSunrise = TSalah[2] - Talpha(-0.833, delta);  // time of sunrise in decimals.
    TSalah[3] = TSalah[2] + Talpha(acot(maslak, delta), delta);  // time of asr in decimals.
    TSalah[4] = TSalah[2] + Talpha(-0.833, delta);  // time of maghrib in decimals.
    TSalah[5] = TSalah[2] + Talpha(-18.0, delta);  // time of isha in decimals.

    Salah = 0;

    for (int N = 5; N > 0; N--) if (TSalah[N] > TNow) Salah = N;

    if (Salah == 0) {
      Salah = 1;
      TRemaining = 24.0 + TSalah[Salah] - TNow;
    }
    else TRemaining = TSalah[Salah] - TNow;

    sprintf(L4, "%s %s %s", timePrint(TSalah[Salah]).c_str(), SALAH[Salah].c_str(), timeRemaining(TRemaining).c_str());

  }

  



  if ((Counter % 3) == 0) MODE = !MODE;

  

  u8g2.firstPage();
  do {

    u8g2.setFontPosTop();

    u8g2.setDrawColor(0);
    u8g2.drawBox(0, 0, 128, 64);
    u8g2.setDrawColor(1);

    u8g2.drawFrame(0, 0, 128, 64);

    switch (MODE) {
      case (true):
        u8g2.setFont(bigFont);
        printIt(L1, 3);

        u8g2.setFont(smallFont);
        printIt(L2, 25);
        printIt(L3, 37);
        printIt(L4, 49);
        break;

      case (false):
        u8g2.setFont(bigbigFont);
        printIt(L1, 8);
        u8g2.setFont(smallFont);
        printIt(L3, 47);
        break;
    }

  } while ( u8g2.nextPage() );


  Counter++;
  delay(350);

}

float Talpha(float alpha, float delTa) {
  return acos((sin(alpha / degRad) - sin(delTa / degRad) * sin(LATITUDE / degRad)) / cos(delTa / degRad) / cos(LATITUDE / degRad)) * degRad / 15.0;
}

float acot(float n, float delTa) {
  float theeta = n + abs(tan((LATITUDE - delTa) / degRad));
  return degRad * atan(1 / theeta);
}

String timePrint(float t) {

  char s[7];

  int hh = int(t);
  int mm = (t - hh) * 60.0;

  sprintf(s, "%d:%02d%s", hh > 12 ? hh - 12 : hh, mm, hh > 11 ? "P" : "A");

  return s;
}

/*
  void printAll(void) {

  Serial.print("Date: " + String(DAY) + "." + String(MONTH) + "." + String(YEAR));
  Serial.println(", " + String(CITY));

  Serial.print("TNow: " + String(TNow) + " = ");
  timePrint(TNow);

  Serial.print("TFajr: " + String(TFajr) + " = ");
  timePrint(TFajr);

  Serial.print("TSunrise: " + String(TSunrise) + " = ");
  timePrint(TSunrise);

  Serial.print("TZuhar: " + String(TZuhar) + " = ");
  timePrint(TZuhar);

  Serial.print("TAsr: " + String(TAsr) + " = ");
  timePrint(TAsr);

  Serial.print("TMaghrib: " + String(TMaghrib) + " = ");
  timePrint(TMaghrib);

  Serial.print("TIsha: " + String(TIsha) + " = ");
  timePrint(TIsha);

  }
*/

String timeRemaining(float t) {

  char s[10];

  int hh = int(t);
  int mm = (t - hh) * 60;

  if (hh != 0 && mm != 0) sprintf(s, "%dh %dm", hh, mm);
  if (hh == 0 && mm != 0) sprintf(s, "%dm", mm);
  if (hh != 0 && mm == 0) sprintf(s, "%dh", hh);
  if (hh == 0 && mm == 0) strcpy(s, "Time");

  return s;
}

void printIt(char L[], int y) {

  u8g2.drawStr((128 - u8g2.getStrWidth(L)) / 2, y, L);

  return;
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
oled1:GND
oled1:VCC
oled1:SCL
oled1:SDA
GND5VSDASCLSQWRTCDS1307+
rtc1:GND
rtc1:5V
rtc1:SDA
rtc1:SCL
rtc1:SQW