/*

//This program Toggle's a a tracing led to change in direction depending on a	Switch.

There's also 3Slide PotentioMeter changing RGB Value's.
And a single PotMeter Changing the speed of the led tracing.
I'am having a minor issue where i can't get the Geopixel Led circle to get collor adressed properly trough a single variable.

Bless this mess.
*/




#include <FastLED.h>
#define DATA_PIN 26
#define NUM_LEDS 16
CRGB leds[NUM_LEDS];

const int directionButton_Pin = 19;

const int redRGBLed_Pin = 16;
const int greenRGBLed_Pin = 4;
const int blueRGBLed_Pin = 0;

const int redPotMeterRead_Pin = 27;
const int greenPotMeterRead_Pin = 14;
const int bluePotMeterRead_Pin = 12;

const int interval_TriggerPotMeter_Pin = 25;

int redValue = 0;
int greenValue = 0;
int blueValue = 0;

int redValue_Before = 0;
int greenValue_Before = 0;
int blueValue_Before = 0;

int colorLed_Threshold = 5;

int current_Led = 0;
int led_Before;


bool directionState_Bool = HIGH;
bool directionState_Bool_Before = HIGH;

bool trigger_NextLed_Bool = LOW;
bool trigger_NextLed_Bool_Before = LOW;


#define redLed CRGB(255, 0, 0);
#define offLed CRGB(0, 0, 0);

CRGB colorLed = CRGB(redValue, greenValue, blueValue);
CRGB colorLed_Before = CRGB(0, 0, 0);

int redPotMeter_Value;
int greenPotMeter_Value;
int bluePotMeter_Value;

unsigned long millis_Before = 0;
unsigned long millis_Report_Before  = 0;

unsigned long trigger_Interval;

int interval_TriggerPotMeter_value;

int trigger_Interval_Before = 0;

int trigger_Interval_Threshold = 50;

int Report_Interval_Threshold = 500;

int interval  = 0;

void setSetup() {
  // Start Serial port
  Serial.begin(115200);

  pinMode(directionButton_Pin, INPUT_PULLUP);

  pinMode(interval_TriggerPotMeter_Pin, INPUT);

  pinMode(redPotMeterRead_Pin, INPUT);
  pinMode(greenPotMeterRead_Pin, INPUT);
  pinMode(bluePotMeterRead_Pin, INPUT);

  pinMode(redRGBLed_Pin, OUTPUT);
  pinMode(greenRGBLed_Pin, OUTPUT);
  pinMode(blueRGBLed_Pin, OUTPUT);

  //FASTLED leds obj
  FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, NUM_LEDS);
}

void readDirectionState_Bool() {
  directionState_Bool = digitalRead(directionButton_Pin);

  if (directionState_Bool != directionState_Bool_Before) {

    directionState_Bool_Before = directionState_Bool;

    if (directionState_Bool == HIGH) {
      Serial.println("Clockwise >>> " + String(current_Led));
    } else {
      Serial.println("Counterclockwise  <<< " + String(current_Led));
    }
  }
}


void readInterval_PotMeter() {
  interval_TriggerPotMeter_value = analogRead(interval_TriggerPotMeter_Pin);
  trigger_Interval = map(interval_TriggerPotMeter_value, 0, 4095, 200, 1000);
}


void readRed_PotMeter() {
  redPotMeter_Value = analogRead(redPotMeterRead_Pin);
  redValue = map(redPotMeter_Value, 0, 4095, 0, 255);
}

void readGreen_PotMeter() {
  greenPotMeter_Value = analogRead(greenPotMeterRead_Pin);
  greenValue = map(greenPotMeter_Value, 0, 4095, 0, 255);
}

void readBlue_PotMeter() {
  bluePotMeter_Value = analogRead(bluePotMeterRead_Pin);
  blueValue = map(bluePotMeter_Value, 0, 4095, 0, 255);
}

void  readRGB_Potmeter() {
  readRed_PotMeter();
  readGreen_PotMeter();
  readBlue_PotMeter();
}

void  read_PotMeters()  {
  readRGB_Potmeter();
  readInterval_PotMeter();
}

void  writeRGBLed()  {
  digitalWrite(redRGBLed_Pin, redValue);
  digitalWrite(greenRGBLed_Pin, greenValue);
  digitalWrite(blueRGBLed_Pin, blueValue);
}

void  writeLedCircle_High()  {
//  leds[current_Led] = colorLed;
	leds[current_Led]=	CRGB	(redValue, greenValue, blueValue);
//	leds[current_Led] = redLed;
	FastLED.show();	
  Serial.println("ledState = HIGH    -Led On-");
}

void  writeLedCircle_Low()  {
  leds[current_Led] = offLed;
	FastLED.show();
  Serial.println("ledState = LOW    -Led Off-");
}

void ledStateDefine() {
  unsigned long current_Millis = millis();
  if (current_Millis - millis_Before > trigger_Interval) {
    millis_Before = current_Millis;
    interval++;
    Serial.println("Interval = " + String(interval));


    if ((interval > 0) && (interval < 3)) {		
	   	writeLedCircle_High();		
    } else {
			writeLedCircle_Low();
			directionState_BoolBehavior();
      interval = 0;
			trigger_Interval = 1;
    }
  }
}

void directionState_BoolBehavior() {
  if (directionState_Bool == HIGH) {
    led_Before = current_Led;
    current_Led++;

    if (current_Led > 15) {
      current_Led = 0;
    }
  } else {
    led_Before = current_Led;
    current_Led--;

    if (current_Led < 0) {
      current_Led = 15;
    }
  }
  Serial.print("current_Led = ");
  Serial.println(String(current_Led));
}
 

void interval_Report() {
  if (labs(trigger_Interval - trigger_Interval_Before) > trigger_Interval_Threshold) {
    trigger_Interval_Before = trigger_Interval;
    Serial.println("trigger_Interval = ");
    Serial.println(String(trigger_Interval));
  }
}


void color_Report() {
	
  if (abs(redValue - redValue_Before) > colorLed_Threshold) {
    redValue_Before = redValue;
    Serial.println("redValue = " + String(redValue));
  }

  if (abs(greenValue - greenValue_Before) > colorLed_Threshold) {
    greenValue_Before = greenValue;
    Serial.println("greenValue = " + String(greenValue));
  }

  if (abs(blueValue - blueValue_Before) > colorLed_Threshold) {
    blueValue_Before = blueValue;
    Serial.println("blueValue = " + String(blueValue));
  }
	
  if (
		//|| =	Logical OR operator
    abs(colorLed.red - colorLed_Before.red) > colorLed_Threshold ||
    abs(colorLed.green - colorLed_Before.green) > colorLed_Threshold ||
    abs(colorLed.blue - colorLed_Before.blue) > colorLed_Threshold
  ) {
    colorLed_Before = colorLed;
    Serial.println("colorLed =");
    Serial.print("Red: ");
    Serial.print(colorLed.red);
    Serial.print(", Green: ");
    Serial.print(colorLed.green);
    Serial.print(", Blue: ");
    Serial.println(colorLed.blue);
  }
}

void  report()  {
  if  (millis() - millis_Report_Before > Report_Interval_Threshold)  {
    millis_Report_Before = millis();
		interval_Report();
    color_Report();
  }
}


void setup() {

setSetup();

}

void loop() {
  readDirectionState_Bool();

  read_PotMeters();

	CRGB colorLed = CRGB(redValue, greenValue, blueValue);

  writeRGBLed();

  ledStateDefine();

	color_Report();

  report();
}