#include <FastLED.h>
#include <Adafruit_NeoPixel.h>
#include <WINDOWS.h>
#include <TlHelp32.h>

#define LED_PIN     6
#define LED_COUNT   30

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

// Definiere die Farben
CRGB brown = CRGB(139, 69, 19);
CRGB oxidizedCopper = CRGB(84, 110, 100);

CRGB leds[NUM_LEDS];

void setup() {
  Serial.begin(9600);
  strip.begin();
  strip.show(); // Setzt alle LEDs auf Schwarz
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  
  pinMode(LED_BUILTIN, OUTPUT);
}

boolean checkIfMinecraftIsRunning() {
  PROCESSENTRY32 entry;
  entry.dwSize = sizeof(PROCESSENTRY32);

  HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

  if (Process32First(snapshot, &entry) == TRUE) {
    while (Process32Next(snapshot, &entry) == TRUE) {
      if (strcmp(entry.szExeFile, "javaw.exe") == 0 && strcmp(entry.szExeFile, "Minecraft.exe") == 0) {
        CloseHandle(snapshot);
        return true;
      }
    }
  }

  CloseHandle(snapshot);
  return false;
}

void loop() {
  // CPU-Auslastung abrufen
  int cpuUsage = getCpuUsage();

  // Festplattenaktivität abrufen
  boolean diskActivity = getDiskActivity();

  // E-Mail-Status abrufen
  boolean newEmail = checkForNewEmail();

  // Systemstatus abrufen
  boolean systemActive = checkSystemStatus();

  // 
  boolean cortanaOutput = checkCortanaOutput();

    if (checkIfMinecraftIsRunning()) {
    // Minecraft läuft, LEDs auf Braune Kupferfarbe setzen
    for (int i = 0; i < NUM_LEDS; i++) {
      strip.setPixelColor(i, brown);
    }
    strip.show();

    // Langsam auf oxidierte Kupferfarbe wechseln
    for (int i = 0; i < 255; i++) {
      strip.fill_solid(oxidizedCopper.fadeToBlackBy(i));
      strip.show();
      delay(10);
    }
  }
}
  // LEDs entsprechend der Ereignisse aktualisieren
  if (cpuUsage > 75) {
    setColor(strip.Color(255, 0, 0)); // Rot für hohe CPU-Auslastung
  }
  else if (diskActivity) {
    setColor(strip.Color(0, 255, 0)); // Grün für Festplattenaktivität
  }
  else if (newEmail) {
    setColor(strip.Color(0, 0, 255)); // Blau für eingehende E-Mail
  }
  else if (systemActive) {
    setColor(strip.Color(255, 255, 0)); // Gelb für aktives System
  }
  else if (cortanaOutput) {
    setColor(strip.Color(16, 255, 231)); // Hellblau für aktives System
  }
  else {
    strip.clear(); // Alle LEDs ausschalten
    // Führe Python-Datei aus
    system("python mainai.py");
    strip.show();
  }


  delay(1000);


// Setzt die Farbe aller LEDs
void setColor(uint32_t color) {
  for (int i = 0; i < LED_COUNT; i++) {
    strip.setPixelColor(i, color);
  }
  strip.show();
}

// Funktionen zur Ermittlung der CPU-Auslastung
int getCpuUsage() {
  // Variablen für die CPU-Auslastung
  FILETIME idleTime, kernelTime, userTime;
  ULARGE_INTEGER idleTimeUL, kernelTimeUL, userTimeUL;
  static ULARGE_INTEGER lastIdleTimeUL = { 0 }, lastKernelTimeUL = { 0 }, lastUserTimeUL = { 0 };
  double cpuUsage = 0.0;

  // Prozessorzeit abrufen
  if (GetSystemTimes(&idleTime, &kernelTime, &userTime)) {
    // Konvertierung von FILETIME in ULARGE_INTEGER
    idleTimeUL.LowPart = idleTime.dwLowDateTime;
    idleTimeUL.HighPart = idleTime.dwHighDateTime;
    kernelTimeUL.LowPart = kernelTime.dwLowDateTime;
    kernelTimeUL.HighPart = kernelTime.dwHighDateTime;
    userTimeUL.LowPart = userTime.dwLowDateTime;
    userTimeUL.HighPart = userTime.dwHighDateTime;

    // CPU-Auslastung berechnen
    if (lastIdleTimeUL.QuadPart != 0) {
      ULONGLONG idleTicks = idleTimeUL.QuadPart - lastIdleTimeUL.QuadPart;
      ULONGLONG totalTicks = kernelTimeUL.QuadPart + userTimeUL.QuadPart - lastKernelTimeUL.QuadPart - lastUserTimeUL.QuadPart;
      cpuUsage = (double)(totalTicks - idleTicks) / totalTicks * 100.0;
    }

    // Werte für den nächsten Durchlauf speichern
    lastIdleTimeUL = idleTimeUL;
    lastKernelTimeUL = kernelTimeUL;
    lastUserTimeUL = userTimeUL;
  }

  return (int)cpuUsage;
}

boolean checkIfMinecraftIsRunning() {
  // Hier wird der Code zur Überprüfung auf Minecraft eingefügt
  // Rückgabe von "true", wenn Minecraft läuft, "false" sonst
}

// Funktion zur Ermittlung der Festplattenaktivität
boolean getDiskActivity() {
  boolean getDiskActivity() {
  // Erstelle einen Handle auf die aktuelle Festplatte
  HANDLE hDisk = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);

  // Erstelle ein Disk-Performance-Objekt
  DISK_PERFORMANCE diskPerformance = {};
  DWORD bytesReturned = 0;

  // Rufe die Leistungsinformationen für die Festplatte ab
  if (!DeviceIoControl(hDisk, IOCTL_DISK_PERFORMANCE, NULL, 0, &diskPerformance, sizeof(diskPerformance), &bytesReturned, NULL)) {
    CloseHandle(hDisk);
    return false;
  }
  }
}

// Funktion zur Überprüfung auf neue E-Mails
boolean checkForNewEmail() {
  
}

// Funktion zur Überprüfung des Systemstatus
boolean checkSystemStatus() {
  // Hier wird der Code zur Überprüfung des Systemstatus eingefügt
  // Rückgabe von "true", wenn das System aktiv ist, "false" sonst
}

boolean checkCortanaOutput() {
  // Hier wird der Code zur Überprüfung des Systemstatus eingefügt
  // Rückgabe von "true", wenn das System aktiv ist, "false" sonst
}
