/*
// MAX7219_32*8_Clock.ino
// MAX7219 32*8 LED display
// Version 1.0
// Modified by 弹棉花的达叔(Bilibili & 抖音)
// Date: 2024/11/30
功能说明:
1. EPS8266连接WIFI,连接成功后显示Online字样,连接失败显示Offline字样。
2. 连接NTP服务器对时,获取当前时间,显示时间,日期,星期。
3. OTA更新。。
4. 时间,日期,星期,文字 分区轮流显示。
*/


#include <WiFi.h>   //ESP32
//#include <ESP8266WiFi.h>   //ESP8266
#include <MD_Parola.h>
//#include <MD_MAX72xx.h>
#include <SPI.h>
#include <time.h>
#include "Font.h"
//#include <ArduinoOTA.h>

//*********MAX7219**********
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW   //WOKWI仿真用这行
//#define HARDWARE_TYPE MD_MAX72XX::FC16_HW  //现实要用这行
#define MAX_DEVICES 4  //4个MAX7219模块
#define CLK_PIN   22   // 根据IO号对应
#define CS_PIN    5   //
#define DATA_PIN  23   //
MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
#define SPEED_TIME 50 // 数字越小越快,0最快
#define PAUSE_TIME  1000 

//**********  User Config Setting   ******************************
const char *ssid = "Wokwi-GUEST";   //改成自家WIFI SSID
const char *password = "";        //密码 
const char *NTPServer = "time1.aliyun.com";
const int gmtOffset_sec = 28800;  //8*3600


//********** 全局变量 **************
//char mesg[20] = "";
char szTime[9];  //时间,最大储存量9个字符
char szData[15];  //日期
char szWeek[10];  //星期
uint8_t h, m, s;
uint8_t month, day, week;
int year;


void getTime()
{
  time_t now = time(nullptr);            // 获取当前时间戳
  struct tm *timeinfo = localtime(&now); // 转为本地时间
  int f = s % 2;
   h = timeinfo->tm_hour;
   m = timeinfo->tm_min;
   s = timeinfo->tm_sec;
   week = timeinfo->tm_wday;
  sprintf(szTime, "%02d%c%02d", h,(f ? ':' : ' '), m);  
   // 将时间转换为字符串: srtftime(存储产生的结果,最大size,tm中对应的值)
  //strftime(szTime, 9, "%R", timeinfo); // R = HH:MM, X(or T) = HH:MM:SS
  strftime(szData,15, "%m-%d", timeinfo);  // yyyy-mm-dd
 // strftime(szWeek,10, "%a", timeinfo);  //A-英文全称  a-缩写
  sprintf(szWeek, "Week %d", week);
}

/*
void getData(){
  time_t now = time(nullptr);            // 获取当前时间戳
  struct tm *timeinfo = localtime(&now); // 转为本地时间
  year = timeinfo->tm_year + 1900;
  month = timeinfo->tm_mon + 1;
  day = timeinfo->tm_mday;
  strftime(szData,15, "%m-%d", timeinfo);  // yyyy-mm-dd
}

void getWeek(){
  time_t now = time(nullptr);            // 获取当前时间戳
  struct tm *timeinfo = localtime(&now); // 转为本地时间
  week = timeinfo->tm_wday;
  strftime(szWeek,10, "%a", timeinfo);  //A-英文全称  a-缩写
 // sprintf(szWeek, "Week %d", week);
}
 */

void setup()
{
  Serial.begin(115200);
  P.begin();
  P.setInvert(false); 
  P.setIntensity(4);  //亮度0-15
  P.setFont(PHP5X7);
  //P.setFont(A6X7);  
  //P.setFont(nullptr);  //默认字体
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  int attempt = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000); // 等待1秒
    Serial.println("Connecting to WiFi...");
    P.displayText("WiFi->",PA_CENTER,SPEED_TIME,3000,PA_SCROLL_UP, PA_SCROLL_DOWN);
    attempt++;
    while(!P.displayAnimate());
    if (attempt > 10) { // 最多尝试10次
      Serial.println("Failed to connect to WiFi, resetting...");
      P.displayText("Offline",PA_CENTER,SPEED_TIME,1000,PA_SCROLL_UP, PA_SCROLL_DOWN);
      delay(1000);
      ESP.restart(); // 重置ESP模块
    }
  }
  Serial.println("WiFi Connected!");
  P.displayText("Online",PA_CENTER,SPEED_TIME,1000,PA_SCROLL_UP, PA_SCROLL_DOWN);
  delay(1000);

  configTime(gmtOffset_sec, 0, NTPServer);  //NTP服务
  P.displayClear();
  // OTA设置并启动
  /*
  ArduinoOTA.setHostname("max7219_64x8_time");  //Arduino IDE--工具--端口 选择max7219_64x8_time, 不连接数据线也可更新代码
  ArduinoOTA.setPassword("12345678");
  ArduinoOTA.begin();
  */
}

void loop()
{
 // ArduinoOTA.handle();
 
  getTime();
 // getData();
  //getWeek();
  static uint8_t  display = 0;  // current display mode
   if(P.displayAnimate())
  {
    switch (display)

    {
      case 0: // 时间
         //P.setTextEffect(0, PA_SCROLL_UP, PA_SCROLL_UP);
        P.displayZoneText(0,szTime, PA_CENTER,SPEED_TIME, 0, PA_PRINT, PA_NO_EFFECT); 
        P.setFont(A6X7);

        if(s == 30){
        display++;
         P.setTextEffect(0, PA_PRINT, PA_CLOSING);
        }
        break; 
      
      
      case 1: // 日期
         //P.setTextEffect(0, PA_SCROLL_UP, PA_SCROLL_UP);
        P.displayZoneText(0,szData, PA_CENTER,SPEED_TIME, 1500, PA_SCROLL_UP, PA_SCROLL_UP);
        P.setFont(PHP5X7);
        display++;
        break;

      case 2: // 星期
        //P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
        P.displayZoneText(0,szWeek, PA_CENTER, SPEED_TIME, 1500, PA_SCROLL_UP, PA_SCROLL_UP);
        //P.setFont(PHP5X7);  //默认字体
        display ++;
        break;

      case 3:  //文字
        P.displayText( "Luck", PA_CENTER, 30, PAUSE_TIME, PA_SCROLL_LEFT, PA_WIPE_CURSOR);
        display = 0;
        break;
    }
      P.displayReset();
  }
    

      // 晚上23点到8点,亮度设置为2,其他时间亮度设置为3
  if (h >= 23 && h < 8 )
  {
    P.setIntensity(2);
  }
  else
  {
    P.setIntensity(3);
  }
}