#include <Keyboard.h>
uint8_t buf[8] = {0};  // Keyboard Report Buffer: 8 bytes

#define PIN_W A0
#define PIN_A A1      // Button to press Enter
#define PIN_S A2      // Button to type "music"
#define PIN_D A3      // Command + Space
#define PIN_VOL_UP A4 // Button to increase volume
#define PIN_VOL_DOWN 2 // Button to decrease volume

bool currState_W = HIGH;
bool currState_A = HIGH;
bool currState_S = HIGH;
bool currState_D = HIGH;
bool currState_VOL_UP = HIGH;
bool currState_VOL_DOWN = HIGH;

bool prevState_W = HIGH; 
bool prevState_A = HIGH; 
bool prevState_S = HIGH; 
bool prevState_D = HIGH; 
bool prevState_VOL_UP = HIGH;
bool prevState_VOL_DOWN = HIGH;

unsigned long prevTime_W = 0;
unsigned long prevTime_A = 0;
unsigned long prevTime_S = 0;
unsigned long prevTime_D = 0;
unsigned long prevTime_VOL_UP = 0;
unsigned long prevTime_VOL_DOWN = 0;

unsigned long waitTime_W = 50;
unsigned long waitTime_A = 50;
unsigned long waitTime_S = 50;
unsigned long waitTime_D = 50;
unsigned long waitTime_VOL_UP = 50;
unsigned long waitTime_VOL_DOWN = 50;

void setup() 
{
  Serial.begin(9600);

  pinMode(PIN_W, INPUT_PULLUP);
  pinMode(PIN_A, INPUT_PULLUP);  // Enter key
  pinMode(PIN_S, INPUT_PULLUP);  // Type "music"
  pinMode(PIN_D, INPUT_PULLUP);  // Command + Space
  pinMode(PIN_VOL_UP, INPUT_PULLUP);  // Volume up
  pinMode(PIN_VOL_DOWN, INPUT_PULLUP); // Volume down

  delay(200);
}

void loop() 
{
  checkButton();
}

void checkButton() {
  bool currRead_W = digitalRead(PIN_W);
  bool currRead_A = digitalRead(PIN_A);
  bool currRead_S = digitalRead(PIN_S);
  bool currRead_D = digitalRead(PIN_D);
  bool currRead_VOL_UP = digitalRead(PIN_VOL_UP);
  bool currRead_VOL_DOWN = digitalRead(PIN_VOL_DOWN);

  if (currRead_W != prevState_W) {
    prevTime_W = millis();
  }
  if (currRead_A != prevState_A) {
    prevTime_A = millis();
  }
  if (currRead_S != prevState_S) {
    prevTime_S = millis();
  }
  if (currRead_D != prevState_D) {
    prevTime_D = millis();
  }
  if (currRead_VOL_UP != prevState_VOL_UP) {
    prevTime_VOL_UP = millis();
  }
  if (currRead_VOL_DOWN != prevState_VOL_DOWN) {
    prevTime_VOL_DOWN = millis();
  }

  if ((millis() - prevTime_W) > waitTime_W) {
      if (currRead_W != currState_W) {
          currState_W = currRead_W;
          if (currState_W == LOW) {
              buf[0] = 0x01;   // HID: Left Control key
              buf[2] = 0x50;   // HID: Left Arrow key
              Serial.write(buf, 8);  // Send keypress
          } else {
              releaseKey();  // Function to release all keys
          }
      }
  }
  if ((millis() - prevTime_A) > waitTime_A) {
    if (currRead_A != currState_A) {
      currState_A = currRead_A;
      if (currState_A == LOW) {
        buf[2] = 0x2C;    // HID: Space key
        Serial.write(buf, 8); // Send Enter keypress
      } else {
        releaseKey();
      }
    }
  }
  if ((millis() - prevTime_S) > waitTime_S) {
      if (currRead_S != currState_S) {
          currState_S = currRead_S;
          if (currState_S == LOW) {
              buf[0] = 0x01;   // HID: Left Control key
              buf[2] = 0x4F;   // HID: Right Arrow key
              Serial.write(buf, 8);  // Send keypress
          } else {
              releaseKey();  // Function to release all keys
          }
      }
  }
  if ((millis() - prevTime_D) > waitTime_D) {
      if (currRead_D != currState_D) {
          currState_D = currRead_D;
          if (currState_D == LOW) {
              // Start Command + Space sequence
              buf[0] = 0x08;   // Command key modifier
              buf[2] = 0x2C;   // Spacebar HID code
              Serial.write(buf, 8); // Send Command + Spacebar
              releaseKey();    // Release both keys

              delay(1000);     // Wait 1 second

              // Type "terminal"
              typePhrase("terminal");

              delay(500);      // Wait 0.5 seconds

              // Press Enter
              buf[2] = 0x28;   // Enter key HID code
              Serial.write(buf, 8);
              releaseKey();    // Release Enter

              delay(1000);     // Wait 1 second

              // Type "cd downloads"
              typePhrase("cd");
              delay(100);
              buf[2] = 0x2C;   // Spacebar HID code
              Serial.write(buf, 8); // Send Space
              releaseKey();    // Release Space
              delay(100);
              typePhrase("downloads");

              delay(100);

              buf[2] = 0x28;   // Enter key HID code
              Serial.write(buf, 8); // Send Enter
              releaseKey();    // Release Enter

              delay(200);      // Small delay between commands

              // Type "python3 music3.py"
              typePhrase("python");
              
              // Type "3"
              buf[2] = 0x20;   // 3 HID code
              Serial.write(buf, 8); // Send 3
              releaseKey();    // Release 3

              delay(100);

              // Press Space
              buf[2] = 0x2C;   // Spacebar HID code 
              Serial.write(buf, 8); // Send Space
              releaseKey();    // Release Space

              delay(100);

              // Type "music"
              typePhrase("music");

              // Type "."
              buf[2] = 0x37;   // . HID code
              Serial.write(buf, 8); // Send period
              releaseKey();    // Release period

              // Type "py"
              typePhrase("py");

              delay(100);

              // Press Enter
              buf[2] = 0x28;   // Enter key HID code
              Serial.write(buf, 8); // Send Enter
              releaseKey();    // Release Enter

          } else {
              releaseKey();  // Release all keys
          }
      }
  }

  if ((millis() - prevTime_VOL_UP) > waitTime_VOL_UP) {
      if (currRead_VOL_UP != currState_VOL_UP) {
          currState_VOL_UP = currRead_VOL_UP;
          if (currState_VOL_UP == LOW) {
              // Send Volume Up keypress
              buf[0] = 0x00;    // No modifier
              buf[2] = 0x80;    // HID code for Volume Up
              Serial.write(buf, 8); // Send Volume Up keypress
              releaseKey();     // Release Volume Up key
          }
      }
  }

  if ((millis() - prevTime_VOL_DOWN) > waitTime_VOL_DOWN) {
      if (currRead_VOL_DOWN != currState_VOL_DOWN) {
          currState_VOL_DOWN = currRead_VOL_DOWN;
          if (currState_VOL_DOWN == LOW) {
              // Send Volume Down keypress
              buf[0] = 0x00;    // No modifier
              buf[2] = 0x81;    // HID code for Volume Down
              Serial.write(buf, 8); // Send Volume Down keypress
              releaseKey();     // Release Volume Down key
          }
      }
  }

  prevState_W = currRead_W;
  prevState_A = currRead_A;
  prevState_S = currRead_S;
  prevState_D = currRead_D;
  prevState_VOL_UP = currRead_VOL_UP;
  prevState_VOL_DOWN = currRead_VOL_DOWN;
}

void typePhrase(const char* phrase) {
  while (*phrase) {
    buf[2] = charToHID(*phrase);  // Convert each character to HID code
    Serial.write(buf, 8);         // Send each keypress
    releaseKey();                 // Release each key
    delay(100);                   // Small delay between each key
    phrase++;
  }
}

uint8_t charToHID(char c) {
  if (c >= 'a' && c <= 'z') {
    return (c - 'a' + 4); // HID codes for lowercase letters start from 4
  }
  return 0; // Default return 0 if character not mapped
}

void releaseKey() 
{
  buf[0] = 0;
  buf[2] = 0;
  Serial.write(buf, 8); // Release key  
}