


#include "ClickButton.h"



// Bemenetek (nyomógomb)
const int ENGINE_CUT_PB = A0;           // ENGINE.CUT RELAY ON-OFF gomb (kétszer kell gyorsan megnyomni), indítás után automatikusan bekapcsol.
const int STARTER_PB = A1;              // Starter Gomb 
const int DUDA_PB = A2;                 // Duda Gomb
const int Bal_index_PB = A3;            // Bal Index Gomb
const int Jobb_index_PB = A4;           // Jobb Index Gomb
const int REFI_PB = A5;                 // REFI gomb
const int BRAKE_SW = 3;                 // Fék kapcsoló/fékpedál

// Kimenetek
const int ENGINE_CUT = 4;                // E.CUT RELAY - RELÉ
const int starter_rele_kimenet = 5;      // Indító motor pici relé. - RELÉ
const int DUDA_ledPin = 6;               // Duda kimenet - FET
const int BRAKE = 7;                     // Féklámpa kimenet - FET
const int Bal_index_Kimenet = 8;         // Bal Index kimenet - FET
const int Jobb_index_Kimenet = 11;       // Jobb Index kimenet - FET
const int REFI_kimenet = 9;              // REFI kimenet - FET
const int HEADLIGH_kimenet = 10;         // REFI kimenet - FET

#define _on LOW                          // low state is on in this case, because using PNP transistors to do the heavy lifting
#define _off HIGH                        // high state is a floating voltage, so it's off
#define _flshCntrMax 5                   // Mennyit villogjon a féklámpa mielött világít folyamatosan
#define _flshSleapTime 100               // Villogási idő (féklámpa)
 
// Változók
int outClignoState = LOW;                // start flashing off
int state1 = LOW;                        // start right flash on off
int reading1;
int previous1 = HIGH;
int state2 = LOW;                        // start left flashing on off
int reading2;
int previous2 = HIGH;
int DUDA_buttonState = 0;                // variable for reading the pushbutton status
int state4 = LOW;                        // start warning on off
int starter_rele;
int reading9;                            // Vészvillogó
int previous9 = LOW;                     // Vészvillogó bekapcsolás után villlogjon=HIGH, nem villogjon=LOW
int ENGINE_CUR_RELAY_ = 1;               // ENGINE.CUT RELAY ÁLLAPOT, bekapsolás után, ha 0 akkor nincs bekapcsolva ha 1 akkor automatikusa bekapcsol tápfesz ráadásakor,
int ENGINE_CUT_state = 1;                // ENGINE.CUT RELAY ÁLLAPOT, bekapsolás után, ha 0 akkor nincs bekapcsolva ha 1 akkor automatikusa bekapcsol tápfesz ráadásakor,
ClickButton button1(ENGINE_CUT_PB, LOW, CLICKBTN_PULLUP);//E.CUT RELAY ÁLLAPOT

int ledState = LOW;                      // REFI // the current state of the output pin
int buttonState;                         // REFI // the current reading from the input pin
int lastButtonState = HIGH;              // REFI // the previous reading from the input pin
unsigned long lastDebounceTime = 0;      // REFI // the last time the output pin was toggled
unsigned long debounceDelay = 50;        // REFI // the debounce time; increase if the output flickers

long time = 1;
const long debounce = 200;               // Index gombnyomás érzékelése
long previousMillis = 0;                 //
const long interval = 500;               // Index villogási idő
enum {none,} currTS; // FÉKLÁMPA DOLGOK  // what the current turn signal is doing


void setup() 
{
  pinMode(Jobb_index_PB, INPUT_PULLUP);    // Jobb index gomb
  pinMode(Jobb_index_Kimenet, OUTPUT);     // Jobb index kimenet
  pinMode(Bal_index_PB, INPUT_PULLUP);     // Bal index gomb
  pinMode(Bal_index_Kimenet, OUTPUT);      // Bal index kimenet
  pinMode(DUDA_PB, INPUT_PULLUP);          // Duda gomb
  pinMode(DUDA_ledPin, OUTPUT);            // Duda kimenet
  pinMode(STARTER_PB, INPUT_PULLUP);       // Starter Gomb 
  pinMode(starter_rele_kimenet, OUTPUT);   // starter_rele_kimenet
  pinMode(BRAKE_SW, INPUT_PULLUP);         // Fék kapcsoló/fékpedál
  pinMode(BRAKE, OUTPUT);                  // FÉKLÁMPA KIMENET
  pinMode(REFI_PB, INPUT_PULLUP);          // REFI GOMB
  pinMode(REFI_kimenet, OUTPUT);           // REFI kimenet
  digitalWrite(REFI_kimenet, ledState);    // REFI
  pinMode(HEADLIGH_kimenet, OUTPUT);       // HEADLIGHT kimenet
  digitalWrite(HEADLIGH_kimenet, HIGH);    // Headlight mindig bevan kapcsolva
  pinMode(4,OUTPUT);                       // ENGINE.CUT RELAY kimenet


  ////////////////////////////// FÉKLÁMPA ///////////////////////////////////////
}
bool isBrakeFlashTime(unsigned long curr, bool B,int *state){
  static unsigned long fut_time;
  static int flshcntr;
  static int flserstate;
  if (curr >=fut_time){
    flserstate = !flserstate;
    if(B && flserstate)flshcntr++;
    fut_time=curr+_flshSleapTime;   
  }
  *state = flserstate;
  if (!B)
    flshcntr = 0; //no Brake, reset the counter
  else if(flshcntr <= _flshCntrMax)
    return true; //has Brake and still has flashes
  return false; //fall though, not in flash
}
void loop()
{
  
////////////////////////////// REFI ///////////////////////////////////////
 // read the state of the switch into a local variable:
  int reading = digitalRead(REFI_PB);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is LOW
      if (buttonState == LOW) {
        ledState = !ledState;
      }
    }
  }

  // set the LED:
  digitalWrite(REFI_kimenet, ledState);

  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;


////////////////////////////// Jobb Index ///////////////////////////////////////
  reading1 = digitalRead(Jobb_index_PB);
  if (reading1 == LOW && previous1 == HIGH && millis() - time > debounce)
  {
    if (state1 == HIGH)
      {
      state1 = LOW;
      digitalWrite(Jobb_index_Kimenet, LOW);
      }
    else
    {
      state4 = LOW;
      state1 = HIGH;
      state2 = LOW;
      digitalWrite(Bal_index_Kimenet, LOW);
    }
    time = millis();
  }
  clignotement (Jobb_index_Kimenet, state1);
  previous1 = reading1;

 
/////////////////////////////// Bal Index ///////////////////////////////////////
  reading2 = digitalRead(Bal_index_PB);
  if (reading2 == LOW && previous2 == HIGH && millis() - time > debounce)
  {
    if (state2 == HIGH)
      {
      state2 = LOW;
      digitalWrite(Bal_index_Kimenet, LOW);
      }
    else
    {
      state4 = LOW;
      state2 = HIGH;
      state1 = LOW;
      digitalWrite(Jobb_index_Kimenet, LOW);
    }
    time = millis();
  }
  clignotement (Bal_index_Kimenet, state2);
  previous2 = reading2;

  ////////////////////////////// Duda ///////////////////////////////////////
  
  DUDA_buttonState = digitalRead(DUDA_PB);  // read the state of the pushbutton value:
  if (DUDA_buttonState == HIGH) {           // check if the pushbutton is pressed.
    digitalWrite(DUDA_ledPin, LOW);         // turn DUDA on:
  } else {
    digitalWrite(DUDA_ledPin, HIGH);        // turn DUDA off:
 }

  ////////////////////////////// Starter relé ///////////////////////////////////////
  // CSAK AKKOR MŰKÖDIK HA FOLYAMATOSAN HÚZOM A FÉKET  ÉS AZ ENGINE.CUT RELAY BE VAN KAPCSOLVA
  
  starter_rele = digitalRead(A1);
  if (digitalRead (A1) == LOW && digitalRead (3) == LOW && digitalRead (4) == HIGH )
  {
    digitalWrite(starter_rele_kimenet, HIGH);
  }
  else
    digitalWrite(starter_rele_kimenet, LOW);


  ///////////////////////////// / Vészvillogó ///////////////////////////////////////
  // A KÉT IRÁNYJELZŐGOMB EGYIDEJŰ GOMBNYOMÁSA ESETÉN MŰKÖDIK.
  reading9 = digitalRead (A3) == LOW && digitalRead(A4) == LOW;
  if (reading9 == LOW && previous9 == HIGH && millis() - time > debounce)
  {
    if (state4 == HIGH)
    {
      state4 = LOW;
      state1 = LOW;
      digitalWrite(Jobb_index_Kimenet, LOW);
      state2 = LOW;
      digitalWrite(Bal_index_Kimenet, LOW);
     }
    else
    {
      state4 = HIGH;
      state1 = LOW;
      digitalWrite(Jobb_index_Kimenet, LOW);
      state2 = LOW;
      digitalWrite(Bal_index_Kimenet, LOW);
    }
    time = millis();
  }
  clignotement (Jobb_index_Kimenet, state4);
  clignotement (Bal_index_Kimenet, state4);
  previous9 = reading9;
}
int clignotement (int outCligno, int ClignoState)
{
  if (ClignoState == HIGH)
  {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis > interval)
    {
      previousMillis = currentMillis;
      if (outClignoState == LOW)
        outClignoState = HIGH;
      else
        outClignoState = LOW;
    }
    digitalWrite(outCligno, outClignoState);
  }





  ///////////////////////////// / ENGINE.CUT RELAY ON-OFF ///////////////////////////////////////
  button1.Update();
  if (button1.clicks != 0) ENGINE_CUR_RELAY_ = button1.clicks;
  if(button1.clicks == 2) ENGINE_CUT_state = !ENGINE_CUT_state;
  digitalWrite(ENGINE_CUT,ENGINE_CUT_state);


  ////////////////////////////// FÉKLÁMPA ///////////////////////////////////////
bool B = isBrake();
  unsigned long curr = millis();
  int rearflashstate;
  bool brkflsh = isBrakeFlashTime(curr,B,&rearflashstate);
  if (B && currTS == none) { 
    if (brkflsh) {
      digitalWrite(BRAKE, !rearflashstate);
    } else {
      digitalWrite(BRAKE, HIGH);
    } 
  } else { 
    digitalWrite(BRAKE, LOW);
  }
}
bool isBrake() {
  static long lasttm;
  static int last;
  int state = digitalRead(BRAKE_SW);
  bool ret = false;
  if (last != state) {
    lasttm = millis();
    last = state;
  }
  if ((millis() - lasttm) > 100) {
    ret = last == _on;
  }
  return ret;
}  
