// --------------------------------------------------------------------------------
/*

14 用 NeoPixel LED 製作激光武士刀
激光武士刀請參考 https://jasonworkshop.com/q1katana

[學習重點]

1. 認識 NeoPixel LED

2. 認識 Random 隨機數

3. 認識 Switch and Case

[挑戰]

- 隨意擴充武士刀的功能


Created by Jason on 14 Aug 2022.

*/
// --------------------------------------------------------------------------------

#include <Adafruit_NeoPixel.h>

Adafruit_NeoPixel ring = Adafruit_NeoPixel(20, 9); // 建立物件 (20 = LED 數量, 9 = Pin)

// Button
int buttonPin = 7;
int buttonState = 0; // Button 狀態

void setup() {
  ring.begin();
  ring.setBrightness(255); // 設定亮度 0 - 255
  ring.show(); // 將設定顯示出來

  randomAct(); // 隨機抽出武士刀子程式
  // rainbowCycle(10); // 彩虹滾動

}

void loop() {
  buttonState = digitalRead(buttonPin); // 讀取 Button 狀態
  if (buttonState == HIGH) {
    randomAct();
  }

  delay(50);
}

// 隨機抽出武士刀子程式
void randomAct() {
  int ran = random(1, 10);
  switch (ran) {
    case 1:
      color(255, 0, 0, 20); // 改變全刀顏色 (R, G, B, WaitMS) 紅
      break;
    case 2:
      color(255, 128, 0, 20); // 改變全刀顏色 (R, G, B, WaitMS) 橙
      break;
    case 3:
      color(255, 255, 0, 20); // 改變全刀顏色 (R, G, B, WaitMS) 黃
      break;
    case 4:
      color(0, 255, 0, 20); // 改變全刀顏色 (R, G, B, WaitMS) 綠
      break;
    case 5:
      color(0, 255, 255, 20); // 改變全刀顏色 (R, G, B, WaitMS) 青
      break;
    case 6:
      color(0, 0, 255, 20); // 改變全刀顏色 (R, G, B, WaitMS) 藍
      break;
    case 7:
      color(255, 0, 255, 20); // 改變全刀顏色 (R, G, B, WaitMS) 紫
      break;
    case 8:
      color(255, 255, 255, 20); // 改變全刀顏色 (R, G, B, WaitMS) 白
      break;
    case 9:
      colorRandom(20); // 全刀隨機變色
      break;
    case 10:
      rainbowCycle(10); // 彩虹滾動
      break;
    default:
      break;
  }
}

// 改變全刀顏色
void color(int R, int G, int B, int wait) {
  for (int i = 0; i < ring.numPixels(); i++) {
    ring.setPixelColor(i, ring.Color(R,G,B));
    ring.show();
    delay(wait);
  }

}

// 全刀隨機變色
void colorRandom(int wait) {
  for (int i = 0; i < ring.numPixels(); i++) {
    int r = random(0, 255);
    int g = random(0, 255);
    int b = random(0, 255);
    ring.setPixelColor(i, ring.Color(r,g,b));
    ring.show();
    delay(wait);
  }
}


// 彩虹滾動
void rainbowCycle(int wait) {
  int i, j;

  for (j = 0; j < 256 * 5; j++) {
    for (i = 0; i < ring.numPixels(); i++) {
      ring.setPixelColor(i, Wheel(((i * 256 / ring.numPixels()) + j) & 255));
    }
    ring.show();
    delay(wait);
  }
}

// 產生漸變顏色值
int32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return ring.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return ring.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return ring.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}