#include <TFT.h> // Hardware-specific library
#include <SPI.h>

#define CS   10
#define DC   9
#define RESET  5

TFT myScreen = TFT(CS, DC, RESET);

const int relay_pin = 6;  // nastavení pinu relé
const int button_REL_pin = 7;  //nastavení pinu tlačítka relé
const int button_ENTER_pin = 4;  //nastavení pinu tlačítka ENTER
const int button_MINUS_pin = 3;  //nastavení pinu tlačítka Mínus
const int button_PLUS_pin = 2;  //nastavení pinu tlačítka PLUS
const int breath_pin = 8 ;  //nastavení pinu vstupu z optopřevodníku ze simulátoru dýchání



int switch_REL_state=0; //nastavení počátečního stavu proměnné tlačítka relé
int switch_REL_state_last = LOW;
int relay_state = HIGH;
int last_relay_state = LOW;
long casLastSwitch_REL=0;
long casLastSwitchON=0;
int button_REL_ON=LOW;

int switch_ENTER_state=0; //nastavení počátečního stavu proměnné tlačítka ENTER
int switch_ENTER_state_last = LOW;
long casLastSwitch_ENTER=0;


int switch_MINUS_state=0; //nastavení počátečního stavu proměnné tlačítka Mínus
int switch_MINUS_state_last = LOW;
long casLastSwitch_ON_MINUS=0;
long casLastSwitch_OFF_MINUS=0;
boolean ignoreUp_MINUS = false; // whether to ignore the button release because the click+hold was triggered

int switch_PLUS_state=0; //nastavení počátečního stavu proměnné tlačítka PLUS
int switch_PLUS_state_last = LOW;
long casLastSwitch_ON_PLUS=0;
long casLastSwitch_OFF_PLUS=0;
boolean ignoreUp_PLUS = false; // whether to ignore the button release because the click+hold was triggered



int breath_state=1;
int breath_state_last=1;
long breath_time=0;
long last_breath_time=0;
int breath_delay=0;
int last_breath_delay=0;

long nebulization_start_time=0;
long duration=0; //Duration of nebulization
long last_duration=0;
long last_time=0;
long debounce= 20; // ms debounce period to prevent flickering when pressing or releasing the button
long holdTime=300;



void setup() {
  myScreen.begin();  // inicializace displeje
  myScreen.background(0,0,0); // clear the screen
  myScreen.setRotation(2); //otočí dislpej o 90°
  Serial.begin(9600);
  pinMode(button_REL_pin, INPUT);  // nastavení pinu tlačítka jako vstup
  pinMode(relay_pin, OUTPUT); //nastavení pinu relé jako výstup
  pinMode(breath_pin, INPUT_PULLUP);
  digitalWrite(relay_pin, relay_state);

  //Text který se nemění
  myScreen.setCursor(0, 0);  // set the cursor to column X, line Y 
  myScreen.print("Actual time:"); // time Actual
  myScreen.setCursor(0, 24);
  myScreen.print("Last breath start:");  //Time Last breath start
  myScreen.setCursor(0, 50);
  myScreen.print("Nebulization delay:");  //Delay
  myScreen.setCursor(0, 76);
  myScreen.print("Nebulization duration:"); //Duration
  myScreen.setCursor(0, 102);
  myScreen.print("Relay state:"); //stav relé
  
}


void button_REL_action(){
  switch_REL_state=digitalRead(button_REL_pin); //  vyčte stav tlačítka relé
  
  if (millis()>=casLastSwitch_REL+100 && switch_REL_state != switch_REL_state_last){   //provede dále pokud od posledního zmáčknutí tlačítka uběhlo alespoň....ms a změnil se stav tlačítka 
    if (switch_REL_state == HIGH && relay_state == HIGH) {
        relay_state=LOW;  //zapne relé
        button_REL_ON=HIGH; //zapnuto tlačítkem
        casLastSwitchON=millis();
    }   else if (switch_REL_state == HIGH && relay_state == LOW) {
        relay_state=HIGH; //vypne relé
        button_REL_ON=LOW;  //vypnuto tlačítkem
        }
    casLastSwitch_REL=millis();
    switch_REL_state_last=switch_REL_state;
  }
  digitalWrite(relay_pin, relay_state);
}


void button_PLUS_action(){
  switch_PLUS_state=digitalRead(button_PLUS_pin); //  vyčte stav tlačítka plus
  // Test for button pressed and store the down time
  if (switch_PLUS_state == HIGH && switch_PLUS_state_last == LOW && (millis() - casLastSwitch_OFF_PLUS) > debounce){
    casLastSwitch_ON_PLUS = millis();
    }
  // Test for button release and store the up time
  if (switch_PLUS_state == LOW && switch_PLUS_state_last == HIGH && (millis() - casLastSwitch_ON_PLUS) > debounce){
    if (ignoreUp_PLUS == false){
      breath_delay=breath_delay +1;
      if(breath_delay>2000){
        breath_delay=2000;
        }    
      }    
    else ignoreUp_PLUS = false;
    casLastSwitch_OFF_PLUS = millis();
    }
  // Test for button held down for longer than the hold time
  if (switch_PLUS_state == HIGH && (millis() - casLastSwitch_ON_PLUS) > holdTime){
    breath_delay=breath_delay +20;
      if(breath_delay>2000){
        breath_delay=2000;
        }    
    ignoreUp_PLUS = true;
    casLastSwitch_ON_PLUS = millis();
    }
  switch_PLUS_state_last=switch_PLUS_state;
}
  



void button_MINUS_action(){
  switch_MINUS_state=digitalRead(button_MINUS_pin); //  vyčte stav tlačítka plus
  // Test for button pressed and store the down time
  if (switch_MINUS_state == HIGH && switch_MINUS_state_last == LOW && (millis() - casLastSwitch_OFF_MINUS) > debounce){
    casLastSwitch_ON_MINUS = millis();
    }
  // Test for button release and store the up time
  if (switch_MINUS_state == LOW && switch_MINUS_state_last == HIGH && (millis() - casLastSwitch_ON_MINUS) > debounce){
    if (ignoreUp_MINUS == false){
      breath_delay=breath_delay -1;
      if(breath_delay<0){
        breath_delay=0;
        }    
      }    
    else ignoreUp_MINUS = false;
    casLastSwitch_OFF_MINUS = millis();
    }
  // Test for button held down for longer than the hold time
  if (switch_MINUS_state == HIGH && (millis() - casLastSwitch_ON_MINUS) > holdTime){
    breath_delay=breath_delay -20;
      if(breath_delay<0){
        breath_delay=0;
        }       
    ignoreUp_MINUS = true;
    casLastSwitch_ON_MINUS = millis();
    }
  switch_MINUS_state_last=switch_MINUS_state;
}
 
//  if (switch_PLUS_state == HIGH && breath_delay<=2000){   // && millis()>=casLastSwitch_ON_PLUS+250     provede dále pokud od posledního zmáčknutí tlačítka uběhlo alespoň....ms a 
//     
//     if (switch_PLUS_state != switch_PLUS_state_last && millis() <= casLastSwitch_ON_PLUS+1500){
//          breath_delay=breath_delay +1;
////          cas_last_count=
//          Serial.print("+1N ");     
//        }
//     if (switch_PLUS_state == switch_PLUS_state_last && millis() <= casLastSwitch_ON_PLUS+1500){
//          breath_delay=breath_delay +1;
//          Serial.print("+1 ");
//        }  
//     if (switch_PLUS_state == switch_PLUS_state_last && casLastSwitch_ON_PLUS+1500 < millis() && millis() <= casLastSwitch_ON_PLUS+2500){
//          breath_delay=breath_delay +5;
//          Serial.print("+5 ");
//        }     
//     if (switch_PLUS_state == switch_PLUS_state_last && millis() > casLastSwitch_ON_PLUS+2500){
//          breath_delay=breath_delay +10;
//          Serial.print("+10 ");
//        }          
//     if (switch_PLUS_state_last!=switch_PLUS_state) { 
//          casLastSwitch_ON_PLUS=millis();
////          Serial.print("nový čas ");
//        }
//     if(breath_delay>2000){
//      breath_delay=2000;
//      }   
//     }
//  switch_PLUS_state_last=switch_PLUS_state;




void breath_action(){
    breath_state=digitalRead(breath_pin);

  if (breath_state==LOW && breath_state != breath_state_last){  
    breath_time=millis();
    }
  breath_state_last=breath_state;
}

    
void loop(){
  breath_action();
  button_REL_action();
  button_PLUS_action();
  button_MINUS_action();
  
//  Serial.print(switch_PLUS_state);
//  Serial.print("; ");
  Serial.print("Delay: ");
  Serial.println(breath_delay);
//  Serial.print("; ");
//  Serial.print(casLastSwitch_PLUS);
//  Serial.print("; ");
//  Serial.println(millis());
  
  nebulization_start_time = breath_time + breath_delay;

  if(button_REL_ON==LOW){ //pokud nebylo relé zapnuto tlačítkem může relé ovládat simulátor
    if (breath_state==LOW && millis()>=nebulization_start_time){
      relay_state=LOW;
      casLastSwitchON=millis();
      } else if(breath_state==HIGH){
        relay_state=HIGH;
        }
  }
  
  myScreen.stroke(255,255,255); //bílá barva
  myScreen.setTextSize(2);
  
  if(last_time/1000 != millis() / 1000){
    myScreen.setCursor(0, 8);  // set the cursor to column X, line Y
    myScreen.stroke(0,0,0); 
    myScreen.print(last_time / 1000); // print the number of seconds since reset
    myScreen.print("s");
    myScreen.stroke(255,255,255);
    myScreen.setCursor(0, 8);  // set the cursor to column X, line Y 
    myScreen.print(millis() / 1000); // print the number of seconds since reset
    last_time=millis();
    myScreen.print("s");
    }

  if(last_breath_time != breath_time){
    myScreen.setCursor(0, 34);  // set the cursor to column X, line Y
    myScreen.stroke(0,0,0); 
    myScreen.print(last_breath_time/1000.0,3); // print the number of seconds since reset
    myScreen.print("s");
    myScreen.stroke(255,255,255);
    myScreen.setCursor(0, 34);  // set the cursor to column X, line Y 
    myScreen.print(breath_time/1000.0,3); // print the number of seconds since reset
    last_breath_time=breath_time;
    myScreen.print("s");
    }

  if(last_breath_delay != breath_delay){
    myScreen.setCursor(0, 60);  // set the cursor to column X, line Y
    myScreen.stroke(0,0,0); 
    myScreen.print(last_breath_delay); // print the number of miliseconds
    myScreen.print("ms");
    myScreen.stroke(255,255,255);
    myScreen.setCursor(0, 60);  // set the cursor to column X, line Y 
    myScreen.print(breath_delay); // print the number of seconds since reset
    last_breath_delay=breath_delay;
    myScreen.print("ms");
    }else{    
      myScreen.stroke(255,255,255);
      myScreen.setCursor(0, 60);  // set the cursor to column X, line Y 
      myScreen.print(breath_delay); // print the number of seconds since reset
      last_breath_delay=breath_delay;
      myScreen.print("ms");
      }

    if(last_duration != duration){
    myScreen.setCursor(0, 86);  // set the cursor to column X, line Y
    myScreen.stroke(0,0,0); 
    myScreen.print(last_duration); // print the number of miliseconds
    myScreen.print("ms");
    myScreen.stroke(255,255,255);
    myScreen.setCursor(0, 86);  // set the cursor to column X, line Y 
    myScreen.print(duration); // print the number of seconds since reset
    last_duration=duration;
    myScreen.print("ms");
    }else{
      myScreen.stroke(255,255,255);
      myScreen.setCursor(0, 86);  // set the cursor to column X, line Y 
      myScreen.print(duration); // print the number of seconds since reset
      last_duration=duration;
      myScreen.print("ms");      
      }
  
  
  

  
//  myScreen.setCursor(0, 86);
//  myScreen.print(duration);
//  myScreen.print("ms");

  
  if(last_relay_state != relay_state){
    myScreen.setCursor(0, 112);  // set the cursor to column X, line Y
    myScreen.stroke(0,0,0);
    if (!last_relay_state == 1){
      myScreen.print("ON"); //možnost !inverze hodnoty
      } else{
        myScreen.print("OFF");
        } 

    myScreen.setCursor(0, 112);  // set the cursor to column X, line Y 
    if (!relay_state == 1){ //!inverze hodnoty
      myScreen.stroke(0,255,0);
      myScreen.print("ON"); 
    } else{
      myScreen.stroke(255,0,0);
      myScreen.print("OFF");
      }
      last_relay_state=relay_state;
    }

    
//  myScreen.setCursor(0, 112);
//  if (!relay_state == 1){
//  myScreen.print("ON"); //možnost !inverze hodnoty
//  } else{
//    myScreen.print("OFF");
//    }

 
}
