#include "LED.h"


LEDRing::LEDRing() {
  breathBrightness = BREATH_MIN;
  lastUpdate = 0;
}

void LEDRing::begin() {
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);

  FastLED.setBrightness(LED_BRIGHTNESS);

  clear();
}

void LEDRing::update() {
  FastLED.show();
}

void LEDRing::clear() {
  fill_solid(
    leds,
    NUM_LEDS,
    CRGB::Black);

  FastLED.show();
}

void LEDRing::off() {
  clear();
}

void LEDRing::setBrightness(uint8_t brightness) {
  FastLED.setBrightness(brightness);
}

void LEDRing::idle() {
  breathing();
}

void LEDRing::breathing() {
  breathBrightness =
    beatsin8(
      BREATH_SPEED,
      BREATH_MIN,
      BREATH_MAX);

  fill_solid(
    leds,
    NUM_LEDS,
    CHSV(
      FOCUS_HUE,
      255,
      breathBrightness));

  FastLED.show();
}

void LEDRing::progress(float percentage) {
  percentage =
    constrain(
      percentage,
      0.0,
      100.0);

  int completed =
    round(
      percentage * NUM_LEDS / 100.0);

  uint8_t breath =
    beatsin8(
      BREATH_SPEED,
      BREATH_MIN,
      BREATH_MAX);

  for (int i = 0; i < NUM_LEDS; i++) {
    if (i < completed) {
      leds[i] =
        CHSV(
          160,
          255,
          breath);
    } else {
      leds[i] =
        CHSV(
          160,
          255,
          2);
    }
  }

  FastLED.show();
}

void LEDRing::wakeAnimation() {
  clear();

  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CRGB::White;

    FastLED.show();

    delay(40);
  }

  delay(150);

  clear();
}

void LEDRing::pickupEffect() {
  for (int b = 20; b < 180; b += 10) {
    fill_solid(
      leds,
      NUM_LEDS,
      CRGB(b, b, b));

    FastLED.show();

    delay(10);
  }

  for (int b = 180; b > 20; b -= 10) {
    fill_solid(
      leds,
      NUM_LEDS,
      CRGB(b, b, b));

    FastLED.show();

    delay(10);
  }
}

void LEDRing::warningEffect() {
  for (int i = 0; i < 2; i++) {
    fill_solid(
      leds,
      NUM_LEDS,
      CRGB::Red);

    FastLED.show();

    delay(120);

    clear();

    delay(80);
  }
}

void LEDRing::completionEffect() {
  for (int i = 0; i < 4; i++) {
    fill_solid(
      leds,
      NUM_LEDS,
      CRGB::Green);

    FastLED.show();

    delay(150);

    clear();

    delay(120);
  }

  rainbowSpin();
}

void LEDRing::rainbowSpin() {
  for (int j = 0; j < 128; j++) {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] =
        CHSV(
          i * 16 + j * 3,
          255,
          180);
    }

    FastLED.show();

    delay(15);
  }

  clear();
}

void LEDRing::show() {
  FastLED.show();
}