////////////////////////////////////////////////////////////////////////////////////////////////////
//ANDRUINO LIBRARY
//A.Scavuzzo
//www.andruino.it
////////////////////////////////////////////////////////////////////////////////////////////////////

void timer_CheckTimers(char *push_usr, char *arduino_name);



void timer_CheckTimers(char *push_usr, char *arduino_name) {


#if DEBUG_SERIAL_TIMER == 1
  Serial.println(F("Check timers"));
#endif

  for (int index = 0; index < MAX_TIMERS; index++) {
    //timer number -- address index
    //0: port number  -- address 0
    //1: repeat + week -- address 1 bit[6:0] S-F-T-W-T-M-S -- 7 bit (1 if is selected, 0 if is unselected)
    //2: hour -- address 2 4:0 (0-23) -- 5 bit
    //3: min -- 4 bit (0-1-2-3-4-5-6-7-8-9-10-11)(0-5-10-15-20-25-30-35-40-45-50-55)
    //4: hour STOP -- address 2 4:0 (0-23) -- 5 bit
    //5: min STOP -- 4 bit (0-1-2-3-4-5-6-7-8-9-10-11)(0-5-10-15-20-25-30-35-40-45-50-55)
    //6: PWM start value
    //7: PWM stop value
    
    uint16_t address;
    uint8_t port_number;    //255 means not used
    uint8_t week;			//S-M-T-W-T-F-S-S (0010101 means timer on S-M-W)
    uint8_t hour;
    uint8_t minutes;
    uint8_t hour_stop;
    uint8_t minutes_stop;
    uint16_t counter_sec;
    bool repeat;
    bool used;
    
    bool start_time_triggered=false;
    bool stop_time_triggered=false;

    bool both_enabled=false;
    bool start_only_enabled=false;
    bool stop_only_enabled=false;
    
    bool match_day_start=false;

    bool pwm_timer=false;
    uint8_t pwm_start_value;
    uint8_t pwm_stop_value;

    uint8_t read_array[7];
    
    address = FLA_TIMERS_ADDRESS + BYTES_FOR_EACH_TIMER * index;
    port_number = eeprom_read_byteNEW (address);      //6 bit +2 (used or unused)

#if DEBUG_SERIAL_TIMER == 1
    Serial.print(F("Timer: ")); Serial.print(index); Serial.print(F(", port_number: ")); Serial.print(port_number); Serial.print(F(", addr: ")); Serial.println(address);
#endif

    if (port_number != 255)	{		   	                            //255 means timer not used

      eeprom_read_blockNEW (read_array, address +1, sizeof(read_array));
      week = read_array[0];
      hour = read_array[1];
      minutes = read_array[2]*5;
      hour_stop = read_array[3];
      minutes_stop = read_array[4]*5;
      pwm_start_value = read_array[5];
      pwm_stop_value = read_array[6];

/*
      hour = eeprom_read_byteNEW (address + 2);                 //5 bit (bit 4:0)  //5 bit used --> 255=not used START
      minutes = (eeprom_read_byteNEW (address + 3)) * 5;        //4 bit for minutes mult by 5 (0-1-2-3-4-5-6-7-8-9-10-11)(0-5-10-15-20-25-30-35-40-45-50-55)
      hour_stop = eeprom_read_byteNEW (address + 4);            //5 bit (bit 4:0)  //5 bit used  --> 255=not used STOP
      minutes_stop = (eeprom_read_byteNEW (address + 5)) * 5;   //4 bit for minutes mult by 5 (0-1-2-3-4-5-6-7-8-9-10-11)(0-5-10-15-20-25-30-35-40-45-50-55)
      pwm_start_value = (eeprom_read_byteNEW (address + 6));   //8 bit for PWM start state timer 
      pwm_stop_value = (eeprom_read_byteNEW (address + 7));    //8 bit for PWM stop state timer 
*/

      if(pwm_start_value != 255 || pwm_stop_value != 255)      //PWM timer when start and stop are not 255
        pwm_timer = true;


      week = eeprom_read_byteNEW (address + 1);         //7 bit
      week = week & 0x7F;
      if (week > 0)
        repeat = true;
      else
        repeat = false;

      if (hour != 255 && hour_stop == 255)
        start_only_enabled = true;
      if (hour_stop != 255 && hour == 255)
        stop_only_enabled = true;
      if(hour != 255 && hour_stop != 255)
        both_enabled = true;


#if DEBUG_SERIAL_TIMER == 1
      Serial.print(F("hours_counter: ")); Serial.println(hours_counter);
      Serial.print(F("minutes_counter: ")); Serial.println(minutes_counter);
      Serial.print(F("hour start: ")); Serial.print(hour); Serial.print(F(", minute start: ")); Serial.println(minutes); 
      Serial.print(F("hour stop: ")); Serial.print(hour_stop); Serial.print(F(", minute stop: ")); Serial.println(minutes_stop); 
      Serial.print(F("pwm_timer: ")); Serial.println(pwm_timer);
      Serial.print(F("pwm_start_value: ")); Serial.print(pwm_start_value); Serial.print(F(", pwm_stop_value: ")); Serial.println(pwm_stop_value);
#endif

      //check time
      if ((minutes_counter == minutes && hours_counter == hour) &&  (both_enabled || start_only_enabled)) {
        start_time_triggered = true;
      } else if ((minutes_counter == minutes_stop && hours_counter == hour_stop) && (both_enabled || stop_only_enabled)) {
        stop_time_triggered = true;
      }

      //is high when repeat day is enabled, and when the day match with the one specified in the week register
      //match_day_start enable the day match only for start timer    
      //days_counter 0-1-2-3-4-5-6
      //index_current_day 0000001(monday) or 0000010(tuesday) or 0000100(wednesday), etc
      match_day_start = (((uint8_t)1 << days_counter) & (uint8_t)week) && repeat && start_time_triggered;


      //check if timer is reached
      //here hour and minute are matching. Note that this is executed only one time because this routine is called each 5min, so the next time the min is not more matched
      if (start_time_triggered || stop_time_triggered) {



#if DEBUG_SERIAL_TIMER == 1
        Serial.print(F("repeat: ")); Serial.print(repeat);
        Serial.print(F(", week: ")); Serial.print(week);
        Serial.print(F(", days_counter: ")); Serial.print(days_counter);
        Serial.print(F(", out: ")); Serial.println(port_number);
#endif


        short index_array;
        //get the index of the ArduinoIO array according to the port_number
        if(pwm_timer)
          index_array = json_SearchDigitalPin(sizeof(base_digital_pins_used), ArduinoIO, port_number, PWM);
        else 
          index_array = json_SearchDigitalPin(sizeof(base_digital_pins_used), ArduinoIO, port_number, OUTPUT);
          
         if (index_array < 0) {
          #if DEBUG_SERIAL_TIMER == 1
                  Serial.print(F("ERROR: index_array: ")); Serial.println(index_array);
          #endif
          return; 
         }
           

#if DEBUG_SERIAL_TIMER == 1
        Serial.print(F("pwm_timer: ")); Serial.println(pwm_timer);
        Serial.print(F("start_time_triggered: ")); Serial.println(start_time_triggered);
        Serial.print(F("stop_time_triggered: ")); Serial.println(stop_time_triggered);
        Serial.print(F("match_day_start: ")); Serial.println(match_day_start);
#endif
 
        //check if the current day is reached
        //repeat=false  -- means only one timer event
        //repeat=true  -- means that the event has to be repeat, so check the day of the week

        //enter when:
        //match day (only on start timer) repeat mode
        //repeat=false
        //stop_time_triggered ==true is used to stop the timer when repeat=true but match day is false (stop across the next days)
        if (match_day_start || repeat == false || stop_time_triggered == true)	{												//means that the timer is reached

          if(start_time_triggered) {
            if(pwm_timer)
              writePWM(ArduinoIO[index_array], pwm_start_value);      //PWM start value
            else 
              writeDig(ArduinoIO[index_array], true);                                   //activate the output
          }
          else if(stop_time_triggered) {
            if(pwm_timer)
              writePWM(ArduinoIO[index_array], pwm_stop_value);       //PWM stop value
            else 
              writeDig(ArduinoIO[index_array], false);                                  //stop the output
          }
          //ArduinoIO[index_array].time_counter = 0;
          //message when the timer set the outpit PIN

          if(start_time_triggered) 
            push_SendPush(andruino_it_ip_address, push_usr, arduino_name, "tmr", "", "", 0, index, port_number, false);    //(char *mode,byte port, byte lim,float value);
          else 
            push_SendPush(andruino_it_ip_address, push_usr, arduino_name, "tmr", "", "", 1, index, port_number, false);    //(char *mode,byte port, byte lim,float value);          
          
          //disable timer (fired) when:
          //only when timer is not repeat mode
          //only when the timer is finished
          //timer start and stop (disable)
          //timer start only (disable)
          //timer stop only (disable)
          if (repeat == false) {
            if((both_enabled && stop_time_triggered) || (start_only_enabled && start_time_triggered) || (stop_only_enabled && stop_time_triggered))
              eeprom_write_byteNEW (address, 255);                               //delete timer
#if DEBUG_SERIAL_TIMER == 1
        Serial.println(F("Timer finished"));
#endif
          }
        }
        

      }
    }
  }
}
