//

unsigned long now;
unsigned long bigTickCounter;
unsigned long tickCounter;

# define NLAMPS	8

# define TICK	10		// ms 100 frames / second

# define OFF    13
# define ON     14
# define WAX    15
# define WANE   16
# define DWELL	17

typedef struct {
	unsigned char state;
	unsigned long color;		// just blue intensity now
	unsigned char timer;
	unsigned char timerToo;		// forehead slap
	
} element;

element theLEDs[NLAMPS];

unsigned char firstTime[NLAMPS] = {53, 59, 61, 67,  71, 73, 79, 83, };
unsigned char setupValue[NLAMPS] = {38, 14, 6, 49, 37, 31, 13, 1,}; 

void setup() {
	Serial.begin(115200);
	Serial.println("Traffic Random w/ PWM machine");

 	initLamps();

	for (unsigned char ii = 0; ii < NLAMPS; ii++) {
		turnLED(ii, OFF);
		theLEDs[ii].timer = setupValue[ii];
	}
}


void turnLED(unsigned char theLED, unsigned char onOff)
{
	theLEDs[theLED].state = onOff;
}

void myShowLEDs()
{
	for (unsigned char ii = 0; ii < NLAMPS; ii++)
		lampSet(ii, theLEDs[ii].color);

	lampsShow();
}

/* run all the LED FSMs */
void ageLEDs()
{
	for (unsigned char ii = 0; ii < NLAMPS; ii++) {
		switch (theLEDs[ii].state) {

		case ON :		/* the agent has turned on an LED */
			theLEDs[ii].state = WAX;
			theLEDs[ii].color = 0x10;

			break;

		case WAX :
			theLEDs[ii].color += 0x08;
			if (theLEDs[ii].color >= 0x80) {
				theLEDs[ii].state = DWELL;
				theLEDs[ii].timerToo = 12;
			}

			break;

		case DWELL :
			if (!--theLEDs[ii].timerToo) theLEDs[ii].state = WANE;

			break;

		case WANE :
			if (theLEDs[ii].color >= 8) theLEDs[ii].color -= 4;
			else theLEDs[ii].state = OFF;

			break;

		case OFF :
			theLEDs[ii].color = 0;

			break;
		}
	}
}

// run all the traffic timers
void runAllTimers()
{
  unsigned char nZeros = 0;

	for (unsigned char ii = 0; ii < NLAMPS; ii++) {
		if (!--theLEDs[ii].timer) {
      nZeros++;
			turnLED(ii, ON);
			theLEDs[ii].timer = firstTime[ii];
		}
	}

  if (nZeros > 3) {
    Serial.print(bigTickCounter);
    Serial.print("   ");
    Serial.println(nZeros);
  }
}

# define FOUR	4

void loop() {
	static unsigned long lastTime;
  static unsigned char bigTick;

  now = millis();

	if (now - lastTime < TICK) return;
  lastTime = now;

	ageLEDs();

	if (++bigTick >= FOUR) {
    bigTickCounter++;
		bigTick = 0;

		runAllTimers();
	}

  if (0) {
    for (int ii = 0; ii < 4; ii++) {
      Serial.print(theLEDs[ii].timer); Serial.print(" ");
    }
    Serial.println();
  }
  
	myShowLEDs();
	tickCounter++;
}

// start all smart LED stuff
// initialize, set color, get color and show

# include <Adafruit_NeoPixel.h>

# define PIN 6		//***

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NLAMPS, PIN, NEO_RGB + NEO_KHZ800);

void initLamps()
{
	strip.begin();
	strip.show();
}

void lampSet(int theLamp, unsigned long theColor)
{
//	strip.setPixelColor(theLamp, theColor | (theColor << 16)); // | (theColor << 8) not.
	strip.setPixelColor(theLamp, theColor | (theColor << 8) | (theColor << 16));
}

unsigned long lampGet(int theLamp)
{
	strip.getPixelColor(theLamp);
}

void lampsShow()
{
    strip.show();
}
// end all smart LED stuff
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
ring5:GND
ring5:VCC
ring5:DIN
ring5:DOUT