/** Advanced Traffic Light
 *  @author Torin Zaugg
 *  @date 02/12/2018
 *  @comments Working with Arduino UNO
 */

int lamps[] = {3, 5, 6, 8, 9, 10, 11}; //This array contains the pins of all the LEDs

//Define the pins for all of the LEDs.
//NS = North/South. EW = East/West
#define GreenNS 3
#define YellowNS 5
#define RedNS 6
#define GreenEW 8
#define YellowEW 9
#define RedEW 10
#define Walk 11

//Define the pin for the switch
#define Button 2

//Variables for time information
int cycleTime = 5000;             //This is how long the light cycle is. Setting it larger makes the lights longer.
int yellowTime = (cycleTime/3);   //This is how long the yellow light is on for. Set 3 to 4 to make yellow lights longer.

boolean doWalkCycle = false;      //This variable is set to true when when the switch is pressed.

/*
 * The setup function - this code is only ran once
 * Use it to setup the interrupt from the butotn, set the direction of the LED pins and button pin
 */
void setup() {
  /*
   * attachInterrupt() tells the arduino to run a function each time the button is pressed (this is called an interrupt.
   * It takes 3 parameters:
   * The first is the pin that triggers the interrupt
   * The second is the name of the function to run
   * The thrid is what to watch for - falling is the pin going to ground, rising is the pin going to +5V.
   */
  attachInterrupt(digitalPinToInterrupt(Button), toggleButton, FALLING);

  //Set the direction for all the LEDs by cycling though the array with a for loop.
  for (int i = 0; i < 7; i = i + 1){
    pinMode(lamps[i], OUTPUT);
  }

  //Set the direction of the switch.
  pinMode(Button, INPUT);

  //Turn all the LEDs off by cycling though the array with a for loop.
  for (int i = 0; i < 7; i = i + 1){
    digitalWrite(lamps[i], LOW);
  }

}

/*
 * The toggleButton() sequence
 * This code runs whenever the button is pressed
 */
void toggleButton(){
  doWalkCycle = true; //Makes the variable doWalkCycle true.
}

/*
 * The loop function - this code is run repeatedly
 */
void loop() {
  //In this condition, the walk light should be turned on with the NS green LED.
  if(doWalkCycle){
    digitalWrite(RedNS, LOW);
    digitalWrite(YellowEW, LOW);
    digitalWrite(GreenNS, HIGH);
    digitalWrite(RedEW, HIGH);
    digitalWrite(Walk, HIGH);

    delay(cycleTime/2);

    //This flashes the walk light when it is about to change to yellow
    for(int i = 0; i < 4; i = i + 1){
      digitalWrite(Walk, LOW);
      delay(250);
      digitalWrite(Walk, HIGH);
      delay(250);
    }

    //Change to yellow and delay for the yellowTime
    digitalWrite(GreenNS, LOW);
    digitalWrite(Walk, LOW);
    digitalWrite(YellowNS, HIGH);
    delay(yellowTime);

    doWalkCycle = false;  //Set doWalkCycle back to false so you have to press the switch
                          //to run the walk cycle again.

  //In this condition the walk light is not turned on. Besides that it is the same as above.
  }else{
    digitalWrite(RedNS, LOW);
    digitalWrite(YellowEW, LOW);
    digitalWrite(GreenNS, HIGH);
    digitalWrite(RedEW, HIGH);

    delay(cycleTime);

    digitalWrite(GreenNS, LOW);
    digitalWrite(YellowNS, HIGH);

    delay(yellowTime);
  }

  digitalWrite(YellowNS, LOW);
  digitalWrite(RedEW, LOW);
  digitalWrite(RedNS, HIGH);
  digitalWrite(GreenEW, HIGH);

  delay(cycleTime);

  digitalWrite(GreenEW, LOW);
  digitalWrite(YellowEW, HIGH);

  delay(yellowTime);
}