/*
  Solution For:
  Arduino Forum
  Topics:   Can an arduino uno handle 14 switches?
  Category: LEDs and Multiplexing
  Link:     https://forum.arduino.cc/t/can-an-arduino-uno-handle-14-switches/1093502/9
    
  Sketch:   sketch.ino
  Created:  24-Feb-2023
  MicroBeaut (μB)
*/

/*
  File:        sketch.ino
  Created:     24-Feb-2023
  Description: MicroBeaut (μB) Sketch
*/

#include "MicroBeaut.h"

#define potPin A0
int potValue;                                   // Variable to store the potentiometer reading
const uint8_t numberOfSwitch = 14;              // Number of switches
bool switchStates[numberOfSwitch];              // Buffer to store switch states

const uint16_t timeDebounce = 10;               // Default debounce time in milliseconds
MicroBeaut_Debounce debounces[numberOfSwitch];  // Array of Debounce objects

uint8_t switchPins[] = {5, 4, 3, 2, A3, A2, A1, 12, 11, 10, 9, 8, 7, 6};  // Pins for the switches

const uint8_t numberOfPosition = 5;             // Number of selector positions
const int rawCountError = 102;                  // Raw count value for 10% error
int potSelections[] = {0, 256, 512, 767, 1023}; // Selector setting values
int selector = -1;                              // Variable to store the selector position
int prevSelector = -1;
bool commonState = false;                       // Variable to store the common state
bool prevState = false;

void setup() {
  Serial.begin(115200); // Initialize serial communication
  for (uint8_t index = 0; index < numberOfSwitch; index++) {
    pinMode(switchPins[index], INPUT_PULLUP);     // Set the pin mode for the switches
    debounces[index].setTimeDebounce(timeDebounce); // Set the debounce time delay for the switches
  }
  pinMode(LED_BUILTIN, OUTPUT);                   // Set the LED pin mode
}
/*
  Function: loop
  Description: The main execution loop that reads sensor inputs and handles device states.
*/
void loop() {
  potValue = analogRead(potPin);    // Read the value from the potentiometer
  prevSelector = selector;          // Store the previous selector position
  selector = PotSelector(potValue); // Get the current selector position from the potentiometer value
  if (selector != -1 && prevSelector != selector) {
    Serial.println("Selected Position: " + String(selector)); // Print the selected position if changed
  }
  commonState = false;              // Reset the common state flag
 
  for (uint8_t index = 0; index < numberOfSwitch; index++) {
    bool value = !digitalRead(switchPins[index]); // Read the state of the switch
    prevState = switchStates[index];              // Store the previous state of the switch
    switchStates[index] = debounces[index].readInput(value); // Update the debounced state of the switch
    commonState |= switchStates[index];           // Update the common state based on switch states
    if (switchStates[index] && !prevState) {
      Serial.println("Switch " + String(index + 1) + " Activated"); // Print when a switch is activated
    }
  }
 
  digitalWrite(LED_BUILTIN, commonState); // Control the LED based on the common state
 
  /*
    TODO: Add additional functionality here if needed
  */
}

/*
  Function: PotSelector
  Description: Determines the position of the potentiometer selector based on its input value.
  Parameters:
    - input: Input value from the potentiometer
  Returns:
    - Index of the selector position if found within the range of selector settings, else returns -1 for error.
*/
int PotSelector(int input) {
  potValue = analogRead(potPin); // Read the potentiometer value
  for (uint8_t index = 0; index < numberOfPosition; index++) {
    int potSelection = potSelections[index]; // Get the selector setting value
    if (potValue >= potSelection - numberOfPosition && potValue <= potSelection + numberOfPosition) {
      return index; // Match with selector setting considering error margin
    }
  }
  return -1; // No matching selector position found within the acceptable range, return error
}