/* 
LED cube diagram.
The numbers repersent 
what pins the LEDs are connected to.
             |   .......
             |   ...N...
2   5   8    | T ...A...
             |   ...N...
3   6   9    | T ...O...
             |   .......
4    7   10  | T ..USB..
*/


/*
Feel free to change any of this code to your liking
and ad on to it as much as you want.
*/

// Initialize the layer pins
int layer1 = 11;
int layer2 = 12;
int layer3 = 13;

// Initialize all the arays needed for the LED cube.
int columns[9] = { 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int layers[3] = { 11, 12, 13 };
int right[3] = { 2, 3, 4 };
int xMiddle[3] = { 5, 6, 7 };
int left[3] = { 8, 9, 10 };
int front[3] = { 4, 7, 10 };
int yMiddle[3] = { 3, 6, 9 };
int back[3] = { 2, 5, 8 };


void setup() {
  pinMode(layer1, OUTPUT);
  pinMode(layer2, OUTPUT);
  pinMode(layer3, OUTPUT);

  // Declare all the arays as output //
  for (int i = 0; i < 10; i++) {
    pinMode(columns[i], OUTPUT);
  }
  for (int i = 0; i < 10; i++) {
    pinMode(layers[i], OUTPUT);
  }
  for (int i = 0; i < 3; i++) {
    pinMode(right[i], OUTPUT);
  }
  for (int i = 0; i < 3; i++) {
    pinMode(xMiddle[i], OUTPUT);
  }
  for (int i = 0; i < 3; i++) {
    pinMode(left[i], OUTPUT);
  }
  for (int i = 0; i < 3; i++) {
    pinMode(front[i], OUTPUT);
  }
  for (int i = 0; i < 3; i++) {
    pinMode(yMiddle[i], OUTPUT);
  }
  for (int i = 0; i < 3; i++) {
    pinMode(back[i], OUTPUT);
  }
  // Declare all the layer pins as output //
  digitalWrite(layer1, LOW);
  digitalWrite(layer2, LOW);
  digitalWrite(layer3, LOW);
}
void loop() {
  // The numbers in the brackets are how many times the function will be ran.
  // For some reason, if you run cubeSwipe function by it's self, it might turn off after a while.

  cubeSwipe(3);
  //randomLed(50);
  spin(10);
}

void randomLed(int randomLedTimes) {
  int randomLedStart = 0;
  while (randomLedStart < randomLedTimes) {
    int randomLayer;
    int randomcolumns;
    randomLayer = random(0, 3);
    randomcolumns = random(0, 9);
    digitalWrite(layers[randomLayer], HIGH);
    digitalWrite(columns[randomcolumns], HIGH);
    delay(75);
    digitalWrite(layers[randomLayer], LOW);
    digitalWrite(columns[randomcolumns], LOW);
    delay(50);
    randomLedStart++;
  }
}

// This function will swipe all the axis of the cube
void cubeSwipe(int cubeSwipeTimes) {
  int cubeSwipeStart = 0;
  while (cubeSwipeStart < cubeSwipeTimes) {
    cubeSwipeStart++;
    // Swipe the Z axis of the cube
    for (int zTimes = 0; zTimes < 4; zTimes++) {
      for (int i = 0; i < 10; i++) {
        digitalWrite(columns[i], HIGH);
      }
      digitalWrite(layer3, HIGH);
      digitalWrite(layer2, LOW);
      digitalWrite(layer1, LOW);
      delay(100);
      digitalWrite(layer3, LOW);
      digitalWrite(layer2, HIGH);
      digitalWrite(layer1, LOW);
      delay(100);
      digitalWrite(layer3, LOW);
      digitalWrite(layer2, LOW);
      digitalWrite(layer1, HIGH);
      delay(100);
      digitalWrite(layer3, LOW);
      digitalWrite(layer2, HIGH);
      digitalWrite(layer1, LOW);
      delay(100);
    }
    delay(10);

    //  Swipe the X axis of the cube
    for (int i = 0; i < 10; i++) {
      digitalWrite(columns[i], LOW);
    }
    for (int xTimes = 0; xTimes < 4; xTimes++) {
      digitalWrite(layer1, HIGH);
      digitalWrite(layer2, HIGH);
      digitalWrite(layer3, HIGH);

      for (int x = 0; x < 3; x++) {
        digitalWrite(right[x], HIGH);
      }
      delay(100);
      for (int x = 0; x < 3; x++) {
        digitalWrite(right[x], LOW);
        digitalWrite(xMiddle[x], HIGH);
      }
      delay(100);
      for (int x = 0; x < 3; x++) {
        digitalWrite(xMiddle[x], LOW);
        digitalWrite(left[x], HIGH);
      }
      delay(100);
      for (int x = 0; x < 3; x++) {
        digitalWrite(left[x], LOW);
        digitalWrite(xMiddle[x], HIGH);
      }
      delay(100);
      for (int x = 0; x < 3; x++) {
        digitalWrite(xMiddle[x], LOW);
      }
    }
    delay(10);

    //  Swipe the Y axis of the cube
    for (int yTimes = 0; yTimes < 4; yTimes++) {
      digitalWrite(layer1, HIGH);
      digitalWrite(layer2, HIGH);
      digitalWrite(layer3, HIGH);

      for (int y = 0; y < 3; y++) {
        digitalWrite(front[y], HIGH);
      }
      delay(100);
      for (int y = 0; y < 3; y++) {
        digitalWrite(front[y], LOW);
        digitalWrite(yMiddle[y], HIGH);
      }
      delay(100);
      for (int y = 0; y < 3; y++) {
        digitalWrite(yMiddle[y], LOW);
        digitalWrite(back[y], HIGH);
      }
      delay(100);
      for (int y = 0; y < 3; y++) {
        digitalWrite(back[y], LOW);
        digitalWrite(yMiddle[y], HIGH);
      }
      delay(100);
      for (int y = 0; y < 3; y++) {
        digitalWrite(yMiddle[y], LOW);
      }
    }
  }
}

void spin(int rotations) {
  int rotationStart = 0;
  while (rotationStart < rotations) {
    rotationStart++;
    digitalWrite(6, HIGH);
    digitalWrite(layer1, HIGH);
    digitalWrite(layer2, HIGH);
    digitalWrite(layer3, HIGH);

    for (int i = 0; i < 4; i++) {
      digitalWrite(10 - i, HIGH);
      digitalWrite(2 + i, HIGH);
      delay(100);
      digitalWrite(10 - i, LOW);
      digitalWrite(2 + i, LOW);
    }
  }
}

void growingCube(){


}