#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 last_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 last_breath_delay=0;

long nebulization_start_time=0;
long nebulization_stop_time=0;
long last_duration=0;
long last_time=0;


/////////////////////////
//Nastavitelné položky//
///////////////////////

int MAX_breath_delay=4000;
int MAX_breath_duration=2000;
int breath_delay=1000; //Delay before nebulization
int duration=1000; //Duration of nebulization
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); //AKTIVACE SÉRIOVÉ LINKY
  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){
      if(ENTER==1){
        breath_delay=breath_delay +1;
        if(breath_delay>MAX_breath_delay){
          breath_delay=MAX_breath_delay;
          }
        }
      if(ENTER==2){
        duration=duration +1;
        if(duration>MAX_breath_duration){
          duration=MAX_breath_duration;
          }         
      }
      }    
    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){
      if(ENTER==1){
        breath_delay=breath_delay +20;
        if(breath_delay>MAX_breath_delay){
          breath_delay=MAX_breath_delay;
          }
        }
      if(ENTER==2){
        duration=duration +20;
        if(duration>MAX_breath_duration){
          duration=MAX_breath_duration;
          }
        }               
    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){
      if(ENTER==1){
        breath_delay=breath_delay -1;
        if(breath_delay<0){
          breath_delay=0;
          }
        }
      if(ENTER==2){
        duration=duration -1;
        if(duration<0){
          duration=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){
      if(ENTER==1){
        breath_delay=breath_delay -20;
        if(breath_delay<0){
          breath_delay=0;
          }
        }  
      if(ENTER==2){
        duration=duration -20;
        if(duration<0){
          duration=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) > 800){
    ENTER=3;
    ignoreUp_ENTER = true;
    casLastSwitch_ON_ENTER = millis();
    }
    
  switch_ENTER_state_last=switch_ENTER_state;
}


///////////////////////////////////////////////////////////////////////////////////////
//Tady by šlo změnit stav ve kterém má spínat LOW/HIGH a přenastavit počáteční stavy//
/////////////////////////////////////////////////////////////////////////////////////

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();
 
  nebulization_start_time = breath_time + breath_delay;
  nebulization_stop_time=nebulization_start_time+duration;

  if(button_REL_ON==LOW){ //pokud nebylo relé zapnuto tlačítkem může relé ovládat simulátor
     
    if (millis()>=nebulization_start_time && millis()<= nebulization_stop_time && ENTER==3){
      relay_state=LOW;  //zapne relé
      casLastSwitchON=millis();
      } else {
        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){
    //vymazání původních čar
    myScreen.stroke(0, 0, 0); // set the stroke color to black

    myScreen.line(0, 108, 127, 108); // draw a line across the screen
    myScreen.line(1, 107, 126, 107); // draw a line across the screen 

    myScreen.line(0, 81, 0, 108); // draw a line at left side
    myScreen.line(127, 81, 127, 109); // draw a line at right side(127, 79, 127, 108);
    myScreen.line(1, 81, 1, 107); // draw a line at left side
    myScreen.line(126, 81, 126, 109); // draw a line at right side (126, 79, 126, 108);

    //nové čáry kolem DELAY
    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, 80); // draw a line at left side
    myScreen.line(126, 53, 126, 80); // draw a line at right side
  }
  
  if(ENTER==2){
    //vymazání původních čar
    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, 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, 53, 1, 79); // draw a line at left side
    myScreen.line(126, 53, 126, 79); // draw a line at right side

    //nové čáry kolem duration    
    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, 109); // draw a line at left side
    myScreen.line(127, 79, 127, 109); // 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, 107); // draw a line at left side
    myScreen.line(126, 80, 126, 107); // draw a line at right side
  }
  
  if(ENTER==0){
//      //vymazání původních čar
//      myScreen.stroke(0, 0, 0); // set the stroke color to black
//      //Vnější obdélník
//      myScreen.line(2, 79, 126, 79); // draw a line across the screen
//
//      //Vnitřní obdélník
//      myScreen.line(2, 80, 126, 80); // draw a line across the screen

    //nové čáry kolem duration    
    myScreen.stroke(0, 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, 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, 53, 1, 80); // draw a line at left side
    myScreen.line(126, 53, 126, 80); // draw a line at right side
    
    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, 109); // draw a line at left side
    myScreen.line(127, 79, 127, 109); // 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, 107); // draw a line at left side
    myScreen.line(126, 80, 126, 108); // draw a line at right side


//    //nové čáry kolem delay a duration  
//    myScreen.stroke(255, 0, 0); // set the stroke color to green
//    myScreen.line(0, 52, 127, 52); // draw a line across the screen
//    myScreen.line(1, 53, 126, 53); // draw a line across the screen
//    myScreen.line(0, 108, 127, 108); // draw a line across the screen
//    myScreen.line(1, 107, 126, 107); // draw a line across the screen 
//
//    myScreen.line(0, 52, 0, 108); // draw a line at left side
//    myScreen.line(127, 52, 127, 109); // draw a line at right side(127, 52, 127, 108);
//    myScreen.line(1, 53, 1, 107); // draw a line at left side
//    myScreen.line(126, 53, 126, 109); // draw a line at right side (126, 53, 126, 108);
  }
  
  if(ENTER==3){
      //vymazání původních čar
      myScreen.stroke(0, 0, 0); // set the stroke color to black
      //Vnější obdélník
      myScreen.line(2, 79, 126, 79); // draw a line across the screen

      //Vnitřní obdélník
      myScreen.line(2, 80, 126, 80); // draw a line across the screen

    //nové čáry kolem delay a duration  
    myScreen.stroke(0, 255, 0); // set the stroke color to green
    myScreen.line(0, 52, 127, 52); // draw a line across the screen
    myScreen.line(1, 53, 126, 53); // draw a line across the screen
    myScreen.line(0, 108, 127, 108); // draw a line across the screen
    myScreen.line(1, 107, 126, 107); // draw a line across the screen 

    myScreen.line(0, 52, 0, 108); // draw a line at left side
    myScreen.line(127, 52, 127, 109); // draw a line at right side(127, 52, 127, 108);
    myScreen.line(1, 53, 1, 107); // draw a line at left side
    myScreen.line(126, 53, 126, 109); // draw a line at right side (126, 53, 126, 108);
  }

}
