/*                                          Basic Receiving
Name: Joshua Adams
Date: 4/22/24
Purpose of program:  To control whether certain functions run or not.

Instructions:
  Conditional statements allow the function to run if the value is 1

To-Do:
 - Finish getting all of the parse functions set up with genric
   attributes for future use and under the right function 
   within parser.h
*/

//********libraries********
//****LEDS****
#include <Arduino.h>
#include <FastLED.h>
#include "parser.h"
#include "ledgfx.h"
#include <LittleFS.h>
#include <FS.h>

#define FORMAT_LITTLEFS_IF_FAILED true

//****LED Definitions****
  #define numleds 50
  #define ledpin 33

//****LEDS****
  CRGB leds[numleds] = {0};
  
  int maxbrightness = 40;
  uint8_t fadeBy;
//  
//Function Control  
  int primaryFunction = -1;
  int secondaryFunction = 1;
  int tertiaryFunction = -1;
//
//Color Assignment
    byte r1, g1, b1;  //Function1
    byte r2, g2, b2;  //Function2
    byte r3, g3, b3;  //Function3
//hue    
  byte hue1, hue2, hue3;
//addToRGB
    byte ra1, ga1, ba1;  //Function1
    byte ra2, ga2, ba2;  //Function2
    byte ra3, ga3, ba3;  //Function3
//subtractFromRGB
    byte rs1, gs1, bs1;  //Function1
    byte rs2, gs2, bs2;  //Function2
    byte rs3, gs3, bs3;  //Function3
//delays
    byte f1Delay1, f1Delay2, f1Delay3;  //Function1
    byte f2Delay1, f2Delay2, f2Delay3;  //Function2
    byte f3Delay1, f3Delay2, f3Delay3;  //Function3
//Brightness Control
  //On/Off - Controls use of brightness in the function
  uint8_t bright1, bright2, bright3;    
  //Value
  uint8_t f1Brightness, f2Brightness, f3Brightness;

//Time
  unsigned long serialReadStart;
  double timeAtLast;
  double timeSinceLast;
  double hour;
  
struct parse 
{
  int space[10][1];
  int dash[10][1];
  int hash[10][1];

};


void SetHue(int hue) {
  for(int i = 0; i < numleds; i++) { leds[i].setHue(hue);}
  FastLED.show();
 }

void SetAll(int function, byte red, byte green, byte blue) {
    for(int i = 0; i < numleds; i++) {
      leds[i].r = red;
      leds[i].g = green;
      leds[i].b = blue;
    }
    FastLED.show();
  }

void SetAll(byte red, byte green, byte blue) {
    for(int i = 0; i < numleds; i++) {
      leds[i].r = red;
      leds[i].g = green;
      leds[i].b = blue;
    }
    FastLED.show(); 
   } 


void ChasingHazzard() {
    int ledPos = 25;
  int length = 20;

  for(int i = 0; i <= length; i++) {   
    leds[ledPos + i].setRGB(r3,g3,b3);  // set:candle,rgb:#,#:#
    leds[ledPos - i].setRGB(r3,g3,b3);  // set:candle,rgb:#,#:#
    for(int j = 0; j <= length; j++)
      leds[ledPos + j].CRGB::addToRGB(3);
    for(int l = 0; l <= length; l++)
        leds[ledPos - l].CRGB::addToRGB(3);

      delay(f3Delay1);
    FastLED.show();    
    }
  while(leds->getLuma() > 0) {
  for(int k = 0; k <= numleds; k++) {
    leds[(ledPos-length) + k].CRGB::subtractFromRGB(rs3);
    leds[(ledPos+length) - k].CRGB::subtractFromRGB(rs3);
      }
    }
  }


void CandleFlame(byte cRed,byte cGreen, byte cBlue) {
  //bright yellow r,g,b = 255,255,0
  uint8_t myRandom;
  RandomNum(myRandom);
  int ledPos = myRandom;
  for(int i = 0; i < 5; i++) {   
    leds[ledPos + i].setRGB(r2,g2,b2);  // set:candle,rgb:#,#:#
    leds[ledPos - i].setRGB(r2,g2,b2);  // set:candle,rgb:#,#:#
    for(int j = 0; j <= i; j++){
      //leds[j].CRGB::addToRGB(3);
      leds[j].r + ra2;  // set:candle,add:#
      leds[j].g + ga2;  // set:candle,add:#
      leds[j].b + ba2;  // set:candle,add:#
    }
      delay(f2Delay1);
    FastLED.show();
    }
  for(int k = 0; k <= numleds; k++) {
    leds[k].CRGB::subtractFromRGB(5);
    }
  }

void WhiteFlameBackup(byte fRed, byte fGreen, byte fBlue)  { 
  for(int i = 0; i < numleds; i++) {  //loop #1 Drawing one led and moving to the nexr loop
    leds[i].r = r2;
    leds[i].g = g2;
    leds[i].b = b2;
  for(int j = 0; j <= i; j++)  //Lop through only what the main loop has drawn so not to draw past the fade. Adds one pixel per cycle
    leds[j].CRGB::addToRGB(ra1);  //Adding one per cycle along with additional brightness to each pixel previously drawn appears to fade in
    FastLED.show();
    delay(f1Delay1);
  }
  while(leds->getLuma() > 0) {  //  loop #3
    for(int k = 0; k <= numleds - 1; k++) 
        leds[k].CRGB::subtractFromRGB(rs1); // loop #4 Causes the fade out due to he 3 getting higher on each iteration, for at he end it's almost faded all ou5
        FastLED.show();
        delay(f1Delay2);      
    }  
 }

void WhiteFlame(byte fRed, byte fGreen, byte fBlue)  { 
  for(int i = 0; i < numleds; i++) {  //loop #1 Drawing one led and moving to the nexr loop
      leds[i].r = fRed;
      leds[i].g = fGreen;
      leds[i].b = fBlue;
    for(int j = 0; j < numleds; j++)  //loop #2 assigning brightness 0 to j and iterating to 50
      leds[j].CRGB::addToRGB(2)+leds[j+1].CRGB::addToRGB(1);  // Due to drawing one led and raising the brightness by 3 each step it appears to fade in
      FastLED.show();
      delay(f1Delay1);
    }
    //Serial.println("Light: "+String(leds->getLuma()));
    //while(leds->getLuma() > 0) {  //  loop #3
    //  for(int k = 0; k <= numleds - 1; k++) 
    //      leds[k].CRGB::subtractFromRGB(2); // loop #4 Causes the fade out due to he 3 getting higher on each iteration, for at he end it's almost faded all ou5
    //      FastLED.show();
    //      delay(f1Delay2);      
    //}
      for(int k = 0; k <= numleds - 1; k++) {
        leds[k].r = leds[k].r;
        leds[k].g = leds[k].g;
        leds[k].b = leds[k].b;
        for(int l = 0; l <= numleds; l++) {
          leds[l].CRGB::subtractFromRGB(3)+leds[l+1].CRGB::subtractFromRGB(1);
        }
        FastLED.show();
        delay(f1Delay2);
      }
  }



void setup() {
  //Serial.setTimeout(3000);
    Serial.begin(115200);
    delay(500);
    Serial.println("Starting Serial Communications");
    ulong quitter = Serial.getTimeout();
    Serial.println("Serial Timeout is: "+String(quitter));
    Serial.println("Setting up defined pins");
  //LEDS
    pinMode(ledpin, OUTPUT);
    //pinMode(LED_BUILTIN, OUTPUT);
    delay(100);
    Serial.println("Setting up LED Constructor");
  //LED_CONSTRUCTOR
    FastLED.addLeds<WS2812B, ledpin, GRB>(leds, numleds);
    Serial.println("Setting up Power Limits");
  //LED_POWERLIMITER
    //set_max_power_indicator_LED(LED_BUILTIN);
    FastLED.setMaxPowerInMilliWatts(900);
    Serial.println("Clearing LED's.");
    FastLED.clear();
    FastLED.show();
  //Variables
    f1Delay1 = 10;
    f1Delay2 = 10;
    f2Delay1 = 10;

    f3Delay1 = 10;

    hue1 = 64;

    r1 = 80;
    g1 = 80;
    b1 = 80;

    ra1 = 2;
    rs1 = 2;

    rs3 = 2;
    rs3 = 2;


    //r2 = 90;
    //g2 = 90;
  }
  

void loop() { 
  if(Serial.available() > 0) {
    readingSerial = true;
    ReadSerial();
    //ReadSerial2();
    }
  if(primaryFunction > 0) {
    if(bright1 == 1) {
        FastLED.setBrightness(f1Brightness);
      }
    WhiteFlameBackup(r1,g1,b1);
      }
  
  if(secondaryFunction > 0) {
    if(bright2 == 1) {  
        FastLED.setBrightness(f2Brightness);
      }
    CandleFlame(r2,g2,b2);
    }

  if(tertiaryFunction > 0) {
    if(bright3 == 1) {
        FastLED.setBrightness(f3Brightness);
      }
      
    }
  }