
#include "CubeAnimations.h"

CubeAnimations::CubeAnimations(
  LedCube myCube,
  unsigned char throttle = 50,
  unsigned int duration = 15000):
  myCube(myCube),
  speed(throttle),
  duration(duration){

};

void CubeAnimations::start(void){
  myCube.reset();
  myCube.start();
}

void CubeAnimations::stop(void){
  myCube.reset();
}

void CubeAnimations::setSpeed(unsigned char throttle){
  speed = constrain(throttle, 0, 100);
}

void CubeAnimations::setDuration(unsigned int duration){
  duration = constrain(duration, 0, 100);
}

bool CubeAnimations::isRunning(void){
  return millis() <= effect_ende;
}

void CubeAnimations::startAnimation(void){
  effect_ende = millis() + duration;
}
void CubeAnimations::wait(unsigned long time){
  delay((time * speed)/ 100);
}

void CubeAnimations::glow(void){
  startAnimation();
  unsigned char glow = 0;
  bool glow_up;
  while (isRunning()){
    if (glow == 0){
      glow_up = true;
    } else if (glow == myCube.shades()) {
      glow_up = false;
    }
    glow_up ? glow++ : glow--;
    myCube.fill(glow);
    wait(200);
  }
}

void CubeAnimations::glitter(unsigned char filling = 50){
  startAnimation();
  filling = constrain(filling, 0, 100);
  unsigned char value;
  while (isRunning()){
    for (byte x = 0; x < myCube.size(); x++) {
      for (byte y = 0; y < myCube.size(); y++) {
        for (byte z = 0; z < myCube.size(); z++) {
          value = random(100) < filling ? myCube.shades() : 0;
          myCube.pixel(x,y,z, value);
        }
      }
    }
    wait(100);
  }
}

void CubeAnimations::shaded_glitter(unsigned char filling = 50){
  startAnimation();
  filling = constrain(filling, 0, 100);
  unsigned char value;
  while (isRunning()){
    for (byte x = 0; x < myCube.size(); x++) {
      for (byte y = 0; y < myCube.size(); y++) {
        for (byte z = 0; z < myCube.size(); z++) {
          value = random(100) < filling ? random(myCube.shades() + 1) : 0;
          myCube.pixel(x,y,z, value);
        }
      }
    }
    wait(100);
  }
}

void CubeAnimations::dimed_glitter(unsigned char filling = 50){
  startAnimation();
  filling = constrain(filling, 0, 100);
  // (total_leds * filling) / (100 * shades)
  // (125 * 50) / (100 * 8) = 7
  unsigned char update_count = (myCube.size()^3 * 100) / (filling * myCube.shades());
  unsigned char x,y,z;

  while (isRunning()){
    myCube.shade(-1);
    for (unsigned char n=0;n<=update_count;n++){
      x = random(myCube.size());
      y = random(myCube.size());
      z = random(myCube.size());
      myCube.pixel(x,y,z, random(myCube.shades() + 1));
    }
    wait(100);
  }
}
