# 1 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino"
# 2 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 2
# 3 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 2
# 4 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 2
# 5 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 2
# 6 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 2
# 7 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 2
# 8 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 2

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2((&u8g2_cb_r0), /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ 255); // High speed I2C

// Define pins for the 7-segment displays
const int digitPins[4] = {2, 3, 4, 5}; // Common anode pins
const int segmentPins[7] = {6, 7, 8, 9, 10, 11, 12}; // Segment pins (a, b, c, d, e, f, g)

// Define the 7-segment display patterns
const byte digitPatterns[10] = {
  252, // 0
  96, // 1
  218, // 2
  242, // 3
  102, // 4
  182, // 5
  190, // 6
  224, // 7
  254, // 8
  246 // 9
};

// Wi-Fi settings
const char* ssid = "study";
const char* password = "abcde54321";

const char* displayQueue = "dQ";
const char* jsonPoints = "points";

const int wifiLoopDelay = 5000 / ( ( TickType_t ) 1000 / ( 
# 36 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 3 4
                                1000 
# 36 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino"
                                ) );
const int displayLoopDelay = 1000 / ( ( TickType_t ) 1000 / ( 
# 37 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 3 4
                                   1000 
# 37 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino"
                                   ) );
const int httpPollDelay = 3000 / ( ( TickType_t ) 1000 / ( 
# 38 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 3 4
                                1000 
# 38 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino"
                                ) );

//FreeRTOS Queue Handles
QueueHandle_t scoreQueue;

// FreeRTOS task handles
TaskHandle_t networkTaskHandle = 
# 44 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 3 4
                                __null
# 44 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino"
                                    ;
TaskHandle_t displayTaskHandle = 
# 45 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 3 4
                                __null
# 45 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino"
                                    ;
portMUX_TYPE critical = {.owner = 0xB33FFFFF,.count = 0} /**< Spinlock initializer */;

// FreeRTOS Event Handles
EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = 0x00000001;

void networkTask(void * parameter);
void displayTask(void * parameter);

void setup() {
  try {
    // Initialize Serial port
    Serial.begin(115200);



    //start display driver  
    u8g2.begin();
    u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font




    // Initialize the pins
    // for (int i = 0; i < 4; i++) {
    //   pinMode(digitPins[i], OUTPUT);
    //   digitalWrite(digitPins[i], HIGH); // Turn off all displays initially
    // }

    // for (int i = 0; i < 7; i++) {
    //   pinMode(segmentPins[i], OUTPUT);
    //   digitalWrite(segmentPins[i], LOW); // Turn off all segments initially
    // }
    WiFi.onEvent( WiFiEvent );
    WiFi.mode(WIFI_MODE_STA);
    WiFi.disconnect();




    scoreQueue = xQueueGenericCreate( ( 2 ), ( sizeof( Scores ) ), ( ( ( uint8_t ) 0U ) ) );
    wifi_event_group = xEventGroupCreate();

    // Start the network task
    xTaskCreatePinnedToCore(networkTask, "Network Task", 20000, 
# 90 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 3 4
                                                               __null
# 90 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino"
                                                                   , 3, &networkTaskHandle, 1);

    // Start the display task
    xTaskCreatePinnedToCore(displayTask, "Display Task", 20000, 
# 93 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" 3 4
                                                               __null
# 93 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino"
                                                                   , 4, &displayTaskHandle, 1 );



    vTaskStartScheduler();
  } catch(String err){
    Serial.print("SetupError: ");
    Serial.println(err);
  }
}

void WiFiEvent(arduino_event_id_t event)
{
  switch (event) {
    case SYSTEM_EVENT_STA_CONNECTED:
      Serial.println("Connected to access point");
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      Serial.println("Disconnected from WiFi access point");
      break;
    case SYSTEM_EVENT_AP_STADISCONNECTED:
      Serial.println("WiFi client disconnected");
      break;
    default: break;
  }
}

void networkTask(void * parameter) {
  try {
    while(true){
      while ( WiFi.status() != WL_CONNECTED )
      {



        WiFi.disconnect();
        WiFi.begin( ssid, password );



        vTaskDelay( 4000 );
      }

      while (WiFi.status() != WL_CONNECTED) {
        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);



      }

      xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);




      HTTPClient http;
      const String url = "https://192.168.1.141:7005/api/score/summary";

      for (;;) {
        if(WiFi.status() != WL_CONNECTED){
          continue;
        }



        http.useHTTP10(true);
        http.begin(url.c_str());
        http.addHeader("x-api-key", "396A62D6-0192-4738-8F45-8AAF7BCFA3EC");
        int httpResponseCode = http.GET();

        DynamicJsonDocument doc(2048);
        if (httpResponseCode>0) { //if no game, what code?




          deserializeJson(doc, http.getStream());
        } else {
          Serial.print("HTTP Req Error code: ");
          Serial.println(httpResponseCode);
          vTaskDelay(httpPollDelay);
          continue;
        }
        // Parse JSON
        Scores pts;
        pts.home = doc["home"].as<int>();
        pts.away = doc["away"].as<int>();
        pts.state = doc["state"].as<String>();
# 191 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino"
        http.end();
        // Send the number to the display task
        xQueueGenericSend( ( scoreQueue ), ( &pts ), ( ( TickType_t ) 0xffffffffUL ), ( ( BaseType_t ) 0 ) );

        vTaskDelay(httpPollDelay); // Wait before fetching the next update
      }

      vTaskDelay(wifiLoopDelay);
    }
  }
  catch (String err){
    Serial.print("NetworkTaskError: ");
    Serial.println(err);
  }
}

void displayTask(void * parameter) {
  try {
    Scores matchScore;
    int wifiStateY = 10;
    int matchStateY = 35;
    int scoreY = 74-u8g2.getMaxCharHeight();
    while(true) {
      u8g2.clearBuffer(); // clear the internal memory
      int bits = (xEventGroupClearBits( wifi_event_group, 0 ));

      if (bits & CONNECTED_BIT) {



        u8g2.drawStr(0,wifiStateY,"Connected! ;)"); // write something to the internal memory
      } else {



        u8g2.drawStr(0,wifiStateY,"Not Connected! :("); // write something to the internal memory
      }

      if (xQueueReceive(scoreQueue, &matchScore, ( TickType_t ) 0xffffffffUL)) {
        // for (int i = 0; i < 4; i++) {
        //   displayNumber(i, number / (int)pow(10, 3 - i) % 10); // Display the number
        //   delay(5); // Delay to display the number
        // }
        u8g2.drawStr(0, matchStateY, matchScore.state.c_str());

        String scoreMsg = "Home " + String(matchScore.home) + " Away " + String(matchScore.away);
        u8g2.drawStr(0,scoreY, scoreMsg.c_str());
      }
      u8g2.sendBuffer(); // transfer internal memory to the display

      vTaskDelay(displayLoopDelay);
      // if (xQueueReceive(scoreQueue, &number, portMAX_DELAY)) {
      //   for (int i = 0; i < 4; i++) {
      //     displayNumber(i, number / (int)pow(10, 3 - i) % 10); // Display the number
      //     delay(5); // Delay to display the number
      //   }
      // }
    }
  } catch (String err){
    Serial.print("DisplayLoopError: ");
    Serial.println(err);
  }
}

// Function to display a number on a specific 7-segment display
void displayNumber(int display, int digitValue) {
  for (int i = 0; i < 7; i++) {
    if ((((digitPatterns[digitValue]) >> (i)) & 0x01)) {
      digitalWrite(segmentPins[i], 0x1); // Turn on the segment
    } else {
      digitalWrite(segmentPins[i], 0x0); // Turn off the segment
    }
  }

  digitalWrite(digitPins[display], 0x0); // Turn on the display
}

// String getStateString(GameState state){
//   switch(state){
//     case GameState::WaitingForStart:
//       return "Pending";
//     case GameState::FirstHalf:
//       return "First Half";
//     case GameState::SecondHalf:
//       return "Second Half";
//     case GameState::HalfTime:
//       return "Half Time";
//     case GameState::Finished:
//       return "Full Time";
//     case GameState::None:
//       return "Not Configured";
//     default:
//       "Other";
//   }
// }

void loop() {
  // Empty loop, tasks handle everything
}
