  /*
  An example digital clock using a TFT LCD screen to show the time.
  Demonstrates use of the font printing routines. (Time updates but date does not.)

  It uses the time of compile/upload to set the time
  For a more accurate clock, it would be better to use the RTClib library.
  But this is just a demo...

  Make sure all the display driver and pin connections are correct by
  editing the User_Setup.h file in the TFT_eSPI library folder.

  #########################################################################
  ###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
  #########################################################################

  Based on clock sketch by Gilchrist 6/2/2014 1.0

  A few colour codes:

  code	color
  0x0000	Black
  0xFFFF	White
  0xBDF7	Light Gray
  0x7BEF	Dark Gray
  0xF800	Red
  0xFFE0	Yellow
  0xFBE0	Orange
  0x79E0	Brown
  0x7E0	Green
  0x7FF	Cyan
  0x1F	Blue
  0xF81F	Pink

  */
  /******************************/
  // #define TFT_CS PB12
  // #define TFT_RST PB10
  // #define TFT_DC PB1

  // #define TFT_MOSI PA7
  // #define TFT_SCLK PA5
  // #define TFT_MISO PA6

  // #define TOUCH_CS PB15
  #include <Arduino.h>
  #include <TFT_eSPI.h> // TFT 库
  #include <SPI.h>      // SPI 库
  #include "DHT.h"
  #include "Wire.h"
  #include "Adafruit_GFX.h"
  #include "Adafruit_SSD1306.h"
  #include "weather_icon.h"
  #include "stm32f1xx_hal.h"
  #include "ArduinoJson.h"


  #define DHTPIN PA1 
  #define DHTTYPE DHT11 // DHT 11


#define MAX_IMAGE_WIDTH 200 // Adjust for your images

  // 定义OLED显示屏的尺寸
  #define SCREEN_WIDTH 128 // OLED display width, in pixels
  #define SCREEN_HEIGHT 64 // OLED display height, in pixels

  #define OLED_RESET -1                                             // Reset pin # (or -1 if sharing Arduino reset pin)
  #define SCREEN_ADDRESS 0x3C                                      ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
  Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  DHT dht(DHTPIN, DHTTYPE);

  TFT_eSPI tft = TFT_eSPI(); // 创建 TFT 对象

  HardwareSerial serial1(PA10, PA9); // RX, TX
  HardwareSerial serial2(PA3, PA2);  // RX, TX

  char receivedData0[100]; // 用于存储接收到的数据
  // char receivedData[100]; // 用于存储接收到的数据
  String receivedData; // 用于存储接收到的数据
  int dataIndex = 0;      // 数据接收指针
  int braceCount = 0;     // 用于跟踪大括号的数量

  String jsonBuffer = "";      // 用于存储接收的 JSON 数据
  bool isJsonComplete = false; // 标记 JSON 是否完整

  String humidityStr = "";
  String temperatureStr = "";
  String fahrenheitStr = "";

  String data = "";

  enum weather{
      SUNNY = 1,
      CLOUDY,
      RAINY,
      SNOWY,
      WINDY,
      FOG,
      UNKNOWN
  };

  // PNG png; // PNG decoder instance

  // int16_t xpos = 100;
  // int16_t ypos = 100;


  // void pngDraw(PNGDRAW *pDraw);
  void displayData(const char *data); // 显示接收到的数据
  void displayLocalData(String data);
  // void pngDraw(PNGDRAW *pDraw);
  void serialEvent1();
  void parseJson();

  void setup()
  {

    // 初始化I²C
    Wire.begin();

    // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
    if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
    {
      Serial.println(F("SSD1306 allocation failed"));
      for (;;)
        ; // Don't proceed, loop forever
    }

    // 初始化 TFT 屏幕
    tft.init();
    tft.setRotation(2);        // 设置屏幕方向
    tft.fillScreen(TFT_WHITE); // 清屏

    dht.begin(); // 初始化 DHT 传感器
    serial1.begin(115200);
    serial2.begin(115200);


  }

  void loop()
  {
    
    float h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.readTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
    float f = dht.readTemperature(true);

    // Check if any reads failed and exit early (to try again).
    if (isnan(h) || isnan(t) || isnan(f))
    {
      Serial.println(F("Failed to read from DHT sensor!"));
      display.clearDisplay(); // 清屏
      display.setCursor(0, 0);
      display.setTextColor(SSD1306_WHITE); // Draw white text
      display.setTextSize(2);              // Normal 1:1 pixel scale
      display.println(F("Failed to read from DHT sensor!"));
      return;
    }

    // serialEvent(); // 检查串口数据
    humidityStr = String(h,2);
    temperatureStr = String(t,2);
    fahrenheitStr = String(f,2);

    serial1.print("Humidity: ");
    serial1.print(humidityStr);
    serial1.print("%\n");
    serial1.print("Temperature: ");
    serial1.print(temperatureStr);
    serial1.print("C\n");

    serial2.print("Humidity: ");
    serial2.print(humidityStr);
    serial2.print("%\n");
    serial2.print("Temperature: ");
    serial2.print(temperatureStr);
    serial2.print("C\n");

    data = "Humidity: " + humidityStr + "%\n" + "Temperature: " + temperatureStr + "C\n" + "Fahrenheit: " + fahrenheitStr + "F\n";

    serial1.print(data); // 打印接收到的数据

    display.clearDisplay();              // Clear display
    display.setTextSize(1);              // Normal 1:1 pixel scale
    display.setTextColor(SSD1306_WHITE); // Draw white text
    display.setCursor(0, 0);             // Start at top-left corner
    display.print(F("Temperature: "));
    display.print(temperatureStr);
    display.println(F("C"));
    
    display.display();
    // displayLocalData(data); // 显示接收到的数据

    // serialEvent1(); // 检查串口数据
  }

  void serialEvent(){
    // 检查是否有数据传入
    if (serial2.available())
    {
      // 从串口读取一个字符
      char incomingByte = serial2.read();
      serial1.print(incomingByte); // 打印接收到的字符

      // 如果接收到换行符或最大长度限制，则显示数据
      if (incomingByte == '\n' || dataIndex >= 100)
      {
        receivedData0[dataIndex] = '\0'; // 结束字符串
        displayData(receivedData0);      // 显示数据
        dataIndex = 0;                  // 重置接收指针
      }
      else
      {
        receivedData0[dataIndex++] = incomingByte; // 将字符存入缓冲区
      }
    }

    // int16_t rc = png.openFLASH((uint8_t *)cloudy_icon, sizeof(cloudy_icon), pngDraw);
    // if (rc == PNG_SUCCESS)
    // {
    //   Serial.printf("image specs: (%d x %d), %d bpp, pixel type: %d\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType());
    //   tft.startWrite();
    //   uint32_t dt = millis();
    //   rc = png.decode(NULL, 0);
    //   Serial.print(millis() - dt);
    //   Serial.println("ms");
    //   tft.endWrite();
    //   // png.close(); // not needed for memory->memory decode
    // }
  }

  void displayData(const char *data)
  {
    // 清除屏幕内容
    tft.fillScreen(TFT_BLACK);

    // 在屏幕上显示接收到的数据
    tft.setCursor(10, 10);                   // 设置光标位置
    tft.setTextSize(2);                      // 设置文本大小
    tft.setTextColor(TFT_YELLOW, TFT_BLACK); // 设置文本颜色
    tft.println("Received Data: ");
    tft.setCursor(10, 26);                  // 设置光标位置
    tft.setTextColor(TFT_WHITE, TFT_BLACK); // 设置文本颜色
    tft.setTextSize(3);                     // 设置文本大小
    tft.println(data);                      // 显示接收到的数据
    // tft.drawRect(10, 26, 300, 100, TFT_BLACK); // 绘制矩形框
    delay(1000); // 延时 5 秒
  }

  void displayLocalData(String data)
  {
    tft.setFreeFont(NULL); // 选择默认字体
    // 在屏幕上显示接收到的数据
    tft.setTextColor(TFT_RED, TFT_WHITE);          // 设置文本颜色
    // tft.drawRect(10, 26, 300, 100, TFT_WHITE); // 绘制矩形框
    tft.setCursor(10, 0, 1);                  // 设置光标位置
    tft.setTextSize(2);                    // 设置文本大小
    tft.println(data);                      // 
    delay(1000); // 延时 5 秒
  }

  // void pngDraw(PNGDRAW *pDraw)
  // {
  //   uint16_t lineBuffer[MAX_IMAGE_WIDTH];
  //   png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff);
  //   tft.pushImage(xpos, ypos + pDraw->y, pDraw->iWidth, 1, lineBuffer);
  // }

  // void serialEvent1()
  // {
  //   while (serial2.available() > 0)
  //   {
  //     char c = serial2.read(); // 读取单个字符
  //     jsonBuffer += c;        // 拼接到缓冲区
  //     // 读取串口数据

  //     if (c == '{')
  //     {
  //       braceCount++;
  //     }
  //     if (c == '}')
  //     {
  //       braceCount--;
  //     }
  //     if (braceCount == 0)
  //     {
  //       isJsonComplete = true;
  //     }
  //   }
  //   if (isJsonComplete)
  //   {
  //     serial1.println("Received complete JSON:");
  //     serial1.println(jsonBuffer);
  //     parseJson();
  //     // 处理完 JSON 数据后，清空缓冲区
  //     jsonBuffer = "";
  //     isJsonComplete = false;
  //   }
    
  // }

  // void parseJson()
  // {
  //   StaticJsonDocument<512> doc; // 根据你的JSON数据大小调整这个值
  //   DeserializationError error = deserializeJson(doc, jsonBuffer);
  //   if (error)
  //   {
  //     // 如果解析失败，打印错误信息
  //     serial1.printf("deserializeJson() failed: %s\n", error.c_str());
  //     return;
  //   }

  //   // 解析成功后，你可以通过doc来访问JSON中的数据
  //   const char *temperature = doc["lives"][0]["temperature"];
  //   const char *humidity = doc["lives"][0]["humidity"];
  //   const char *weather = doc["lives"][0]["weather"];
  //   const char *city = doc["lives"][0]["city"];
  //   // 根据你的JSON结构添加更多的键

  //   serial1.printf("temperature: %s\n", temperature);
  //   serial1.printf("humidity: %s\n", humidity);
  //   serial1.printf("weather: %s\n", weather);
  //   serial1.printf("city: %s\n", city);
  //   serial1.println();
  //   // 处理其他键的数据

  //   // 你可以在这里将解析得到的数据发送到TFT屏幕或其他处理
  //   tft.setCursor(10, 100, 2);
  //   tft.setTextColor(TFT_BLACK, TFT_WHITE); // 设置文本颜色
  //   tft.setTextSize(1);                     // 设置文本大小
  //   tft.println("city:" + String(city));                      // 显示城市名称
  //   tft.setCursor(10, 120, 2);
  //   tft.println("Temperature: " + String(temperature) + "C");
  //   tft.setCursor(10, 136, 2);
  //   tft.println("Humidity: " + String(humidity) + "%");
  //   tft.setCursor(10, 152, 2);
  //   tft.println("Weather: " + String(weather));
  // }