#include <Arduino.h>
#include <SevSeg.h>
#include "UniqueNumber.h"

SevSeg sevSeg;
const uint8_t numDigits = 2;
const uint8_t digitPins[] = {10, 11};
const uint8_t segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9};

const uint8_t generateButtonGPIO = A4;
const uint8_t resetButtonGPIO = A5;

UniqueNumber<uint8_t, 99> uniqueNumber;

void generateNumber() {
  if (uniqueNumber.available()) {
    uint8_t number = uniqueNumber.generateRandomNumber();
    sevSeg.setNumber(number);
    Serial.print("Current Number: "); Serial.print(number);
    Serial.print(" / Available Numbers: "); Serial.println(uniqueNumber.available());
  } else {
    Serial.println("No more numbers available! Please press RESET-Button");
    sevSeg.setChars("--");
  }
}

void reset() {
  uniqueNumber.clear();
  sevSeg.blank();
  Serial.print("The numbers have been reset. You can generate ");
  Serial.print(uniqueNumber.available());
  Serial.println(" new random numbers again.");
}

void handleGenerateButton() {
  static bool lastState;

  bool currentState = digitalRead(generateButtonGPIO);
  bool stateDidNotChange = currentState == lastState;
  if (stateDidNotChange) return;
  lastState = currentState;

  bool isPressed = currentState == LOW;
  if (isPressed) generateNumber();
}

void handleResetButton() {
  static bool lastState;

  bool currentState = digitalRead(resetButtonGPIO);
  bool stateDidNotChange = currentState == lastState;
  if (stateDidNotChange) return;
  lastState = currentState;

  bool isPressed = currentState == LOW;
  if (isPressed) reset();
}

void handleButtons() {
  handleGenerateButton();
  handleResetButton();
}

void setupDisplay() {
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_CATHODE; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = true; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist or isn't connected

  sevSeg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint);
  sevSeg.setBrightness(90);
  sevSeg.blank();
}

void setupButtons() {
  pinMode(generateButtonGPIO, INPUT_PULLUP);
  pinMode(resetButtonGPIO, INPUT_PULLUP);
}

void showWelcomeMessage() {
  Serial.println("Press \"Generate\" to generate a new unique random number out of 100 available numbers (0 to 99).");
  Serial.println("Press \"Reset\" if no more numbers are available to start from the beginning.");
}

void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(A0));
  setupButtons();
  setupDisplay();
  showWelcomeMessage();
}

void loop() {
  sevSeg.refreshDisplay();
  handleButtons();
}