/*
  Forum: https://forum.arduino.cc/t/arduino-sketch-function-limits-script-kills-all-lights/1208706
  Wokwi: https://wokwi.com/projects/386390802476295169
*/
#include <FastLED.h>
#include <SerialCommand.h>
#include <SoftwareSerial.h>
// LED strip variable ---------------------------------------------------------------------------
#define NUM_LEDS 11
CRGB leds[NUM_LEDS];
#define LED_PIN 9
static int currentAmt;
// Engine fix variables----------------------------------------------------------------------------
int LED1 = 3;
int LED2 = 4;
int LED3 = 5;
bool led1Trigger;
bool led2Trigger;
bool led3Trigger;
bool led1Flash;
bool led2Flash;
bool led3Flash;
int led1State = LOW;
int led2State = LOW;
int led3State = LOW;
unsigned long prevMillis = 0;
const long interval = 1000;
// communication between unity and arduino--------------------------------------------------
SerialCommand sCmd;
void setup() {
  Serial.begin(9600);
  Serial.println("Start");
  // commands for fuel bar -----------------------------------------------------------------------
  sCmd.addCommand("FILL", fillHandler);
  sCmd.addCommand("RAISE", raiseHandler);
  sCmd.addCommand("LOWER", lowerHandler);
  sCmd.addCommand("EMPTY", emptyHandler);
  sCmd.addCommand("RED", redHandler);
  sCmd.addCommand("RESETGREEN", resetGreenHandler);
  // commands for engine leds--------------------------------------------------------------
  sCmd.addCommand("BLINK1", blink1);
  sCmd.addCommand("FIX1", fix1);
  sCmd.addCommand("BLINK2", blink2);
  sCmd.addCommand("FIX2", fix2);
  sCmd.addCommand("BLINK3", blink3);
  sCmd.addCommand("FIX3", fix3);
  // sets up the LED strip -------------------------------------------------------------------------
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS); // sets up our strip
  FastLED.setMaxPowerInVoltsAndMilliamps(5, 500); // limits it to only take 5 volts
  FastLED.clear();
  FastLED.show();
  // sets up the engine LEDS ---------------------------------------------------------------------
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
}
void loop() {
  // for communicating between arduino and unity ----------------------------------------------------
  if (Serial.available() > 0) {
    sCmd.readSerial();
  }
  // engine light stuff ---------------------------------------------------------------------------------
  unsigned long currentMillis = millis();
  // these are all to say if the engine has been triggered, then the matching LED should begin flashing LED 1
  if (led1Trigger == true) {
    led1Flash = true;
  } else {
    led1Flash = false;
  }
  // LED 2
  if (led2Trigger == true) {
    led2Flash = true;
  } else {
    led2Flash = false;
  }
  //LED 3
  if (led3Trigger == true) {
    led3Flash = true;
  } else {
    led3Flash = false;
  }
  // this controls the on/off flashing, and also the ability the turn OFF the flashing
  if (currentMillis - prevMillis >= interval) {
    prevMillis = currentMillis;
    // LED 1
    if (led1State == LOW) {
      led1State = HIGH;
    } else {
      led1State = LOW;
    }
    if (led1Flash == true) {
      digitalWrite(LED1, led1State);
    } else {
      digitalWrite(LED1, LOW);
    }
    // LED 2
    if (led2State == LOW) {
      led2State = HIGH;
    } else {
      led2State = LOW;
    }
    if (led2Flash == true) {
      digitalWrite(LED2, led2State);
    } else {
      digitalWrite(LED2, LOW);
    }
    // LED 3
    if (led3State == LOW) {
      led3State = HIGH;
    } else {
      led3State = LOW;
    }
    if (led3Flash == true) {
      digitalWrite(LED3, led3State);
    } else {
      digitalWrite(LED3, LOW);
    }
  }
}
// engine LED commands -----------------------------------------------------------------------------------------
void blink1(const char *command) { led1Trigger = true; }
void fix1(const char *command) { led1Trigger = false; }
void blink2(const char *command) { led2Trigger = true; }
void fix2(const char *command) { led2Trigger = false; }
void blink3(const char *command) { led3Trigger = true; }
void fix3(const char *command) { led3Trigger = false; }
// fuel bar commands ----------------------------------------------------------------------------------------------
void fillHandler(const char *command) {
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CRGB(0, 255, 0);
    FastLED.show();
    delay(20);
  }
  currentAmt = NUM_LEDS - 1;
}
void raiseHandler(const char *command) {
  if (currentAmt < NUM_LEDS - 1) {
    leds[currentAmt] = CRGB(0, 255, 0);
    FastLED.show();
    currentAmt += 1;
  } else if (currentAmt == NUM_LEDS - 1) {
    leds[currentAmt] = CRGB(0, 255, 0);
    FastLED.show();
  }
}
void lowerHandler(const char *command) {
  if (currentAmt > 1) {
    leds[currentAmt] = CRGB::Black;
    FastLED.show();
    currentAmt -= 1;
  } else if (currentAmt == 1) {
    leds[currentAmt] = CRGB::Black;
    FastLED.show();
  }
}
void emptyHandler(const char *command) {
  for (int i = currentAmt; i >= 0; i--) {
    leds[i] = CRGB::Black;
    FastLED.show();
    delay(20);
  }
  currentAmt = 1;
}
// turns the whole LED strip red ----------------------------------------------------------
void redHandler (const char *command) {
    for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CRGB(255, 0, 0);
    FastLED.show();
    delay(20);
  }
}
//turns the red off, and LED strip back to the amount of green it last had -----------------------------------------
void resetGreenHandler (const char *command) {
  for (int i = 0; i < NUM_LEDS; i++){
    leds[i] = CRGB::Black;
    FastLED.show();
  }
  for (int i = 0; i < currentAmt; i++) {
      leds[i] = CRGB(0, 255, 0);
      FastLED.show();
      delay(20);
  }
}