#include <Adafruit_NeoPixel.h>
#include <microLED.h>

union MRGB {
  uint8_t raw [3];
  struct {
    uint8_t r;
    uint8_t g;
    uint8_t b;
    uint8_t w;
  };
};

const uint8_t n_Stripes = 7;
const uint32_t n_Leds = 40;

Adafruit_NeoPixel a_strip[8];
// MRGB ** a_matrix;
MRGB a_matrix[8][44];
// uint32_t ** a_matrix;


void Projectorize() {
  // Adafruit_NeoPixel * __a_strip
  // MRGB * ** __src, 
 
 
    // int nN = sizeof(*__a_strip);
    int nN = n_Stripes;
    int nM = n_Leds;
    
     // Adafruit_NeoPixel a_s = * __a_strip;
     // MRGB ** a_d = * __src;
    // a_s[ random() % nN ].setPixelColor(random() % nM, 255, 0, 0);

    for (int n=0; n<nN; n++) {

      // Serial.print("N: " + String(n)+";"); 

      for (int m=0; m<nM; m++) {
        
        a_strip[n].setPixelColor(m,
          // random() & 0xff, 0, 0
          random() & 0xff,
          a_matrix[n][m].r,
          0 // a_matrix[n][m].g, a_matrix[n][m].b
        );
        
      }
    }
    // a_s[ random() % nN ].setPixelColor(random() % nM, 255, 0, 0);

     // Serial.println("N: " + String(nN));    

}

void Show() {

  for (int n=0; n<n_Stripes; n++) {
    a_strip[n].show();
  }

}

void setup() {
  // Serial.begin(115200);
  Serial.begin(115200);
  Serial.println("--- debug started.");    

  // strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRB + NEO_KHZ800);
  
  
  /*
  a_matrix = new MRGB*[n_Stripes];
  for (int n=0; n<n_Stripes; n++) {
    a_matrix[n] = (MRGB *)malloc(1001);

  }
  */

  /*
  a_matrix = new MRGB*[n_Stripes];
  for (int n=0; n<n_Stripes; n++) {
    a_matrix[n] = new MRGB[n_Leds];

  }
  */
  
  // a_strip = new Adafruit_NeoPixel[n_Stripes];

  for (int n=0; n<n_Stripes; n++) {
    // a_strip[i]. = new  Adafruit_NeoPixel(N_LEDS, 1+i, NEO_GRB + NEO_KHZ800);
    
    a_strip[n].setPin(3+n);
    a_strip[n].updateLength(n_Leds);
    a_strip[n].updateType(NEO_GRB + NEO_KHZ800);    
    // setBrightness(uint8_t);

/*
  void setPin(int16_t p);
  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
  void setPixelColor(uint16_t n, uint32_t c);
  void fill(uint32_t c = 0, uint16_t first = 0, uint16_t count = 0);
  void setBrightness(uint8_t);
  void clear(void);
  void updateLength(uint16_t n);
  void updateType(neoPixelType t);    
*/
    a_strip[n].begin();
  }
 

  Serial.println("leds: " + String (a_strip[0].numPixels()) );    

}

void loop() {

  // Serial.println("loopS" );    
  // int n = random() % n_Stripes;
  // int m = random() % n_Leds;
  // a_matrix[n][m].r = random() & 0xff;


    int nN = n_Stripes;
    int nM = n_Leds;

    for (int n=0; n<nN; n++) {
      for (int m=0; m<nM; m++) {
        a_matrix[n][m].r = random() & 0xff;
      }
    }


// & a_matrix, 
  Projectorize();
  Show();

  // Serial.println("loopF" );    

  delay(1000 / 5);

  return;

  chase(a_strip[0].Color(255, 0, 0)); // Red
  chase(a_strip[0].Color(0, 255, 0)); // Green
  chase(a_strip[0].Color(0, 0, 255)); // Blue
}

static void chase(uint32_t c) {

  for (int n=0; n<n_Stripes; n++) {

  Serial.println("line: " + String(n) );    

  for(uint16_t i=0; i<a_strip[n].numPixels()+4; i++) {
      a_strip[n].setPixelColor(i  , c); // Draw new pixel
      a_strip[n].setPixelColor(i-4, 0); // Erase pixel a few steps back
      a_strip[n].show();
      delay(25);
  }
  }
}