// The LED_BUILTIN exhibits a continuous blinking pattern
// with a frequency of 500ms in the ON state followed by 500ms in the OFF state.

#include "TCone.h"

// Define the task periodic in milliseconds
#define TASK_PERIOD 1
// Define the number of tasks
#define TASK_SIZE 3

// TaskMember declaration
// Single:
// taskMember = {duration, manualReset, enable};
// Array:
// taskMembers[N] = {
//   {duration_0, manualReset_0, enable_0},
//   {duration_1, manualReset_1, enable_1},
//   {..., ..., ...}
//   {duration_N-1, manualReset_N-1, enable_N-1},
// };
TaskMember taskMember[TASK_SIZE] = {
  {20},
  {20},
  {20}
};

// Tasks declaration
// Para:
// uint16_t period    - in milliseconds
// TaskMember *tasks  - Pointer of TaskMember
// uint16_t size      - Number of Tasks
// It is mandatory to name the TCone declaration as "Tasks". No other name should be used.
TCone Tasks(TASK_PERIOD, taskMember, TASK_SIZE);

// Define the 'buttonPins' as a constant array.
const uint8_t buttonPins[TASK_SIZE] = {A3, A2, A1};
// Define the 'ledPins' as a constant array.
const uint8_t ledPins[TASK_SIZE] = {4, 3, 2};
// Button read state
bool readState[TASK_SIZE];


void setup() {
  // Use a loop to th pin mode.
  for (uint8_t index = 0; index < TASK_SIZE; index++) {
    // Set the pin mode of "buttonPins[index]" as an input pulllup
    pinMode(buttonPins[index], INPUT_PULLUP);
    // Set the pin mode of "ledPins[index]" as an output
    pinMode(ledPins[index], OUTPUT);
  }

  // Manual reset when task completed.
  Tasks.manualReset(true);
  // It is imperative to utilize the begin() function to internally configure Timer0
  // and commence its operation.
  Tasks.begin();
}

void loop() {
  // Use a loop to read the button state
  for (uint8_t index = 0; index < TASK_SIZE; index++) {
    // If the task is completed,
    if (taskMember[index].completed) {
      // Save the previous state
      bool prevState = readState[index];
      // Read the button state
      readState[index] = digitalRead(buttonPins[index]);
      // If the previous state was true and the current state is now false,
      if (prevState & !readState[index]) {
        // Toggle the state.
        taskMember[index].state = !taskMember[index].state;
        // Write the state value to the LED_BUILTIN.
        digitalWrite(ledPins[index], taskMember[index].state);
      }
      // Manual Reset: Reset the elapsed time to zero
      // and mark the completed flag as false.
      Tasks.reset(index);
    }
  }
}