// =========================================================================================
// For: https://forum.arduino.cc/t/fastled-beat-triggered-traffic-pattern-help-please/861691
// =========================================================================================

#include <FastLED.h>

//FASTLED 
#define LEDstripPin 4                          
#define NUM_LEDS 60
#define COLOR_ORDER GRB
#define CHIPSET WS2812B

CRGB leds[NUM_LEDS];


class VehicleSimple                              // old/basic vehicle with a very simple pathfinding
{
  public:
    CRGB color;                                  // the color of this car
    bool debug = false;                          // debug messages for this car    Vehicle(uint32_t color): color(color) {}     // constructor
    uint16_t newPosition = 4711;                 // number should be out of the range of the real grid.
    uint16_t currentPosition = 0;                // startposition is anywhere in the middle of the screen, might interfere with some traffic lights, but I don't care...
    uint32_t previousMillis = 0;                 // timekeeping for intervals
    uint16_t wait = 500;                         // timekeeping standard/speed

    VehicleSimple(CRGB color): color(color) {}   // constructor

    void setPosition(byte newPosition) {
      currentPosition = newPosition;
    }

    void setSpeed (uint16_t newSpeed) {
      wait = newSpeed;
    }

    void toggleDebug()
    {
      debug = !debug;
    }

    void tick()                                  // call this method in the loop (run)
    {
      if (millis() - previousMillis > wait)      // time to move
      {
        if (debug) Serial.print (color, HEX);
        
        if (currentPosition < NUM_LEDS) 
          newPosition = currentPosition + 1;
        else
          newPosition = 0;

        // move
        if (newPosition != currentPosition) 
          leds[currentPosition] = CRGB( 0, 0, 0);   // delete if necessary
        leds[newPosition] = color;                                       // set new field
        FastLED.show();                                                                  // update strip to match
        currentPosition = newPosition;
        previousMillis = millis();
      }
    }
};

VehicleSimple car[]
{ // a group of newer cars - to make some traffic in the city
  CRGB(0,   0,  255),
  CRGB(255,  0,  255),
  CRGB(255,  128, 255),
  CRGB(255,  128, 0),
  CRGB(255, 0,  0),
  CRGB(0, 255, 128),
  //CRGB(128,  32, 128),
  //CRGB(200,  16, 255),
  //CRGB(200,  32, 255),
  //CRGB(255,  0,  255),
  //CRGB(255,  16, 255),
  //CRGB(255,  32, 255)
};


void setup() 
{
  Serial.begin(115200);
  Serial.println(F("\nNeopixel Traffic Simplified"));
  randomSeed(analogRead(0));

  FastLED.addLeds<WS2812B,LEDstripPin, GRB>(leds, NUM_LEDS);

  fill_solid(leds, NUM_LEDS, CRGB( 0, 0, 0));
  FastLED.show();
//  FastLED.setBrightness(8);

  for (auto &i : car)
    i.setSpeed((random(15, 30) * 10)); // give each car in this group an indiviudal speed

  car[0].setSpeed(100);  // a very fast car
}

void loop() {
  for (auto &i : car)       // there are lot of cars in this group/array of objects
    i.tick();
}