#include<string.h>
#define MAX_TASKS  5
#define debug 0

bool isReadySerialRead = false;
String strRead="";
typedef void (*TaskFunction_t)(void);
// Feladat struktúrája
typedef struct
{
  TaskFunction_t taskFunction;
  String name;
  uint32_t delays;
  uint32_t count;
  unsigned long time;
  uint8_t isActive;
} Task_t;
Task_t tasks[MAX_TASKS];
int taskSize=0;
void RTOS_Init(void) {
  for (int i = 0; i < MAX_TASKS; i++)
  {
    tasks[i].taskFunction = NULL;
    tasks[i].name="";
    tasks[i].delays=0;
    tasks[i].time=0;
    tasks[i].count=0;
    tasks[i].isActive = 0;
  }
}
void RTOS_ModTaskTime(String taskname,uint32_t time)
{
  for (int i = 0; i < MAX_TASKS; i++) {
  if(tasks[i].name==taskname)
  {
    tasks[i].delays=time;
  }
  }
}
void RTOS_ModTaskRepeatNum(String taskname,uint32_t num)
{
  for (int i = 0; i < MAX_TASKS; i++) {
  if(tasks[i].name==taskname)
  {
    tasks[i].count=num;
  }
  }
}
void RTOS_AddTask(TaskFunction_t taskFunction,String name, uint32_t delays,uint8_t count) {
  if(taskSize<MAX_TASKS)
  {
    for (int i = 0; i < MAX_TASKS; i++) {
      if (tasks[i].isActive == 0) {
          tasks[i].taskFunction = taskFunction;
          tasks[i].name=name;
          tasks[i].delays=delays;
          tasks[i].time=millis();
          tasks[i].count=count;
          tasks[i].isActive = 1;
          taskSize++;
          break;
      }
    }
  }
  else
  {
      Serial.print("MAX_TASKS véget ért, nem lehet többet hozzáadni ");
      Serial.println(MAX_TASKS);
      //taskSize++;
  }
}
void RTOS_Run(void)
{
  while (1) {
    unsigned long currenttime=millis();
    for (int i = 0; i < taskSize; i++)
    {
      if (tasks[i].isActive)
      {
        if(((currenttime-tasks[i].time)>=tasks[i].delays)&&tasks[i].count>0||tasks[i].count==-1)
        {
          tasks[i].taskFunction();
         
        if(debug)
          {  Serial.print(" task ");
          Serial.print(i);    
        Serial.print(" time:");
        Serial.println(currenttime-tasks[i].time);}
              tasks[i].time=millis();
              tasks[i].count--;
        }
        else
        {
         
        }
      }
    }
  if(Serial.available())
  {
    RTOS_ModTaskRepeatNum("task01",1);
  }
  }
}
// Példafüggvények
void Task1(void) {
   // Serial.println("Task 1 is running...");
    char c=Serial.read();
    if(c=='\n')
    {
      isReadySerialRead=true;
      RTOS_ModTaskRepeatNum("task02",1);
    }
    else
    {
    strRead+=c;
    }
    digitalWrite(3,not digitalRead(3));
}

void Task2(void) {
    if(isReadySerialRead)
{
    Serial.println("Task 2 is running...");
    Serial.println(strRead);
    isReadySerialRead=false;
    strRead="";
}  
    digitalWrite(4,not digitalRead(4));
}
void Task3(void) {
    //Serial.println("Task 3 is running...");
   //tasks[0].count=1;
   //RTOS_ModTaskRepeatNum("task01",5);
    digitalWrite(5,not digitalRead(5));
}
void Task4(void) {
    //Serial.print("Task 4 is running...\n");
    digitalWrite(6,not digitalRead(6));
}
void Task5(void) {
    //Serial.print("Task 5 is running...\n");
    digitalWrite(7,not digitalRead(7));
}
void Task6(void) {
    Serial.print("Task 6 is running...\n");
}
void Task7(void) {
    Serial.print("Task 7 is running...\n");
}
void Task8(void) {
    Serial.print("Task 8 is running...\n");
}
void Task9(void) {
    Serial.print("Task 9 is running...\n");
}
void Task10(void) {
    Serial.print("Task 10 is running...\n");
}
void Task11(void) {
    Serial.print("Task 11 is running...\n");
}
void Task12(void) {
    Serial.print("Task 12 is running...\n");
}
void setup() {
  Serial.begin(115200);
  // put your setup code here, to run once:
    for(int i=3;i<=13;i++)
    pinMode(i, OUTPUT);
    RTOS_Init();
    RTOS_AddTask(Task1,"task01",50,-1);  //10x hívódik meg
    RTOS_AddTask(Task2,"task02",20,1);  //-1 == végtelenszer hívódik meg
    RTOS_AddTask(Task3,"task03",500,-1);
    RTOS_AddTask(Task4,"task04",300,-1);
    RTOS_AddTask(Task5,"task05",350,-1);
   RTOS_AddTask(Task6,"task06",300,0);
  /*  RTOS_AddTask(Task7,1000);
    RTOS_AddTask(Task8,1000);
    RTOS_AddTask(Task9,1000);
    RTOS_AddTask(Task10,1000);
    RTOS_AddTask(Task11,1000);
    RTOS_AddTask(Task12,1000);
    */
    Serial.print("\nSizeOfTask:");
    Serial.println(taskSize);
    RTOS_Run();  // Végtelen ciklus, ami futtatja a feladatokat
}
void loop()
{
 
}