/*
   Sequence A: Button A switch on with delay
               Button B switch off with delay
   Sequence Z: Button Z switch on / off one output after the other
*/


constexpr uint8_t t = 20;
constexpr uint8_t t1 = 40;
constexpr uint8_t t2 = 60;
constexpr uint8_t t3 = 80;
constexpr uint8_t t4 = 200;
constexpr uint16_t t5 = 500;
constexpr uint16_t t6 = 800;
constexpr uint16_t t7 = 1000;

constexpr uint8_t led[] {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; // the LEDs assigned to pins
constexpr size_t noOfLeds = sizeof(led) / sizeof(led[0]);

void setup() {
  Serial.begin(115200);
  // set up pins  as outputs
  for (auto &i : led) {
    pinMode(i, OUTPUT);
  }
}
//Effects setup
void loop() {
  //effect_change();

  effect_1_fill_in_out();
  effect_1_fill_in_out();
  //effect_1_fill_in_out();
  effect_change();
  effect_1_fill_in_out_otherend();
  effect_1_fill_in_out_otherend();
  //effect_1_fill_in_out_otherend();
  effect_change();
  effect_2_chasing_with_vibration();
  effect_2_chasing_with_vibration();
  effect_change();
  effect_3_LefFilltoRightAndBack();
  effect_3_LefFilltoRightAndBack();
  effect_change();
  effect_4_chasing_with_vibration_negative();
  effect_4_chasing_with_vibration_negative();
  effect_change();
  effect_5_police();
  effect_5_police();
  effect_5_police();
  effect_5_police();
  effect_5_police();
  effect_5_police();
  effect_change();
  effect_6_RainDropp_Left();
  effect_6_RainDropp_Left();
  effect_6_RainDropp_Left();
  effect_change();
  effect_6_RainDropp_Right();
  effect_6_RainDropp_Right();
  effect_6_RainDropp_Right();
  effect_change();

}

void effect_change()
{
  Serial.println(__func__);
  delay(t5);
  for (int i = 2; i <= 12; i++) {
    digitalWrite(i, HIGH);
  }
  delay(t2);
  for (int i = 2; i <= 12; i++) {
    digitalWrite(i, LOW);
  }
  delay(t2);
  //***
  for (int i = 2; i <= 12; i++) {
    digitalWrite(i, HIGH);
  }
  delay(t2);
  for (int i = 2; i <= 12; i++) {
    digitalWrite(i, LOW);
  }
  delay(t2);
  //***
  for (int i = 2; i <= 12; i++) {
    digitalWrite(i, HIGH);
  }
  delay(t2);
  for (int i = 2; i <= 12; i++) {
    digitalWrite(i, LOW);
  }
  delay(t6);
}

//******** EFFECT 1 ********
void effect_1_fill_in_out() {
  Serial.println(__func__);
  // used pinX and pin loop - two times
  static uint8_t pinX = 0;
  static uint8_t pin = noOfLeds - 1;
  static uint8_t state = 0;
  static uint32_t previousMillis = 0;
  static uint16_t interval = t3;

  uint32_t currentMillis = millis();

  /*
  if (currentMillis - previousMillis > interval) {
    digitalWrite(pin, HIGH);
  }


*/


  // *** in ***
  for (int pinX = 2; pinX <= 11; pinX++) {
    for (int pin = 11; pin > pinX; pin--) {
      digitalWrite(pin, HIGH);
      delay(t3);      // 1
      digitalWrite(pin, LOW);
    }
    digitalWrite(pinX, HIGH);
  }
  delay(t4);          // 2

  // *** OUT ***
  for (int pinX = 2; pinX <= 11; pinX++) {
    digitalWrite(pinX, LOW);
    for (int pin = pinX; pin >= 2; pin--) {
      digitalWrite(pin, HIGH);
      delay(t3);      // 3
      digitalWrite(pin, LOW);
    }
  }
  delay(t4);          // 4
}

void effect_1_fill_in_out_XXX() {
  Serial.println(__func__);
  // *** in ***
  for (int pinX = 2; pinX <= 11; pinX++) {
    for (int pin = 11; pin > pinX; pin--) {
      digitalWrite(pin, HIGH);
      delay(t3);
      digitalWrite(pin, LOW);
    }
    digitalWrite(pinX, HIGH);
  }
  delay(t4);

  // *** OUT ***
  for (int pinX = 2; pinX <= 11; pinX++) {
    digitalWrite(pinX, LOW);
    for (int pin = pinX; pin >= 2; pin--) {
      digitalWrite(pin, HIGH);
      delay(t3);
      digitalWrite(pin, LOW);
    }
  }
  delay(t4);
}

//******** EFFECT 1 - FROM OTHER END ********
void effect_1_fill_in_out_otherend()
{
  Serial.println(__func__);
  // *** in ***
  for (int pinX = 11; pinX >= 2; pinX--) {
    for (int pin = 2; pin < pinX; pin++) {
      digitalWrite(pin, HIGH);
      delay(t3);
      digitalWrite(pin, LOW);
    }
    digitalWrite(pinX, HIGH);
  }
  delay(t4);

  // *** OUT ***
  for (int pinX = 11; pinX >= 2; pinX--) {
    digitalWrite(pinX, LOW);
    for (int pin = pinX; pin <= 11; pin++) {
      digitalWrite(pin, HIGH);
      delay(t3);
      digitalWrite(pin, LOW);
    }
  }
  delay(t4);
}
//******** EFFECT 2 ********

void effect_2_chasing_with_vibration()
{
  Serial.println(__func__);
  for (int i = 2; i < 12; i++) {
    digitalWrite(i, HIGH);
    delay(t);
    digitalWrite(i + 1, HIGH);
    delay(t);
    digitalWrite(i + 2, HIGH);
    delay(t);
    digitalWrite(i, LOW);
    delay(t);
    digitalWrite(i + 1, LOW);
    delay(t);
  }
  for (int i = 11; i > 1; i--) {
    Serial.println(__func__);
    digitalWrite(i, HIGH);
    delay(t);
    digitalWrite(i - 1, HIGH);
    delay(t);
    digitalWrite(i - 2, HIGH);
    delay(t);
    digitalWrite(i, LOW);
    delay(t);
    digitalWrite(i - 1, LOW);
    delay(t);
  }

}

//******** EFFECT 3 ********

void effect_3_LefFilltoRightAndBack()
{
  Serial.println(__func__);
  for (int i = 2; i < 12; i++) {
    digitalWrite(i, HIGH);
    delay(t3);
  }
  delay(t5);
  for (int i = 2; i < 12; i++) {
    digitalWrite(i, LOW);
    delay(t3);
  }
  delay(t5);
  for (int i = 12; i >= 2; i--) {
    digitalWrite(i, HIGH);
    delay(t3);
  }
  delay(t5);
  for (int i = 12; i >= 2; i--) {
    digitalWrite(i, LOW);
    delay(t3);
  }
  delay(t5);
  //delay(500);
}

//******** EFFECT 4 ********

void effect_4_chasing_with_vibration_negative()
{
  Serial.println(__func__);
  for (int i = 2; i <= 12; i++) {
    digitalWrite(i, HIGH);
  }
  for (int i = 2; i < 12; i++) {
    digitalWrite(i, LOW);
    delay(t1);
    digitalWrite(i + 1, LOW);
    delay(t1);
    digitalWrite(i + 2, LOW);
    delay(t1);
    digitalWrite(i, HIGH);
    delay(t1);
    digitalWrite(i + 1, HIGH);
    delay(t1);
  }
  for (int i = 11; i > 1; i--) {
    digitalWrite(i, LOW);
    delay(t1);
    digitalWrite(i - 1, LOW);
    delay(t1);
    digitalWrite(i - 2, LOW);
    delay(t1);
    digitalWrite(i, HIGH);
    delay(t1);
    digitalWrite(i - 1, HIGH);
    delay(t1);
  }

}

//******** EFFECT 5 ********

void effect_5_police() {
  Serial.println(__func__);
  for (int i = 2; i <= 6; i++) {
    digitalWrite(i, HIGH);
  }
  delay(t3);
  for (int i = 2; i <= 6; i++) {
    digitalWrite(i, LOW);
  }
  delay(t3);
  for (int i = 2; i <= 6; i++) {
    digitalWrite(i, HIGH);
  }
  delay(t3);
  for (int i = 2; i <= 6; i++) {
    digitalWrite(i, LOW);
  }
  delay(t3);
  for (int i = 2; i <= 6; i++) {
    digitalWrite(i, HIGH);
  }
  delay(t3);
  for (int i = 2; i <= 6; i++) {
    digitalWrite(i, LOW);
  }
  delay(t3);


  for (int i = 7; i <= 12; i++) {
    digitalWrite(i, HIGH);
  }
  delay(t3);
  for (int i = 7; i <= 12; i++) {
    digitalWrite(i, LOW);
  }
  delay(t3);
  for (int i = 7; i <= 12; i++) {
    digitalWrite(i, HIGH);
  }
  delay(t3);
  for (int i = 7; i <= 12; i++) {
    digitalWrite(i, LOW);
  }
  delay(t3);
  for (int i = 7; i <= 12; i++) {
    digitalWrite(i, HIGH);
  }
  delay(t3);
  for (int i = 7; i <= 12; i++) {
    digitalWrite(i, LOW);
  }
  delay(t3);

}

//******** EFFECT 3 ********

void effect_6_RainDropp_Left()
{
 Serial.println(__func__);
  for (int i = 2; i < 12; i++) {
    digitalWrite(i, HIGH);
    delay(t3);
  }

  for (int i = 2; i < 12; i++) {
    digitalWrite(i, LOW);
    delay(t3);
  }
}

void effect_6_RainDropp_Right()
{
  Serial.println(__func__);
  for (int i = 12; i >= 2; i--) {
    digitalWrite(i, HIGH);
    delay(t3);
  }
  for (int i = 12; i >= 2; i--) {
    digitalWrite(i, LOW);
    delay(t3);
  }
}