#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_ON_ENTER=0;
long casLastSwitch_OFF_ENTER=0;
boolean ignoreUp_ENTER = false; // whether to ignore the button release because the click+hold was triggered
int 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(3, 0);  // set the cursor to column X, line Y 
  myScreen.print("Actual time:"); // time Actual
  myScreen.setCursor(3, 26);
  myScreen.print("Last breath start:");  //Time Last breath start
  myScreen.setCursor(3, 54);
  myScreen.print("Nebulization delay:");  //Delay
  myScreen.setCursor(3, 82);
  myScreen.print("Nebulizat. duration:"); //Duration
  myScreen.setCursor(3, 110);
  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;
}



void button_ENTER_action(){
  switch_ENTER_state=digitalRead(button_ENTER_pin); //  vyčte stav tlačítka plus
  // Test for button pressed and store the down time
  
  if (switch_ENTER_state == HIGH && switch_ENTER_state_last == LOW && (millis() - casLastSwitch_OFF_ENTER) > debounce){
    casLastSwitch_ON_ENTER = millis();
    }
  // Test for button release and store the up time
  if (switch_ENTER_state == LOW && switch_ENTER_state_last == HIGH && (millis() - casLastSwitch_ON_ENTER) > debounce){
    if (ignoreUp_ENTER == false){
      ENTER=ENTER +1;
      if(ENTER>2){
        ENTER=0;
        }    
      }    
    else ignoreUp_ENTER = false;
    casLastSwitch_OFF_ENTER = millis();
    }
    
//  // Test for button held down for longer than the hold time
//  if (switch_ENTER_state == HIGH && (millis() - casLastSwitch_ON_ENTER) > holdTime){
//    breath_delay=breath_delay -20;
//      if(breath_delay<0){
//        breath_delay=0;
//        }       
//    ignoreUp_ENTER = true;
//    casLastSwitch_ON_ENTER = millis();
//    }
  switch_ENTER_state_last=switch_ENTER_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();
  button_ENTER_action();
  
//  Serial.print(switch_PLUS_state);
//  Serial.print("; ");
  Serial.print("ENTER: ");
  Serial.print(ENTER);
  Serial.print("; Stav tlačítka ENTER: ");
  Serial.println(switch_ENTER_state);
//  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(3, 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(3, 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(3, 36);  // 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(3, 36);  // 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(3, 64);  // 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(3, 64);  // 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(3, 64);  // 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(3, 92);  // 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(3, 92);  // 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(3, 92);  // set the cursor to column X, line Y 
      myScreen.print(duration); // print the number of seconds since reset
      last_duration=duration;
      myScreen.print("ms");      
      }
  
 
  
  if(last_relay_state != relay_state){
    myScreen.setCursor(3, 120);  // 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(3, 120);  // 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;
    }

if(ENTER==1){
    myScreen.stroke(255, 0, 0); // set the stroke color to red
    //Vnější obdélník
    myScreen.line(0, 52, 127, 52); // draw a line across the screen
    myScreen.line(0, 80, 127, 80); // draw a line across the screen
    myScreen.line(0, 52, 0, 80); // draw a line at left side
    myScreen.line(127, 52, 127, 80); // draw a line at right side
    //Vnitřní obdélník
    myScreen.line(1, 53, 126, 53); // draw a line across the screen
    myScreen.line(1, 79, 126, 79); // draw a line across the screen
    myScreen.line(1, 53, 1, 79); // draw a line at left side
    myScreen.line(126, 53, 126, 79); // draw a line at right side
  }
  
if(ENTER==2){
    //překreslí předchozí obdélníky černou
    myScreen.stroke(0, 0, 0); // set the stroke color to black
    //Vnější obdélník
    myScreen.line(0, 52, 127, 52); // draw a line across the screen
//    myScreen.line(0, 80, 127, 80); // draw a line across the screen //Nepřekreslí spodní čáru
    myScreen.line(0, 52, 0, 79); // draw a line at left side, zkácená o bod
    myScreen.line(127, 52, 127, 79); // draw a line at right side, zkácená o bod
    //Vnitřní obdélník
    myScreen.line(1, 53, 126, 53); // draw a line across the screen
//    myScreen.line(1, 79, 126, 79); // draw a line across the screen //Nepřekreslí spodní čáru
    myScreen.line(1, 53, 1, 79); // draw a line at left side
    myScreen.line(126, 53, 126, 79); // draw a line at right side
    
    myScreen.stroke(255, 0, 0); // set the stroke color to red
    //Vnější obdélník
    myScreen.line(0, 79, 127, 79); // draw a line across the screen
    myScreen.line(0, 108, 127, 108); // draw a line across the screen
    myScreen.line(0, 79, 0, 108); // draw a line at left side
    myScreen.line(127, 79, 127, 108); // draw a line at right side
    //Vnitřní obdélník
    myScreen.line(1, 80, 126, 80); // draw a line across the screen
    myScreen.line(1, 107, 126, 107); // draw a line across the screen
    myScreen.line(1, 80, 1, 106); // draw a line at left side
    myScreen.line(126, 80, 126, 106); // draw a line at right side
  }
  
if(ENTER==0){
    myScreen.stroke(0, 0, 0); // set the stroke color to black
    //Vnější obdélník
    myScreen.line(0, 79, 127, 79); // draw a line across the screen
    myScreen.line(0, 108, 127, 108); // draw a line across the screen
    myScreen.line(0, 79, 0, 108); // draw a line at left side
    myScreen.line(127, 79, 127, 108); // draw a line at right side
    //Vnitřní obdélník
    myScreen.line(1, 80, 126, 80); // draw a line across the screen
    myScreen.line(1, 107, 126, 107); // draw a line across the screen
    myScreen.line(1, 80, 1, 106); // draw a line at left side
    myScreen.line(126, 80, 126, 106); // draw a line at right side
  }
 

 
}
