#include <OneButton.h>
#include <RotaryEncoder.h>
#include <Adafruit_NeoPixel.h>

RotaryEncoder encoder(A3, A2, RotaryEncoder::LatchMode::TWO03);

int pin         =  3; 
int numPixels   = 16; // Popular NeoPixel ring size
#define MAX_SLIDE_POT_ANALOG_READ_VALUE 1024

//#define selectSW1 9
int mode;
const int modes = 4;
int analogSliderValues[modes];
bool Muted[modes] = {false, false, false, false};
const int Mute = 0;
static int pos = 250;
int newPos = 250;
static int pos1 = 250;
int newPos1 = 250;
static int pos2 = 250;
int newPos2 = 250;
static int pos3 = 250;
int newPos3 = 250;
OneButton button(9, true);

byte setPos = 0;




int pixelFormat = NEO_GRB + NEO_KHZ800;


Adafruit_NeoPixel *pixels;
void setup() {
  button.attachClick(singleclick);                  // link the function to be called on a singleclick event.
  button.attachLongPressStop(longclick); 
  //pinMode(selectSW1, INPUT_PULLUP);
  Serial.begin(9600);

  // You may have to modify the next 2 lines if using other pins than A2 and A3
  PCICR |= (1 << PCIE1);                      // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
  PCMSK1 |= (1 << PCINT10) | (1 << PCINT11); 

  pixels = new Adafruit_NeoPixel(numPixels, pin, pixelFormat);

  
  pixels->begin();  // This enables the interrupt for pin 2 and 3 of Port C.
}  // setup()



ISR(PCINT1_vect) {
  encoder.tick();  // just call tick() to check the state.
}  // ISR


// Read the current position of the encoder and print out when changed.
void loop() {

  button.tick();

  if (mode == 1) {
   
    Line1();
  }

   if (mode == 2)  {
    
    Line2();
  }
  if (mode == 3)  {
   
    Line3();
  }
  if (mode == 4)  {
    
    Line4();
  }
  String p1=":";
//Serial.println(newPos + p1 + newPos1 + p1 + newPos2 + p1 + newPos3 + p1 + mode);




switch(mode){

case 1:{
if(!Muted[0]){
  analogSliderValues[0] = newPos;
}
  else{
analogSliderValues[0] = Mute;

  }
}

case 2:{
if(!Muted[1]){
  analogSliderValues[1] = newPos1;
  
  }
  else{
analogSliderValues[1] = Mute;

  }
}

case 3:{
if(!Muted[2]){
  analogSliderValues[2] = newPos2;}
  else{
analogSliderValues[2] = Mute;
  }
}

case 4:{
if(!Muted[3]){
  analogSliderValues[3] = newPos3;}
  else{
analogSliderValues[3] = Mute;
  }
}
}
pixels->show();

switch(setPos){

 case 1:{
int value_pot_a = pos;
  int num_leds_switchedon = map(value_pot_a, 0, MAX_SLIDE_POT_ANALOG_READ_VALUE, 0, numPixels - 1);  

 
 for (int i = 0; i < num_leds_switchedon; ++i) {
    pixels->setPixelColor(i, pixels->Color(150, 150, 150));
  }  
  // LEDs are switched off which correspond to the area right of the slide knob
  for (int i = num_leds_switchedon; i < numPixels - 1; ++i) {
    pixels->setPixelColor(i, pixels->Color(0, 0, 0));
  }
  if(Muted[0]){
pixels->setPixelColor(15, pixels->Color(255, 0, 0));
  }
  if(!Muted[0]){
pixels->setPixelColor(15, pixels->Color(0, 0, 0));   
  }
  pixels->show();
  break;
}

case 2:{
 int value_pot_a = pos1;
  int num_leds_switchedon = map(value_pot_a, 0, MAX_SLIDE_POT_ANALOG_READ_VALUE, 0, numPixels - 1);  

 
 for (int i = 0; i < num_leds_switchedon; ++i) {
    pixels->setPixelColor(i, pixels->Color(150, 150, 0));
  }  
  // LEDs are switched off which correspond to the area right of the slide knob
  for (int i = num_leds_switchedon; i < numPixels - 1; ++i) {
    pixels->setPixelColor(i, pixels->Color(0, 0, 0));
  }
  if(Muted[1]){
pixels->setPixelColor(15, pixels->Color(255, 0, 0));
  }
  if(!Muted[1]){
pixels->setPixelColor(15, pixels->Color(0, 0, 0));   
  }
  pixels->show();
  break;
}
case 3:{
 int value_pot_a = pos2;
  int num_leds_switchedon = map(value_pot_a, 0, MAX_SLIDE_POT_ANALOG_READ_VALUE, 0, numPixels - 1);  

 
 for (int i = 0; i < num_leds_switchedon; ++i) {
    pixels->setPixelColor(i, pixels->Color(0, 0, 150));
  }  
  // LEDs are switched off which correspond to the area right of the slide knob
  for (int i = num_leds_switchedon; i < numPixels - 1; ++i) {
    pixels->setPixelColor(i, pixels->Color(0, 0, 0));
  }
  if(Muted[2]){
pixels->setPixelColor(15, pixels->Color(255, 0, 0));
  }
  if(!Muted[2]){
pixels->setPixelColor(15, pixels->Color(0, 0, 0));   
  }
  pixels->show();
  break;
}
case 4:{
 int value_pot_a = pos3;
  int num_leds_switchedon = map(value_pot_a, 0, MAX_SLIDE_POT_ANALOG_READ_VALUE, 0, numPixels - 1);  

  // The first NeoPixel in a strand is #0, second is 1, all the way up
  // to the count of pixels minus one.
  //for(int i=0; i<numPixels; i++) { // For each pixel...

    // pixels->Color() takes RGB values, from 0,0,0 up to 255,255,255
    // Here we're using a moderately bright green color:
    //pixels->setPixelColor(i, pixels->Color(255, 255, 0));
 for (int i = 0; i < num_leds_switchedon; ++i) {
    pixels->setPixelColor(i, pixels->Color(150, 0, 0));
  }  
  // LEDs are switched off which correspond to the area right of the slide knob
  for (int i = num_leds_switchedon; i < numPixels - 1; ++i) {
    pixels->setPixelColor(i, pixels->Color(0, 0, 0));
  }
  if(Muted[3]){
pixels->setPixelColor(15, pixels->Color(255, 0, 0));
  }
  if(!Muted[3]){
pixels->setPixelColor(15, pixels->Color(0, 0, 0));   
  }
  pixels->show();
  break;
}

}
//pixels->show();


sendSliderValues();
printSliderValues();
}  // loop ()



/**** Print 1st setting on Line1 ***/
void Line1() {
  if (setPos != 1){
  setPos = 1;
  encoder.setPosition(pos);
  }
  newPos = encoder.getPosition();
  if (pos != newPos) {
    //printPos(newPos,0);
    //newPos = map(newPos, 0, 128, 0, 1024);
    pos = newPos;
  }
}  //Line1 ()


/**** Print 2nd setting on Line2 ***/
void Line2() {
 if (setPos != 2){
    setPos = 2;
    encoder.setPosition(pos1);
 }
  newPos1 = encoder.getPosition();
  if (pos1 != newPos1) {
    //printPos(newPos1,1);
    //newPos1 = map(newPos1, 0, 128, 0, 1024);
    pos1 = newPos1;

  }
}  //Line2 ()

void Line3() {
 if (setPos != 3){
    setPos = 3;
    encoder.setPosition(pos2);
 }
  newPos2 = encoder.getPosition();
  if (pos2 != newPos2) {
    //printPos(newPos1,1);
    //newPos2 = map(newPos2, 0, 128, 0, 1024);
    pos2 = newPos2;
  }
}  //Line2 ()

void Line4() {
 if (setPos != 4){
    setPos = 4;
    encoder.setPosition(pos3);
 }
  newPos3 = encoder.getPosition();
  if (pos3 != newPos3) {
    //printPos(newPos1,1);
    //newPos3 = map(newPos3, 0, 128, 0, 1024);
    pos3 = newPos3;
  }
}  //Line2 ()

void sendSliderValues() {
  String builtString = String("");

  for (int i = 0; i < mode; i++) {
    builtString += String((int)analogSliderValues[i]);

    if (i < mode - 1) {
      builtString += String("|");
    }
  }
  
  Serial.println(builtString);
}

void printSliderValues() {
  for (int i = 0; i < modes; i++) {
    String printedString = String("Slider #") + String(i + 1) + String(": ") + String(analogSliderValues[i]) + String(" mV");
    Serial.write(printedString.c_str());

    if (i < modes - 1) {
      Serial.write(" | ");
    } else {
      Serial.write("\n");
    }
  }
}

void singleclick(){  
mode++;
      if (mode == 5) {
      mode = 1;
      }                              // what happens when the button is clicked                             // turn off the gren led
}
 
void longclick(){ 
                                  // what happens when buton is long-pressed
switch(mode){
      case 1:{
        Muted[0] = !Muted[0];
        break;
      }
      case 2:{
         Muted[1] = !Muted[1];
        break;
      }
      case 3:{
         Muted[2] = !Muted[2];
        break;
      }
      case 4:{
         Muted[3] = !Muted[3];
        break;
}
      
      }            
}