/*
  DIY Digital Distance and Tilt Meter

  by Mr B, Soham Bhattacharta
Subcribe to my channel
https://www.youtube.com/channel/UCbUhalMDrZZtt8Z3- ILzitw?sub_confirmation=1

*/
#include "Arduino.h"

// #include "WiFi.h"


// #include <WiFiUdp.h>
// #include <NTPClient.h>
// #include "NTPClientMy.h"
// #include <TimeLib.h>
// WiFiUDP ntpUDP;
// NTPClient timeClient(ntpUDP, "asia.pool.ntp.org");

// WiFiClient client;

// String date;

#define NUM_MAX 4 //Number of MAX7219 Displays

// for ESP-01 module
//#define DIN_PIN 2 // D4
//#define CS_PIN  3 // D9/RX
//#define CLK_PIN 0 // D3

// for NodeMCU 1.0
#define DIN_PIN 4
#define CS_PIN  16
#define CLK_PIN 17


#define CLOCKVIEW    0 //basic
#define CLOCKBIG    1
#define CLOCKMED    2
#define CLOCK       3
#define DATE        4
#define DATE1       5
#define DATE2       6
#define TEMP        7
#define CLOCKBIGJMP 8

#include "fonts.h"
#include "max7219.h"


// =======================================================================
// CHANGE YOUR CONFIG HERE:
// =======================================================================
const char* ssid     = "Wokwi-GUEST";     // SSID of local network
const char* password = "";   // Password on network

#define MAX_DIGITS 16
byte dig[MAX_DIGITS]={0};
byte digold[MAX_DIGITS]={0};
byte digtrans[MAX_DIGITS]={0};
int updCnt = 0;
int atPosition = 0;
int dots = 0;
long dotTime = 0;
long clkTime = 0;

byte del=0;
int h,m,s;

int hour=5,minute=20,second=0;
int year=2024,month=3,day=28,dayOfWeek=4;


// int dx = 0;
// int dy = 0;
int alarmCnt = 0;
int pos = 8;
int cnt = -1;
int h1, h0, m1, m0, s1, s0, secFr, lastSec=-1, lastDay=-1;
int d1,d0,mn1,mn0,y_1,y_0,dw;

uint32_t startTime, diffTime, zeroTime;

int trans = 0, prevTrans = 0;
int stx=1;
int sty=1;
int st = 1;
float temp = 0;

int typewifi = 1; //1 is local, 2 is internet
bool is_Update_NTF = false; //false/true

// #include "mytimeLib.h"

// =======================================================================
const uint8_t fontIcon[] PROGMEM = {9,
8, B00111100,B01000010,B10011001,B10100001,B10100001,B10011001,B01000010,B00111100, //smile
8, B00111100,B01000010,B10010101,B10100001,B10100001,B10010101,B01000010,B00111100
};


void setup() 
{
  Serial.begin(115200);
  initMAX7219();
  sendCmdAll(CMD_SHUTDOWN,1);
  sendCmdAll(CMD_INTENSITY,0);//set brightness
  Serial.print("Connecting WiFi ");
  // WiFi.begin(ssid, password);
  // printStringWithShift("   Connect :) \\ [\|}] ",50);
  // printStringWithShiftRightToLeft("   a _ ?  ",105);
  // delay(15000);
  // while (WiFi.status() != WL_CONNECTED) {
  //   delay(500);
  //   Serial.print(".-");
  //   typewifi = 2;
  // }

  // printStringWithShift("ok",50);
  
  // printStringWithShift("Z",50);
  //clr();
  //printStringWithShift("-",50);
  // showIconHehe(113,50);
  // showIconHehe(114,50);
  // showIconHehe(115,50);
  // showIconHehe(116,50);
  // showIconHehe(117,50);
  // showIconHehe(118,50);
  // showIconHehe(119,50);

  // showIconFont(0,50, fontIcon);

  printStringWithShift("Hello",50);

  showIconFont(1,50, fontIcon);
  // printStringWithShift(" ",50);
  // printStringWithShift(" ",50);
  // printStringWithShift("-",50);

  //delay(shiftDelay);
 

  // for (int i=30+1; i>0; i--) {
  //   delay(30);
  //   scrollRight();
  //   refreshAll();
  // }

  // timeClient.begin();
  // timeClient.setTimeOffset(25200); //+7
  
  // zeroTime = millis();
  // Serial.println("");
  // Serial.print("Connected: "); Serial.println(WiFi.localIP());

  // updateTimeNTF();
}
// =======================================================================

// =======================================================================

// void showClockBig(int);

void loop()
{

  // if ((WiFi.status() == WL_CONNECTED))
  // {
  //   typewifi = 2;
  //   if(!is_Update_NTF)
  //     updateTimeNTF();
  // }else{
  //   typewifi = 1;
  // }

  // // Serial.println(second);
  // // Serial.println(dots);

  // startTime = millis();
  // updateTime();

  // h1 = hour / 10;
  // h0 = hour % 10;
  // m1 = minute / 10;
  // m0 = minute % 10;
  // s1 = second / 10;
  // s0 = second % 10;
  // d1 = day / 10;
  // d0 = day % 10;
  // mn1 = month / 10;
  // mn0 = month % 10;
  // // y_1 = (year - 2000)/10;
  // // y_0 = (year - 2000)%10;
  // y_1 = (year / 10) % 10;;
  // y_0 = year % 10;
  // dw = dayOfWeek; // dw=0..6, dayOfWeek=1..7
  // if(dw>6) dw -= 7;

  // // if (cnt < 0) cnt = second * 10;
  // // if (secFr == 0) cnt = 0;
  // // dots = (cnt % 40 < 20) ? 1 : 0;
  // dots = (second % 2 < 1) ? 1 : 0;

  
  // // if(updCnt<=0) { // every 10 scrolls, ~450s=7.5m
  // //   updCnt = 10;
  // //   Serial.println("Get dat");
  // //   printStringWithShift("   Getting dat",15);
  // //   //getWeatherData();
  // //   //getCurrencyRates();
  // //   getTime();
  // //   Serial.println("Data loaded");
  // //   clkTime = millis();
  // // }
 
  // // if(millis()-clkTime > 15000 && !del && dots) { // clock for 15s, then scrolls for about 30s
  // //   //printStringWithShift(date.c_str(),100);
  // //   //showDate1();
  // //   //showSimpleClock();
  // //   printStringWithShift("  Chau123", 15);
  // //   //printStringWithShift(currencyRates.c_str(),350);
  // //   //printStringWithShift(weatherString.c_str(),400);
  // //   updCnt--;
  // //   clkTime = millis();
  // // }
  // // if(millis()-dotTime > 500) {
  // //   dotTime = millis();
  // //   dots = !dots;
  // // }
  
  // if(millis()-clkTime > 5000) {
  //   atPosition++;
  //   clkTime = millis();
  //   if(atPosition>7){
  //     atPosition = 1;
  //   }
  // }

  // clr();
  // render(atPosition);
  // refreshAll();

 // updateTimeNTF();
  //showDate1();
}

// 4+1+4+3+4+1+4=21 + 3+1+3
// void showClock()
// {
//   if (h1 > 0) showDigit(h1, h1 == 2 ? 0 : 1, dig4x8);
//   showDigit(h0, 5, dig4x8);
//   showDigit(m1, 12, dig4x8);
//   showDigit(m0, 17, dig4x8);
//   showDigit(s1, 24, dig3x7);
//   showDigit(s0, 28, dig3x7);
//   setCol(10, dots ? 0x24 : 0);
// }

// // 5+1+5+3+5+1+5+ 1+3+1+3=33
// void showClockMed()
// {
//   if (h1 > 0) showDigit(h1, 0, dig5x8rn);
//   showDigit(h0, h1==2 ? 6 : 5, dig5x8rn); // <20h display 1 pixel earlier for better looking dots
//   showDigit(m1, 13, dig5x8rn);
//   showDigit(m0, 19, dig5x8rn);
//   showDigit(s1, 25, dig3x6);
//   showDigit(s0, 29, dig3x6);
//   setCol((hour==20) ? 12 : 11, dots ? 0x24 : 0); // 20:xx - dots 1 pixel later
// }

// //6+2+6+3+6+2+6 = 31
// void showClockBig(int jump=0)
// {
//   if(jump && !trans) {
//     dx+=stx; if(dx>25 || dx<-25) stx=-stx;
//     dy+=sty; if(dy>6 || dy<-6) sty=-sty;
//     delay(40); // ugly!
//   }
//   if (h1 > 0) showDigit(h1, h1 == 2 ? 1 : 2, dig6x8);
//   showDigit(h0, 8, dig6x8);
//   showDigit(m1, 17, dig6x8);
//   showDigit(m0, 24, dig6x8);
//   setCol(15, dots ? 0x24 : 0);
// }

// // 4+1+4+2+4+1+4+2+4+1+4 = 31
// //  [ 4. 1.16]
// void showDate()
// {
//   if(d1) showDigit(d1, 0, dig4x8);
//   showDigit(d0, 5, dig4x8);
//   if(mn1) showDigit(mn1, 11, dig4x8);
//   showDigit(mn0, 16, dig4x8);
//   showDigit(y_1, 22, dig4x8);
//   showDigit(y_0, 27, dig4x8);
//   setCol(10, 0x80);
//   setCol(21, 0x80);
// }

// //  [ 4. 1.2016]
// void showDate1()
// {
//   // int h1 = h / 10;
//   // int h0 = h % 10;
//   // int m1 = m / 10;
//   // int m0 = m % 10;
//   // int s1 = s / 10;
//   // int s0 = s % 10;

//   // int day = 4;
//   // int month = 3;
//   // int year = 2024;
//   // int dayOfWeek = 4;

//   // int d1 = day / 10;
//   // int d0 = day % 10;
//   // int mn1 = month / 10;
//   // int mn0 = month % 10;
//   // int y_1 = (year - 2000)/10;
//   // int y_0 = (year - 2000)%10;
//   // int dw = dayOfWeek; // dw=0..6, dayOfWeek=1..7
//   // if(dw>6) dw -= 7;

//   if(d1) showDigit(d1, 0, dig3x8);
//   showDigit(d0, 4, dig3x8);
//   if(mn1) showDigit(mn1, 9, dig3x8);
//   showDigit(mn0, 12, dig3x8);
//   showDigit(2, 18, dig3x8);
//   showDigit(0, 22, dig3x8);
//   showDigit(y_1, 26, dig3x8);
//   showDigit(y_0, 29, dig3x8);
//   setCol(8, 0x80);
//   setCol(16,0x80);
// }

// // 4+1+4+ 3 +4+1+4 = 21 +1 +10 =32
// //  [ 4. 1 MO]
// void showDate2()
// {
//   if(d1) showDigit(d1, 0, dig4x8);
//   showDigit(d0, 5, dig4x8);
//   if(mn1) showDigit(mn1, 11, dig4x8);
//   showDigit(mn0, 16, dig4x8);
//  showDigit(dw, 22, dweek_en);
//   // showDigit(dw, 22, dweek_pl);
//   setCol(10, 0x80);
// }

// // ----------------------------------

// float readTherm() 
// {
//   // float pad = 9960;          // balance/pad resistor value - 10k
//   // float thermr = 10000;      // thermistor nominal resistance - 10k
//   // long resist = pad*((1024.0 / analogRead(THERMISTOR_PIN)) - 1);
//   float temp = 30;
//   // temp = 1 / (0.001129148 + (0.000234125 * temp) + (0.0000000876741 * temp * temp * temp));
//   // temp -= 273.15;
//   return temp;
// }

// // ----------------------------------
// void showTemp()
// {
// //  int t = (readIntTemp() / 10000) - 2;
// //  if(t/10) showDigit(t / 10, 6, dig5x8sq);
// //  showDigit(t % 10, 12, dig5x8sq);
// //  showDigit(7, 18, dweek_pl);
//   if(secFr==0) temp = readTherm() + 0.05;
// //  Serial.println(temp);
//   if(temp>0 && temp<99) {
//     int t1=(int)temp/10;
//     int t0=(int)temp%10;
//     int tf=(temp-int(temp))*10.0;
//     if(t1) showDigit(t1, 2, dig5x8sq);
//     showDigit(t0, 8, dig5x8sq);
//     showDigit(tf, 16, dig5x8sq);
//   }
//   setCol(14, 0x80);
//   showDigit(7, 22, dweek_pl);
// }

// // =======================================================================
// // void showSpecial()
// // {
// // //day=14; month=2;
// //   int bd = isBDay();
// //   if(bd<0)
// //     showClockBig();
// //   else
// //     showString(0, specialText[bd]);
// // }

// // =======================================================================
// // void showAlarm()
// // {
// //   if (hourAlarm/10 > 0) showDigit(hourAlarm/10, 3, dig4x8);
// //   showDigit(hourAlarm%10, 8, dig4x8);
// //   showDigit(minuteAlarm/10, 15, dig4x8);
// //   showDigit(minuteAlarm%10, 20, dig4x8);
// //   setCol(13, 0x24);
// // }
// // =======================================================================
// void render(int d)
// {

//   Serial.println("at-view");
//   Serial.println(d);
//   switch(d) {
//     // case CLOCKVIEW:   showAnimClock(); break;
//     case CLOCKBIG:    showClockBig(); break;
//     // case CLOCKBIGJMP: showClockBig(1); break;//randomp pic
//     // case CLOCKBIGJMP: printStringWithShift("randomp pic hehe  ",150); refreshAllRot90(); break;//randomp pic
    
//     case CLOCKMED:    showClockMed(); break;
//     case CLOCK:       showClock(); break;
//     case DATE:        showDate(); break;
//     case DATE1:       showDate1(); break;
//     case DATE2:       showDate2(); break;
//     case TEMP:        showTemp(); break;
//     // case SPECIAL: printStringWithShift("randomp pic hehe    ",150); break;//randomp pic
//     // case SPECIAL:     showSpecial(); break;
//     // case ALARM:       showAlarm(); break;
// //    case EMPTY:    break;
//     default:          
//       showClockMed(); 
//     break;
//   }
// }
// // ----------------------------------

// void showSimpleClock()
// {
//   dx=dy=0;
//   clr();
//   showDigit(h/10,  0, dig6x8);
//   showDigit(h%10,  8, dig6x8);
//   showDigit(m/10, 17, dig6x8);
//   showDigit(m%10, 25, dig6x8);
//   showDigit(s/10, 34, dig6x8);
//   showDigit(s%10, 42, dig6x8);
//   setCol(15,dots ? B00100100 : 0);
//   setCol(32,dots ? B00100100 : 0);
//   refreshAll();
// }

// // =======================================================================

// void showAnimClock()
// {
//   byte digPos[6]={0,8,17,25,34,42};
//   int digHt = 12;
//   int num = 6; 
//   int i;
//   if(del==0) {
//     del = digHt;
//     for(i=0; i<num; i++) digold[i] = dig[i];
//     dig[0] = h/10 ? h/10 : 10;
//     dig[1] = h%10;
//     dig[2] = m/10;
//     dig[3] = m%10;
//     dig[4] = s/10;
//     dig[5] = s%10;
//     for(i=0; i<num; i++)  digtrans[i] = (dig[i]==digold[i]) ? 0 : digHt;
//   } else
//     del--;
  
//   clr();
//   for(i=0; i<num; i++) {
//     if(digtrans[i]==0) {
//       dy=0;
//       showDigit(dig[i], digPos[i], dig6x8);
//     } else {
//       dy = digHt-digtrans[i];
//       showDigit(digold[i], digPos[i], dig6x8);
//       dy = -digtrans[i];
//       showDigit(dig[i], digPos[i], dig6x8);
//       digtrans[i]--;
//     }
//   }
//   dy=0;
//   setCol(15,dots ? B00100100 : 0);
//   setCol(32,dots ? B00100100 : 0);
//   refreshAll();
//   delay(30);
// }

// // =======================================================================

// void showDigit(char ch, int col, const uint8_t *data)
// {
//   if(dy<-8 | dy>8) return;
//   int len = pgm_read_byte(data);
//   int w = pgm_read_byte(data + 1 + ch * len);
//   col += dx;
//   for (int i = 0; i < w; i++)
//     if(col+i>=0 && col+i<8*NUM_MAX) {
//       byte v = pgm_read_byte(data + 1 + ch * len + 1 + i);
//       if(!dy) scr[col + i] = v; else scr[col + i] |= dy>0 ? v>>dy : v<<-dy;
//     }
// }

// // =======================================================================



// // =======================================================================



// // =======================================================================

// // float utcOffset = 7;
// // long localEpoc = 0;
// // long localMillisAtUpdate = 0;

// // void getTime()
// // {
// //   WiFiClient client;
// //   if (!client.connect("www.google.com", 80)) {
// //     Serial.println("connection to google failed");
// //     return;
// //   }

// //   client.print(String("GET / HTTP/1.1\r\n") +
// //                String("Host: www.google.com\r\n") +
// //                String("Connection: close\r\n\r\n"));
// //   int repeatCounter = 0;
// //   while (!client.available() && repeatCounter < 10) {
// //     delay(500);
// //     //Serial.println(".");
// //     repeatCounter++;
// //   }

// //   String line;
// //   client.setNoDelay(false);
// //   while(client.connected() && client.available()) {
// //     line = client.readStringUntil('\n');
// //     line.toUpperCase();
// //     if (line.startsWith("DATE: ")) {
// //       date = "     "+line.substring(6, 22);
// //       h = line.substring(23, 25).toInt();
// //       m = line.substring(26, 28).toInt();
// //       s = line.substring(29, 31).toInt();
// //       localMillisAtUpdate = millis();
// //       localEpoc = (h * 60 * 60 + m * 60 + s);
// //     }
// //   }
// //   client.stop();
// // }

// // =======================================================================

// //update time offline from datetime exit
// void updateTime()
// {
//   diffTime = (millis() - zeroTime)/1000;
//   if(diffTime<=0) return;
//   zeroTime += diffTime*1000;
//   for(int i=0;i<diffTime;i++) {
//     second++;
//     if(second>=60) {
//       second=0;
//       minute++;
//       if(minute>=60) {
//         minute=0;
//         hour++;
//         if(hour>=24) {
//           hour=0;
//           dayOfWeek++;
//           if(dayOfWeek>7)
//             dayOfWeek=1;
//           day++;
//           if(day>31) {
//             day=1;
//             month++;
//             if(month>12) {
//               month=1;
//               year++;
//             }
//           }
//         }
//       }
//     }
//   }

//   // long curEpoch = localEpoc + ((millis() - localMillisAtUpdate) / 1000);
//   // long temp_value_2 = round(curEpoch + 3600 * utcOffset + 86400L); 
//   // long epoch = temp_value_2 % 86400L; 
//   // h = ((epoch  % 86400L) / 3600) % 24;
//   // m = (epoch % 3600) / 60;
//   // s = epoch % 60;
// }
// =======================================================================
esp:0
esp:2
esp:4
esp:5
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:21
esp:22
esp:23
esp:25
esp:26
esp:27
esp:32
esp:33
esp:34
esp:35
esp:3V3
esp:EN
esp:VP
esp:VN
esp:GND.1
esp:D2
esp:D3
esp:CMD
esp:5V
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:D1
esp:D0
esp:CLK
matrix1:V+
matrix1:GND
matrix1:DIN
matrix1:CS
matrix1:CLK
matrix1:V+.2
matrix1:GND.2
matrix1:DOUT
matrix1:CS.2
matrix1:CLK.2