#include "util.h"

FASTLED_USING_NAMESPACE

#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif

#define LED_PIN    3

#define LED_TYPE WS2812  //PL9823
#define COLOR_ORDER GRB
//#define NUM_LEDS 125

int animationSpeed = 45;
int counter=10;
int analogin = A0;

uint8_t BRIGHTNESS;

//#define BRIGHTNESS          64
#define FRAMES_PER_SECOND  120
char logp[50];


void setup() {
  delay(3000); // 3 second delay for recovery
 Serial.begin(57600);
  
 Serial.println("resetting"); 
  // tell FastLED about the LED strip configuration
 FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
 
 pinMode(analogin, INPUT);
  // set master brightness control
  BRIGHTNESS = 64;
 // FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear();
 // PCintPort::attachInterrupt(A0, isr, CHANGE);
  //attachInterrupt (digitalPinToInterrupt (analogin), changeEffect, CHANGE); // pressed
//  attachPCINT(digitalPinToPCINT(analogin), isr, CHANGE);

}



void isr() {
 BRIGHTNESS=map(analogRead(analogin),0,1023,10,255);
 sprintf(logp,"intr Brightness: %d",BRIGHTNESS);
 Serial.println(logp);
   FastLED.setBrightness(  BRIGHTNESS );
 }
 
//static uint8_t p = 1;

void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } }
static uint8_t hue=0;

void loop() {


SetBrightness();

for(int i=0;i < 125;i++){
  //leds[i] = CHSV(hue++,255,255); 

  leds[i] = CHSV(100,255,255); 
  // leds.fill_rainbow(hue++);
  FastLED.show();
   FastLED.delay(10);
   }

//theaterChaseRainbow(150);   
   
counter=40;
//very first 
//colorfade();
colorfade_hue(5);

raining(350,false);

counter=5;SetBrightness();

planarSpin(); counter=5;
SetBrightness();
  
fountian(); counter=10;

 //trifade(); counter=200;
 SetBrightness();

 sinelon(); 
 counter=10;
 SetBrightness();
 
//  shiftSquares(); counter=10;
//  tunnel(); counter=10;
// SetBrightness();
 raining(450,false);
 chaseTheDot(); counter=10;
 SetBrightness();
 
planarFlop3D(); counter=10;
  //fountian(); counter=10;
  SetBrightness();
 
 // random_led(60,200);
// rainbow(400,25);
 //colorfade();
 }

void colorfade_hue(uint8_t cycles){
    //loop rain process
 for(int cycle=0;cycle< cycles;cycle++){
  for(uint8_t i=0;i < 255;i++){
    //hue++;
  fill_solid(leds, NUM_LEDS, CHSV(i, 255, 128));
  
  FastLED.show();
  FastLED.delay(20);
  }
 }
}


void theaterChaseRainbow(int SpeedDelay) {

  byte *c;
  for (int j=0; j < 20; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 5; q++) {
        for (int i=0; i < NUM_LEDS; i=i+3) {
       //   c = Wheel( (i+j) % 255);
       //     c = random8( (uint8_t)(i+j) % 255);
         CRGB col = CHSV(random8(),255,255);
          leds[i+q] = col;
          //setPixel(i+q, col.r, col.g, col.b);    //turn every third pixel on
       //   setPixel(i+q, *c, *(c+1), *(c+2));    //turn every third pixel on
        }

//        showStrip();

    FastLED.show();
    
        FastLED.delay(SpeedDelay);
        for (int i=0; i < NUM_LEDS; i=i+3) {
          leds[i+q]=0;
         // setPixel(i+q, 0,0,0);        //turn every third pixel off
        }
    }
  }
}


//color fade example
void colorfade(){
///color fade test rgb
  //start from red
  for( int colorStep=0; colorStep <= 255; colorStep++ ) {

  int r = 255;
  int g = 0;
  int b = colorStep;

  // Now loop though each of the LEDs and set each one to the current color
  for(int x = 0; x < NUM_LEDS; x++){
      leds[x] = CRGB(r,g,b);
  }

  // Display the colors we just set on the actual LEDs
      FastLED.delay(1); 
      FastLED.show();
      }

    //into blue
      for( int colorStep=255; colorStep >= 0; colorStep-- ) {

      int r = colorStep;
      int g = 0;
      int b = 255;

      // Now loop though each of the LEDs and set each one to the current color
      for(int x = 0; x < NUM_LEDS; x++){
          leds[x] = CRGB(r,g,b);
      }

      // Display the colors we just set on the actual LEDs
  FastLED.delay(1); 
  FastLED.show();
  }

//start from blue
  for( int colorStep=0; colorStep <= 255; colorStep++ ) {

      int r = 0;
      int g = colorStep;
      int b = 255; 

      // Now loop though each of the LEDs and set each one to the current color
      for(int x = 0; x < NUM_LEDS; x++){
          leds[x] = CRGB(r,g,b);
      }

      // Display the colors we just set on the actual LEDs
  FastLED.delay(1); 
  FastLED.show();
  }

//into green
  for( int colorStep=255; colorStep >= 0; colorStep-- ) {

      int r = 0;
      int g = 255;
      int b = colorStep; 

      // Now loop though each of the LEDs and set each one to the current color
      for(int x = 0; x < NUM_LEDS; x++){
          leds[x] = CRGB(r,g,b);
      }

      // Display the colors we just set on the actual LEDs
  FastLED.delay(1); 
  FastLED.show();
  }

//start from green
  for( int colorStep=0; colorStep <= 255; colorStep++ ) {

      int r = colorStep;
      int g = 255;
      int b = 0;

      // Now loop though each of the LEDs and set each one to the current color
      for(int x = 0; x < NUM_LEDS; x++){
          leds[x] = CRGB(r,g,b);
      }

      // Display the colors we just set on the actual LEDs
  FastLED.delay(1); 
  LEDS.show();
  }

}



void raining(int cycles,bool isRainbow) {
byte rain_[NUM_LEDS] = {0};
uint8_t speed_ = 1;
// Matrix size
uint8_t NUM_ROWS = 25;
uint8_t NUM_COLS = 5;

const uint8_t mapping[125] = {
  100,101,102,103,104, 
  79, 78,77,76,75,
  50, 51,52,53,54,  
  29, 28,27,26,25,
  0, 1,2,3,4,
    
  105, 106,107,108,109,
  84, 83,82,81,80,
  55, 56,57,58,59,
  34, 33,32,31,30,
  5, 6,7,8,9,
  
  110,111,112,113,114,
  89,88,87,86,85,
  60,61,62,63,64,
  39,38,37,36,35,
  10,11,12,13,14,
  
  115,116,117,118,119,
  94,93,92,91,90,
  65,66,67,68,69,
  44,43,42,41,40,
  15,16,17,18,19,
  
  120,121,122,123,124,
  95,96,97,96,95,
  70,71,72,73,74,
  49,48,47,46,45,
  20,21,22,23,24,
};

//initialize rain data
 for (int i = 0; i < NUM_LEDS; i++) {
   if (random8(20) == 0) {
      rain_[i] = 1;  //random8(20) number of dots. decrease for more dots
    }
    else {
      rain_[i] = 0;
    }
  }

 //get a random color
 CRGB cl = CHSV(random8(), 255, 255);   //get a randon color

  //loop rain process
 for(int cycle=0;cycle< cycles;cycle++){
  
  if(isRainbow) 
   cl = CHSV(random8(), 255, 255);   //get a randon color

 for (byte i = 0; i < NUM_COLS; i++) {
   for (byte j = 0; j < NUM_ROWS; j++) {
      byte layer = rain_[XY(i, ((j + speed_ + random8(2) + NUM_ROWS) % NUM_ROWS))];   //fake scroll based on shift coordinate
      // random8(2) add glitchy look
      if (layer) {
        uint8_t temp = XY((NUM_COLS - 1) - i, (NUM_ROWS - 1) - j);
        leds[mapping[temp]] = cl;//CHSV(250, 255, BRIGHTNESS);
       // leds[temp] = CHSV(250, 255, BRIGHTNESS);
       // sprintf(logp,"XY = %d,layer=%d",temp ,mapping[temp]);
       // Serial.println(logp);
        
      }
    }
  }

  speed_ ++;
  fadeToBlackBy(leds, NUM_LEDS, 40);
  blurRows(leds, NUM_COLS, NUM_ROWS, 16);      //if you want
    
  FastLED.show();
  
  FastLED.delay(60);
  
  uint8_t rand1 = random8 (NUM_LEDS);
  uint8_t rand2 = random8 (NUM_LEDS);
  if ((rain_[rand1] == 1) && (rain_[rand2] == 0) )   //simple get two random dot 1 and 0 and swap it,
  {
    rain_[rand1] = 0;  //this will not change total number of dots
    rain_[rand2] = 1;
  }
  }   
 
}


uint16_t XY (uint8_t x, uint8_t y) {
  //return (x * NUM_ROWS + y);
uint16_t i =0;
   if( y & 0x01) {
      // Odd rows run backwards
      uint8_t reverseX = (5 - 1) - x;
      i = (y * 5) + reverseX;
    } else {
      // Even rows run forwards
      i = (y * 5) + x;
    }
    return i;
}

/*
void rainbow(int cycles, int speed){ // TODO direction
  for(int j =0;j < cycles;j++ ) {
  //fadeToBlackBy( leds, NUM_LEDS, 40);
  //int i = random16(NUM_LEDS);
  //leds[i] += CHSV( random8(), 255, 255);
  for(hue=0;hue < 255;){
   leds.fill_rainbow(hue++);
   FastLED.delay(speed);
  }
  //FastLED.show();
  //FastLED.delay(speed);
  }
}*/
// Wipes color from end to end
void colorWipe(CRGB c, int speed)
{
  for(int i=0; i<NUM_LEDS; i++)
    {
      leds[i] = c;
    }
   
    FastLED.show();
    delay(speed);
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
CRGB Wheel(byte WheelPos) {
  if(WheelPos < 85) {
    return CRGB(WheelPos * 3, 255 - WheelPos * 3, 0);
  } 
  else if(WheelPos < 170) {
    WheelPos -= 85;
    return CRGB(255 - WheelPos * 3, 0, WheelPos * 3);
  } 
  else {
    WheelPos -= 170;
    return CRGB(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

CRGB randomColor(){
  return Wheel(random(256)); 
}

void SetBrightness(){
BRIGHTNESS=map(analogRead(analogin),0,1023,10,255);
   FastLED.setBrightness(  BRIGHTNESS );
 sprintf(logp,"Brightness: %d",BRIGHTNESS);
 Serial.println(logp);  
 }
/*
void rain() {

// counter = 50;
  uint8_t x,y;
  CRGB templed[25]=0;
  while (counter--) {
  CRGB color = randomColor();//CRGB(random8(),random8(),random8());  
     //  shift(NEG_Y);
    uint8_t numDrops = random8(8, 26);
    for (uint8_t i = 0; i < numDrops; i++) 
    {
      drawLed(color,random8(0,5),random8(0,5),4);
      }
      
      flushBuffer();
      for(uint8_t p=0;p < 25;p++)
       {
         templed[p] = leds[(100 + p)];
       }
      fadeToBlackBy( leds, NUM_LEDS, 128);
      //FastLED.clear();
      delay(120);
     
      for(int8_t z=3;z >= 0;z--){ 
       for(uint8_t p=0;p<25;p++)
       {

         leds[((z*25) + p)] = templed[p];
         sprintf(logp,"%d,",((z*25) + p));
         Serial.print(logp);
       }
      
       //drawLed(color,x,y,z);
        flushBuffer();
        fadeToBlackBy( leds, NUM_LEDS, 128);
       //  FastLED.clear();
       delay(120); 
      }
    }
  
}*/

void planarSpin() {
  
  int spinsPerColor = 5; // a spin is actually half a revolution
  
  while (counter--) {
    CRGB color = randomColor();//CRGB(random8(),random8(),random8());
    int x = 0;
    int y = 0;
    for (int i = 0; i < spinsPerColor; i++) {
      for (int x = 0; x <= 4; x++) {
        drawLine(color,x,0,0,4-x,4,0);
        drawLine(color,x,0,1,4-x,4,1);
        drawLine(color,x,0,2,4-x,4,2);
        drawLine(color,x,0,3,4-x,4,3);
        drawLine(color,x,0,4,4-x,4,4);
        flushBuffer();
        clearBuffer();
        delay(animationSpeed);
      }
      for (int y = 0; y <= 4; y++) {
        drawLine(color,4,y,0,0,4-y,0);
        drawLine(color,4,y,1,0,4-y,1);
        drawLine(color,4,y,2,0,4-y,2);
        drawLine(color,4,y,3,0,4-y,3);
        drawLine(color,4,y,4,0,4-y,4);
        flushBuffer();
        clearBuffer();
        delay(animationSpeed);
      }
    }
    color = nextColor(color);
  }
 
}

/********************************** FOUNTIAN **********************************\
| Light shoots up the middle of the cube then once it reaches the top fall     |
| back down on the outside of the cube. After it hits the bottom it changes    |
| color and starts again                                                       |
|                                                                              |
| Written By: Asher Glick                                                      |
\******************************************************************************/
void fountian() {
  continuePattern = false;
  CRGB color = randomColor();//CRGB(random8(),random8(),random8());
//  int animationSpeed = 150;
  while (counter--) {
    for (int z = 4; z >= 0; z--) {
      drawLed(color,2,2,z);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed+30);
    }
    for (int z = 0; z <= 4; z++) {
      drawBoxWalls(color,1,1,z,3,3,z);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed+30);
    }
    for (int z = 4; z >= 0; z--) {
      drawBoxWalls(color,0,0,z,4,4,z);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed+30);
    }
    color=nextColor(color);
  }
}
uint8_t gHue = 0;
void confetti() 
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, NUM_LEDS, 10);
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( gHue + random8(64), 200, 255);
}

void sinelon()
{
  while (counter--) {
      CRGB color = randomColor();//CRGB(random8(),random8(),random8());
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, NUM_LEDS, 20);
  uint8_t pos = beatsin16( 13, 0, NUM_LEDS-1 );
  leds[pos] += color;
  flushBuffer();
  FastLED.delay(60);
  }
}


void trifade() {
  
 
 
uint8_t r,g,b;
  while (counter--) {
    // blue fade out, red fade in
//clearBuffer(10);
  CRGB color = randomColor();//CRGB(random8(),random8(),random8());
  for(int i = 0; i < NUM_LEDS; i++ ) 
  leds[i] = color;
//sinelon(color);
 
     fadeToBlackBy( leds, NUM_LEDS, 120);
    // clearBuffer(40);
   flushBuffer();
     delay(120);

  /*  for (int i = 1; i <= 4; i++)// {
     // drawBox(CRGB(random8(),random8(),random8()),9-i,0,0,0,3,3,3);
      drawBox(CRGB(random8(),random8(),random8()),i,0,0,0,4,4,4);
      flushBuffer();
      clearBuffer(64);
      delay(animationSpeed);
    }*/
  /*  // red fade out, green fade in
    for (int i = 1; i <= 8; i++) {
      //drawBox(CRGB(random8(),random8(),random8()),9-i,0,0,0,3,3,3);
      drawBox(CRGB(random8(),random8(),random8()),i,0,0,0,4,4,4);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    // green fade out, blue fade in
    for (int i = 1; i <= 8; i++) {
     // drawBox(CRGB(random8(),random8(),random8()),9-i,0,0,0,3,3,3);
      drawBox(CRGB(random8(),random8(),random8()),i,0,0,0,4,4,4);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }*/
  }
  
}

/******************************** SHIFT SQUARES *******************************\
| Three 2x2x2 squares start on the cube each a red green or blue. then they    |
| randomly move around the cube one at a time, if they crash into each other   |
| then then both leds turn on and while they occupy the same space they apear  |
| a different color                                                            |
|                                                                              |
| Written By: Asher Glick                                                      |
\******************************************************************************/
void shiftSquares() {
  CRGB color = CRGB(random8(),random8(),random8());
 animationSpeed = 200;
  
  int blx = 3; // blue x
  int bly = 0; // blue y
  int blz = 0; // blue z
  
  int rdx = 0; // red x
  int rdy = 3; // red y
  int rdz = 0; // red z
  
  int gnx = 0; // green x
  int gny = 0; // green y
  int gnz = 3; // green z

  int wnx = 0; // green x
  int wny = 0; // green y
  int wnz = 2; // green z
  
  int * mover = &blx;
 // continuePattern = true;
  
  while(counter--) {
    switch (random(0,9)) {
      case 0: mover = &blx; break;
      case 1: mover = &bly; break;
      case 2: mover = &blz; break;
      case 3: mover = &rdx; break;
      case 4: mover = &rdy; break;
      case 5: mover = &rdz; break;
      case 6: mover = &gnx; break;
      case 7: mover = &gny; break;
      case 8: mover = &gnz; break;
    }
    *mover = (((*mover)+3)%4)-1;
    drawBox(CRGB(random8(),random8(),random8()) ,abs(blx),abs(bly),abs(blz),abs(blx)+1,abs(bly)+1,abs(blz)+1);
    drawBox(CRGB(random8(),random8(),random8())  ,abs(gnx),abs(gny),abs(gnz),abs(gnx)+1,abs(gny)+1,abs(gnz)+1);
    drawBox(CRGB(random8(),random8(),random8()),abs(rdx),abs(rdy),abs(rdz),abs(rdx)+1,abs(rdy)+1,abs(rdz)+1);
    flushBuffer();
   // clearBuffer();
     FastLED.clear();
    delay(animationSpeed);
    *mover = (((*mover)+3)%4)-1;
    drawBox(CRGB(random8(),random8(),random8()) ,abs(blx),abs(bly),abs(blz),abs(blx)+1,abs(bly)+1,abs(blz)+1);
    drawBox(CRGB(random8(),random8(),random8())  ,abs(gnx),abs(gny),abs(gnz),abs(gnx)+1,abs(gny)+1,abs(gnz)+1);
    drawBox(CRGB(random8(),random8(),random8()),abs(rdx),abs(rdy),abs(rdz),abs(rdx)+1,abs(rdy)+1,abs(rdz)+1);
    flushBuffer();
   // clearBuffer();
     FastLED.clear();
    delay(animationSpeed*2);
  }
}

/*********************************** TUNNEL ***********************************\
|
\******************************************************************************/
void tunnel() {
  continuePattern = false;
  CRGB color = CRGB(random8(),random8(),random8());
//  int animationSpeed =100;
  
  CRGB color1[]  = {CRGB(random8(),random8(),random8()),
  CRGB(random8(),random8(),random8()),
  CRGB(random8(),random8(),random8()),
  CRGB(random8(),random8(),random8()),
  CRGB(random8(),random8(),random8()),
  CRGB(random8(),random8(),random8()),
  CRGB(random8(),random8(),random8()),
  CRGB(random8(),random8(),random8())};
  int bright1[] = {2,4,6,8,2,4,6,8};
  //int color2[]  = {B,B,B,B,R,R,R,R};
//int bright2[] = {6,4,2,0,6,4,2,0};
  int bright2[] = {8,6,4,2,8,6,4,2};
  
  int index[]   = {0,1,2,3,4,5,6,7};
  counter=200;
  while (counter--) {
    drawBoxWalls(color1[index[0]],bright1[index[0]],1,1,0,2,2,0);
  //  drawBoxWalls(color1[index[0]],bright2[index[0]],1,1,0,2,2,0);
    drawBoxWalls(color1[index[1]],bright1[index[1]],1,1,1,2,2,1);
  //  drawBoxWalls(color1[index[1]],bright2[index[1]],1,1,1,2,2,1);
    drawBoxWalls(color1[index[2]],bright1[index[2]],1,1,2,2,2,2);
  //  drawBoxWalls(color1[index[2]],bright2[index[2]],1,1,2,2,2,2);
    drawBoxWalls(color1[index[3]],bright1[index[3]],1,1,3,2,2,3);
   // drawBoxWalls(color1[index[3]],bright2[index[3]],1,1,3,2,2,3);
     drawBoxWalls(color1[index[3]],bright2[index[3]],1,1,4,2,2,4);


      drawBoxWalls(color1[index[4]],bright1[index[4]],0,0,4,4,4,4);
    drawBoxWalls(color1[index[4]],bright1[index[4]],0,0,3,4,4,4);
  //  drawBoxWalls(color1[index[4]],bright2[index[4]],0,0,3,3,3,3);
    drawBoxWalls(color1[index[5]],bright1[index[5]],0,0,2,4,4,2);
  //  drawBoxWalls(color1[index[5]],bright2[index[5]],0,0,2,3,3,2);
    drawBoxWalls(color1[index[6]],bright1[index[6]],0,0,1,4,4,1);
  //  drawBoxWalls(color1[index[6]],bright2[index[6]],0,0,1,3,3,1);
    drawBoxWalls(color1[index[7]],bright1[index[7]],0,0,0,4,4,0);
  //  drawBoxWalls(color1[index[7]],bright2[index[7]],0,0,0,3,3,0);
    
    
    flushBuffer();
    clearBuffer();
    for (int i = 0; i < 8; i++){
      //index[i] = index[i]==7?0:index[i]+1;
      index[i] = (index[i]+1)%8;
    }
    delay(animationSpeed+70);
    
  }
}
/******************************** CHASE THE DOT *******************************\
| A single point of light moves around the cube randomly and changes colors    |
| when it tries to go out of bounds                                            |
|                                                                              |
| Inspired By: Jonah Glick                                                     |
| Written By: Asher Glick                                                      |
\******************************************************************************/
void chaseTheDot() {
  continuePattern = false;
  CRGB color = randomColor();//CRGB(random8(),random8(),random8());
 // int animationSpeed = 100;
  
  int xpos = 0;
  int ypos = 0;
  int zpos = 0;
  counter = 200;
  while (counter--) {
    switch(random(0,6)) {
      case 0:
        if (xpos > 0) {xpos--;break;}
        else color=nextColor(color);
      case 1:
        if (xpos < 4) {xpos++;break;}
        else color=nextColor(color);
        xpos--; break;
        
      case 2:
        if (ypos > 0) {ypos--;break;}
        else color=nextColor(color);
      case 3:
        if (ypos < 4) {ypos++;break;}
        else color=nextColor(color);
        ypos--; break;
      
      case 4:
        if (zpos > 0) {zpos--;break;}
        else color=nextColor(color);
      case 5:
        if (zpos < 4) {zpos++;break;}
        else color=nextColor(color);
        zpos--; break;
    }
    drawLed(color,xpos,ypos,zpos);
    flushBuffer();
    clearBuffer();
    delay(animationSpeed+20);
  }
}
/********************************* PLANAR FLOP ********************************\
| 
\******************************************************************************/
/******************************* PLANAR FLOP 3D *******************************\
| Version 2 of the planar flop, doing more complicated maths and 3D vectors    |
| 'n stuff. Making this function found the bug of reversed z axis line drawing |
\******************************************************************************/
void planarFlop3D() {
  continuePattern = false;
  CRGB color = randomColor();//CRGB(random8(),random8(),random8());
  
 // int animationSpeed = 150;
  
  while (counter--) {
  color = randomColor();//CRGB(random8(),random8(),random8());  
    for (int y = 4; y>=0; y--){
      for (int z = 0; z <= 4; z++) drawLine(color,0,4,z,4,y,z);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    for (int x = 4; x >= 0; x--) {
      for (int z = 0; z <= 4; z++) drawLine(color,0,4,z,x,0,z);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    
    
    for (int x = 0; x <= 4; x++) {
      for (int y = 0; y <= 4; y++) drawLine(color,0,y,0,x,y,4);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    for (int z = 4; z >= 0; z--) {
      for (int y = 0; y <= 4; y++) drawLine(color,0,y,0,4,y,z);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    
    for (int z = 0; z <= 4; z++) {
      for (int x = 0; x <= 4; x++) drawLine(color,x,0,0,x,4,z);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    for (int y = 4; y >= 0; y--) {
      for (int x = 0; x <= 4; x++) drawLine(color,x,0,0,x,y,4);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    
    for (int y = 0; y <= 4; y++) {
      for (int z = 0; z <= 4; z++) drawLine(color,4,0,z,0,y,z);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    for (int x = 0; x <= 4; x++) {
      for (int z = 0; z <= 4; z++) drawLine(color,4,0,z,x,4,z);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    
    for (int x = 4; x >= 0; x--) {
      for (int y = 0; y <= 4; y++) drawLine(color,4,y,4,x,y,0);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    for (int z = 0; z <= 4; z++) {
      for (int y = 0; y <= 4; y++) drawLine(color,4,y,4,0,y,z);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    
    for (int z = 4; z >= 0; z--) {
      for (int x = 0; x <= 4; x++) drawLine(color,x,4,4,x,0,z);
     flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    } 
    for (int y = 0; y <= 4; y++) {
      for (int x = 0; x <= 4; x++) drawLine(color,x,4,4,x,y,0);
      flushBuffer();
      clearBuffer();
      delay(animationSpeed);
    }
    color = nextColor(color);
  }
}

void random_trail(){
//fill_solid(leds, NUM_LEDS, CRGB::Black);  
for (uint8_t j=0; j < NUM_LEDS; j++)
{
// leds[random8(125)] = CRGB(random8(125),random8(),random8());
  leds[j]  = randomColor();//CRGB(random8(),random8(),random8());
  FastLED.show();
//  fadeall();
 // i = i++;
 fadeToBlackBy( leds, NUM_LEDS, 40);  
   delay(40);
}
}

void fillplain(CRGB color){
 
  
  
}

  

void random_led(int idelay, uint8_t loopcount){
  
 // Serial.print("random_led starts\n");
  do{
leds[random8(125)] = CRGB(random8(),random8(),random8());
 // leds[i]  = CRGB(random8(125),random8(),random8());
  FastLED.show();
//  fadeall();
 // i = i++;
 fadeToBlackBy( leds, NUM_LEDS, 100);
 delay(idelay);
  }
 while(loopcount--);  
// Serial.print("random_led end\n");
}