#include <freertos/FreeRTOS.h>
#include <freertos/task.h>


#define LED1_PIN 2
#define LED2_PIN 0
#define LED3_PIN 4

TaskHandle_t LeftToRightTask, RightToLeftTask;

SemaphoreHandle_t SequentialSemaphore;

void vLeftToRightTask(void *pvParameters) {
  while (1) {
    Serial.println("Left to Right Task is running...");
    digitalWrite(LED1_PIN, HIGH);
    vTaskDelay(pdMS_TO_TICKS(1000));
    digitalWrite(LED1_PIN, LOW);
    vTaskDelay(pdMS_TO_TICKS(1000));

    digitalWrite(LED2_PIN, HIGH);
    vTaskDelay(pdMS_TO_TICKS(500));
    digitalWrite(LED2_PIN, LOW);
    vTaskDelay(pdMS_TO_TICKS(500));

    digitalWrite(LED3_PIN, HIGH);
    vTaskDelay(pdMS_TO_TICKS(150));
    digitalWrite(LED3_PIN, LOW);
    vTaskDelay(pdMS_TO_TICKS(150));  // Total delay: 150 + 500 + 350 = 1000ms

    // Signal that the task is done
    xSemaphoreGive(SequentialSemaphore);

    // Wait for the semaphore to be taken by the other task
    xSemaphoreTake(SequentialSemaphore, portMAX_DELAY);
  }
}

void vRightToLeftTask(void *pvParameters) {
  while (1) {
    Serial.println("Right to Left Task is running...");

    digitalWrite(LED3_PIN, HIGH);
    vTaskDelay(pdMS_TO_TICKS(150));
    digitalWrite(LED3_PIN, LOW);
    vTaskDelay(pdMS_TO_TICKS(150));

    digitalWrite(LED2_PIN, HIGH);
    vTaskDelay(pdMS_TO_TICKS(500));
    digitalWrite(LED2_PIN, LOW);
    vTaskDelay(pdMS_TO_TICKS(500));

    digitalWrite(LED1_PIN, HIGH);
    vTaskDelay(pdMS_TO_TICKS(1000));
    digitalWrite(LED1_PIN, LOW);
    vTaskDelay(pdMS_TO_TICKS(1000));  // Total delay: 150 + 500 + 350 = 1000ms

    // Signal that the task is done
    xSemaphoreGive(SequentialSemaphore);

    // Wait for the semaphore to be taken by the other task
    xSemaphoreTake(SequentialSemaphore, portMAX_DELAY);
  }
}

void setup() {
  Serial.begin(115200);

  pinMode(LED1_PIN, OUTPUT);
  pinMode(LED2_PIN, OUTPUT);
  pinMode(LED3_PIN, OUTPUT);

  SequentialSemaphore = xSemaphoreCreateBinary();

  xTaskCreate(vLeftToRightTask, "LeftToRightTask", 1000, NULL, 1, &LeftToRightTask);
  xTaskCreate(vRightToLeftTask, "RightToLeftTask", 1000, NULL, 1, &RightToLeftTask);
}

void loop() {
  // Unused in FreeRTOS-based applications
}