#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Encoder.h> // Use the Encoder library

// Define OLED display size
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Rotary encoder pins using the Encoder library
Encoder encoder(4, 5);  // Replace with actual GPIO pin numbers for D2 and D3

// Buttons
const int redButtonPin = 5;
const int blueButtonPin = 6;

// Buzzer
const int buzzerPin = 7;

// Volume and mode variables
int volume = 2; // Set default volume to level 2
int currentCat = 0;
bool speakerOn = false;
long lastEncoderPos = -999; // To track changes in encoder position


int melody[] = {
  392, 440, 392, 349, 392, 330, 0,     
  294, 330, 294, 349, 392, 330, 0      
};

// Duration of each note (in ms)
int noteDurations[] = {
  250, 250, 250, 250, 250, 250, 250,   // Duration for first phrase
  250, 250, 250, 250, 250, 250, 250    // Duration for second phrase
};

void setup() {
  // Initialize serial for debugging
  Serial.begin(9600);
  
  // Initialize OLED display
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }

  // Set up pins for buttons
  pinMode(redButtonPin, INPUT_PULLUP);
  pinMode(blueButtonPin, INPUT_PULLUP);
  
  // Set up the buzzer pin
  pinMode(buzzerPin, OUTPUT);
  
  // Initial OLED display off
  display.clearDisplay();
  display.display();
  
  // Welcome screen
  displayMessage("Press Blue for Cats");
}

void loop() {
  // Check for red button press to control speaker
  if (digitalRead(redButtonPin) == LOW) {
    speakerOn = !speakerOn;
    if (speakerOn) {
      playGetLuckyMelody(); // Play Daft Punk's "Get Lucky" (short section)
    } else {
      noTone(buzzerPin);
    }
    delay(500); // Debounce
  }

  // Volume control with rotary encoder
  long newPos = encoder.read();
  if (newPos != lastEncoderPos) {
    lastEncoderPos = newPos;
    
    // Scale the encoder value to a range of 0 to 9
    volume = constrain(map(newPos, -100, 100, 0, 9), 0, 9); // Adjust range as needed
    Serial.print("Volume: ");
    Serial.println(volume);
  }

  // Check for blue button press to change OLED cat animations
  if (digitalRead(blueButtonPin) == LOW) {
    currentCat++;
    if (currentCat > 3) {
      currentCat = 0; // Reset to off mode
    }
    drawCat(currentCat);
    delay(500); // Debounce
  }
}

// Function to play Daft Punk's "Get Lucky" melody (short version)
void playGetLuckyMelody() {
  for (int thisNote = 0; thisNote < sizeof(melody) / sizeof(melody[0]); thisNote++) {
    int noteDuration = noteDurations[thisNote];
    if (melody[thisNote] != 0) {
      tone(buzzerPin, melody[thisNote], noteDuration);
    } else {
      noTone(buzzerPin); // Rest note (silence)
    }
    int pauseBetweenNotes = noteDuration * 1.30; // Slight pause between notes
    delay(pauseBetweenNotes);
  }
}

// Function to display message on OLED
void displayMessage(const char* message) {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println(message);
  display.display();
}

// Function to draw cats based on mode
void drawCat(int catMode) {
  display.clearDisplay();
  switch (catMode) {
    case 0: // Off Mode
      displayMessage("ZZZ");
      break;
    case 1: // Cat 1
      displayMessage("HOW TO MAKE");
      break;
    case 2: // Cat 2
      displayMessage("(ALMOST)");
      break;
    case 3: // Cat 3
      displayMessage("ANYTHING");
      break;
  }
  display.display();
}