/*
    XIAO ESP32 desktop buddy
    Markus Opitz 2026
*/


#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define SDA_PIN D9
#define SCL_PIN D10

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// blink
unsigned long lastBlinkTime = 0;
unsigned long blinkInterval = 0;

bool isBlinking = false;
unsigned long blinkStartTime = 0;
const unsigned long blinkDuration = 120;

// direction
int pupilOffsetX = 0;

void setup() {

  Serial.begin(115200);

  // I2C start
  Wire.begin(SDA_PIN, SCL_PIN);

  // display start
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {  // or try address 0x3C
    Serial.println("SSD1306 not found");
    while (true);
  }

  display.clearDisplay();
  display.display();

  // init random
  randomSeed(analogRead(0));

  // 1st random blink
  blinkInterval = random(2000, 5000);
}

void loop() {

unsigned long currentTime = millis();

  // start new blink
  if (!isBlinking && currentTime - lastBlinkTime > blinkInterval) {

    isBlinking = true;
    blinkStartTime = currentTime;
  }

  // end blink
  if (isBlinking && currentTime - blinkStartTime > blinkDuration) {

    isBlinking = false;
    lastBlinkTime = currentTime;

    // new blink direction
    int lookDirection = random(0, 3);

    switch (lookDirection) {

      case 0:
        pupilOffsetX = -6; // left
        break;

      case 1:
        pupilOffsetX = 0; // mid
        break;

      case 2:
        pupilOffsetX = 6; // right
        break;
    }

    // new interval
    blinkInterval = random(2000, 5000);
  }

  // draw eyes
  drawEyes(isBlinking);

  delay(10);
}

void drawEyes(bool blinking) {

  display.clearDisplay();

  // positions
  int leftEyeX = 38;
  int rightEyeX = 90;

  int eyeY = 32;

  int eyeWidth = 26;
  int eyeHeight = 20;

  if (blinking) {

    // closed eyes
    display.drawLine(leftEyeX - eyeWidth / 2,
                     eyeY,
                     leftEyeX + eyeWidth / 2,
                     eyeY,
                     SSD1306_WHITE);

    display.drawLine(rightEyeX - eyeWidth / 2,
                     eyeY,
                     rightEyeX + eyeWidth / 2,
                     eyeY,
                     SSD1306_WHITE);

  } else {

    // white eyes
    display.fillRoundRect(
      leftEyeX - eyeWidth / 2,
      eyeY - eyeHeight / 2,
      eyeWidth,
      eyeHeight,
      12,       //size
      SSD1306_WHITE
    );

    display.fillRoundRect(
      rightEyeX - eyeWidth / 2,
      eyeY - eyeHeight / 2,
      eyeWidth,
      eyeHeight,
      12,        //size
      SSD1306_WHITE
    );

    // black pupils
    display.fillCircle(
      leftEyeX + pupilOffsetX,
      eyeY,
      5,
      SSD1306_BLACK
    );

    display.fillCircle(
      rightEyeX + pupilOffsetX,
      eyeY,
      5,
      SSD1306_BLACK
    );
  }

  display.display();
}