// Alarm sketch 3: Advanced alarm techniques - The 'two argument' alarm handler

const u32 LEDS = 7;     // To size our arrays and loops
u32 periods[LEDS];      // How fast each is blinking
u32 alarms[LEDS];       // The alarm index for each 
u32 pins[LEDS] = {      // The actual pin numbers of the LEDs
  BODY_RGB_RED_PIN,
  BODY_RGB_GREEN_PIN,
  BODY_RGB_BLUE_PIN,
  NORTH_LED_PIN,
  SOUTH_LED_PIN,
  EAST_LED_PIN,
  WEST_LED_PIN
};

// A 'two argument' alarm handler.  
void allAlarmHandler(u32 when, void * arg) {
  u32 index = (u32) arg;    // We know arg is 'really' a u32, because that's
                            // what we passed in to Alarms.create, below.

  ledToggle(pins[index]);   // Toggle whatever pin we're dealing with
  Alarms.set(alarms[index], when+periods[index]); // And reschedule whichever alarm
}

void setup() {
  for (u32 i = 0; i < LEDS; ++i) { // Create all the alarms

    // Here we use the 'two argument' form of Alarms.create.  The
    // second argument officially must be a 'void *' -- a pointer to nothing? --
    // but actually we can 'sneak in' any value we want, so long as it fits
    // in 32 bits.  Here, we pass in the appropriate array index for each
    // particular alarm, allowing us to reuse the single handler, above.
    
    alarms[i] = Alarms.create(allAlarmHandler,(void*) i); 
    periods[i] = random(100,1000); // Pick random periods from 0.1sec-1.0sec
    Alarms.set(alarms[i], 0);      // Start everybody off right away.
  }
}

void loop() { 
  /* Nothing to do */
}
