#include <FastLED.h>

#define LED_PIN     9      // Pin where the matrix is connected
#define LED_COUNT   128    // Total number of LEDs (128 LEDs)
#define BRIGHTNESS  100    // Set brightness to 255 for full brightness
#define sensor 8           // Pin where the motion sensor is connected
#define COLOR_ORDER GRB    // Color order of the LEDs (usually GRB for RGB LEDs)
#define trig 7             // Trig pin connection
#define echo 6            // echo pin connection
int val = 0;
long duration;
int distance;
CRGB leds[LED_COUNT];  // Array to hold LED data

// Array of LED positions to light up (0-based indexing)
int Base[] = {3,4,10,13,17,22,25,30,33,38,41,46,50,53,59,60,67,68,74,77,81,86,89,94,97,102,105,110,114,117,123,124};

int Blink1[] = {10,11,12,13,17,22,25,30,33,38,41,46,50,51,52,53,74,75,76,77,81,86,89,94,97,102,105,110,114,115,116,117};
int Blink2[] = {17,18,19,20,21,22,25,30,33,38,41,42,43,44,45,46,81,82,83,84,85,86,89,94,97,102,105,106,107,108,109,110};
int Blink3[] = {25,26,27,28,29,30,33,34,35,36,37,38,89,90,91,92,93,94,97,98,99,100,101,102};

int joy1[] = {11,12,18,21,25,30,33,38,41,46,50,51,52,53,74,75,76,77,81,86,89,94,97,102,106,109,115,116};

int sad1[] = {10,11,12,13,17,22,25,30,33,38,42,45,51,52,75,76,82,85,89,94,97,102,105,110,114,115,116,117};

int angry1[] = {25,26,27,28,29,30,33,34,35,36,37,38,89,90,91,92,93,94,97,98,99,100,101,102};
int angry2[] = {21,22,25,27,28,35,38,41,42,43,44,45,46,81,82,83,84,85,86,89,93,99,100,102,105,106};
int angry3[] = {5,6,9,11,19,22,25,29,33,36,38,41,43,44,47,48,54,58,59,60,61,62,65,66,67,68,69,73,79,80,83,84,86,89,91,94,98,102,105,108,116,118,121,122};

int pensive1[] = {14,17,18,19,20,27,28,30,33,37,41,42,43,44,45,46,53,54,73,74,81,82,83,84,85,86,90,94,97,99,100,107,108,109,110,113};
int pensive2[] = {14,18,19,27,28,29,35,36,37,41,42,43,53,54,73,74,84,85,86,90,91,92,98,99,100,108,109,113};
int pensive3[] = {14,17,29,35,41,42,43,84,85,86,92,98,110,113};

int dead1[] = {27, 28, 35, 36, 91, 92, 99, 100};
int dead2[] = {18, 21, 27, 28, 35, 36, 42, 45, 82,85, 91, 92, 99, 100, 106, 109};
int dead3[] = {9,14,18,21,27,28,35,36,42,45,49,54,73,78,82,85,91,92,99,100,106,109,113,118};
int dead4[] = {0, 7, 9,14,18,21,27,28,35,36,42,45,49,54, 56, 63, 64, 71, 73,78,82,85,91,92,99,100,106,109,113,118, 120, 127};

void setup() {
  FastLED.addLeds<WS2812, LED_PIN, COLOR_ORDER>(leds, LED_COUNT);  // Setup for WS2812 (NeoPixel) type LED
  FastLED.setBrightness(BRIGHTNESS);  // Set the brightness 
  // Clear the LEDs initially
  FastLED.clear();  
  FastLED.show();
  pinMode(sensor, INPUT); // PIR motion sensor as an Input
  pinMode(trig, OUTPUT); // Sets the trigPin as an Output
  pinMode(echo, INPUT); // Sets the echoPin as an Input
}


void blinkblink(){
  FastLED.clear(); //Clears the previous inputs
  for (int i = 0; i < sizeof(Blink3) / sizeof(Blink3[0]); i++) {
    leds[Blink3[i]] = CRGB(0, 255, 0);  // Set the LED at position to green (RGB: 0, 255, 0)
  }
  FastLED.show(); // Update the LEDs after all changes
  delay(50); 

  FastLED.clear();
  for (int i = 0; i < sizeof(Blink2) / sizeof(Blink2[0]); i++) {
    leds[Blink2[i]] = CRGB(0, 255, 0);  
  }
  FastLED.show();  
  delay(50);

  FastLED.clear();
  for (int i = 0; i < sizeof(Blink1) / sizeof(Blink1[0]); i++) {
    leds[Blink1[i]] = CRGB(0, 255, 0);  
  }
  FastLED.show();  
  delay(50);

  FastLED.clear();
  for (int i = 0; i < sizeof(Base) / sizeof(Base[0]); i++) {
    leds[Base[i]] = CRGB(0, 255, 0);  
  }
  FastLED.show();  
  delay(3000);

  FastLED.clear();
  for (int i = 0; i < sizeof(Blink1) / sizeof(Blink1[0]); i++) {
    leds[Blink1[i]] = CRGB(0, 255, 0);  
  }
  FastLED.show(); 
  delay(50);

  FastLED.clear();
  for (int i = 0; i < sizeof(Blink2) / sizeof(Blink2[0]); i++) {
    leds[Blink2[i]] = CRGB(0, 255, 0);  
  }
  FastLED.show();
  delay(50);
}


void joyful(){
  FastLED.clear();
  for (int i = 0; i < sizeof(Blink3) / sizeof(Blink3[0]); i++) {
    leds[Blink3[i]] = CRGB(225, 255, 0);  // Set the LED at position to Yellow (RGB: 255, 255, 0)
  }
  FastLED.show();
  delay(100);

  FastLED.clear();
  for (int i = 0; i < sizeof(Blink2) / sizeof(Blink2[0]); i++) {
    leds[Blink2[i]] = CRGB(225, 255, 0);
  }
  FastLED.show();
  delay(100);

  FastLED.clear();
  for (int i = 0; i < sizeof(joy1) / sizeof(joy1[0]); i++) {
    leds[joy1[i]] = CRGB(225, 255, 0); 
  }
  FastLED.show(); 
  delay(3000);

  FastLED.clear();
  for (int i = 0; i < sizeof(Blink2) / sizeof(Blink2[0]); i++) {
    leds[Blink2[i]] = CRGB(225, 255, 0); 
  }
  FastLED.show(); 
  delay(100); 
}


void sad(){
  FastLED.clear();
  for (int i = 0; i < sizeof(Blink3) / sizeof(Blink3[0]); i++) {
    leds[Blink3[i]] = CRGB(0, 0, 225);  // Set the LED at position to Blue (RGB: 0, 0, 225)
  }
  FastLED.show();  
  delay(100);

  FastLED.clear();
  for (int i = 0; i < sizeof(Blink2) / sizeof(Blink2[0]); i++) {
    leds[Blink2[i]] = CRGB(0, 0, 225); 
  }
  FastLED.show();  
  delay(100);

  FastLED.clear();
  for (int i = 0; i < sizeof(sad1) / sizeof(sad1[0]); i++) {
    leds[sad1[i]] = CRGB(0, 0, 225);  
  }
  FastLED.show();  
  delay(3000);

  FastLED.clear();
  for (int i = 0; i < sizeof(Blink2) / sizeof(Blink2[0]); i++) {
    leds[Blink2[i]] = CRGB(0, 0, 225);
  }
  FastLED.show();  
  delay(100);
}

void angry(){
  FastLED.clear();
  for (int i = 0; i < sizeof(angry1) / sizeof(angry1[0]); i++) {
    leds[angry1[i]] = CRGB(255, 0, 0);  // Set the LED at position to Red (RGB: 255, 0, 0)
  }
  FastLED.show(); 
  delay(100);

  FastLED.clear();
  for (int i = 0; i < sizeof(angry2) / sizeof(angry2[0]); i++) {
    leds[angry2[i]] = CRGB(255, 0, 0); 
  }
  FastLED.show();  
  delay(100);

  FastLED.clear();
  for (int i = 0; i < sizeof(angry3) / sizeof(angry3[0]); i++) {
    leds[angry3[i]] = CRGB(255, 0, 0);
  }
  FastLED.show();  
  delay(3000);

  FastLED.clear();
  for (int i = 0; i < sizeof(angry2) / sizeof(angry2[0]); i++) {
    leds[angry2[i]] = CRGB(255, 0, 0);  
  }
  FastLED.show();
  delay(100);
}

void pensive(){
  FastLED.clear();
  for (int i = 0; i < sizeof(pensive3) / sizeof(pensive3[0]); i++) {
    leds[pensive3[i]] = CRGB(160, 32, 240);  // Set the LED at position to Purple (160, 32, 240)
  }
  FastLED.show();  
  delay(3000);

  FastLED.clear();
  for (int i = 0; i < sizeof(pensive2) / sizeof(pensive2[0]); i++) {
    leds[pensive2[i]] = CRGB(160, 32, 240);  
  }
  FastLED.show();  
  delay(100);

  FastLED.clear();
  for (int i = 0; i < sizeof(pensive1) / sizeof(pensive1[0]); i++) {
    leds[pensive1[i]] = CRGB(160, 32, 240);  
  }
  FastLED.show();  
  delay(3000);

  FastLED.clear();
  for (int i = 0; i < sizeof(pensive2) / sizeof(pensive2[0]); i++) {
    leds[pensive2[i]] = CRGB(160, 32, 240); 
  }
  FastLED.show();  
  delay(100);
}

void dead(){
  FastLED.clear();
  for (int i = 0; i < sizeof(dead1) / sizeof(dead1[0]); i++) {
    leds[dead1[i]] = CRGB(128, 0, 32); // Set the LED at position to Burgundy (128, 0, 32)
  }
  FastLED.show();  
  delay(100);

  FastLED.clear();
  for (int i = 0; i < sizeof(dead2) / sizeof(dead2[0]); i++) {
    leds[dead2[i]] = CRGB(128, 0, 32);  
  }
  FastLED.show(); 
  delay(100);

  FastLED.clear();
  for (int i = 0; i < sizeof(dead3) / sizeof(dead3[0]); i++) {
    leds[dead3[i]] = CRGB(128, 0, 32);  
  }
  FastLED.show();  
  delay(100);

  FastLED.clear();
  for (int i = 0; i < sizeof(dead4) / sizeof(dead4[0]); i++) {
    leds[dead4[i]] = CRGB(128, 0, 32);  
  }
  FastLED.show(); 
  delay(1000);
}


void loop() {
  //Angry if there is motion
  val = digitalRead(sensor);   
  if (val == 1){
    angry();
  }
  //Expression based on candy level
  else{
    // Clears the trigPin
    digitalWrite(trig, LOW);
    delayMicroseconds(2);
    // Sets the trigPin on HIGH state for 10 micro seconds
    digitalWrite(trig, HIGH);
    delayMicroseconds(10);
    digitalWrite(trig, LOW);
    // Reads the echoPin, returns the sound wave travel time in microseconds
    duration = pulseIn(echo, HIGH);
    // Calculating the distance (in cm)
    distance = duration * 0.034 / 2;

    //Expression based on distance
    if (distance > 13){
      dead();
    }else if (distance >  9){
      pensive();
    }else if (distance > 6){
      sad();
    }else if (distance > 3){
      blinkblink();
    }
    else{
      joyful();
    }
  }
}
