#include "pch.h" // Precompiled header
#include <windows.h>
#include <commctrl.h>
#include <iostream>
#include <tchar.h>
#include <shellapi.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include <comdef.h>

// Function prototypes
DWORD WINAPI OpenGUI(LPVOID lpParam);
void RestartDiscord();
void ToggleWindow();
void SetMicrophoneGain(float gainLevel);

// Global variables
HWND hWnd;
HINSTANCE hInstance;
HWND hGainTrackbar;
BOOL isWindowVisible = TRUE;
int gainLevel = 5000; // Default mid-range gain

// Function to set microphone gain (mapped from -96 dB to +55 dB)
void SetMicrophoneGain(float gainLevel) {
    CoInitialize(NULL);

    IMMDeviceEnumerator* pEnumerator = NULL;
    CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pEnumerator);

    IMMDevice* pDevice = NULL;
    pEnumerator->GetDefaultAudioEndpoint(eCapture, eConsole, &pDevice);

    IAudioEndpointVolume* pVolume = NULL;
    pDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (void**)&pVolume);

    // Map trackbar value (0-10000) to dB range (-96 to +55 dB)
    float minDb = -96.0f;
    float maxDb = 55.0f;
    float gainDb = minDb + (gainLevel / 10000.0f) * (maxDb - minDb);

    pVolume->SetMasterVolumeLevel(gainDb, NULL); // Apply gain in dB

    pVolume->Release();
    pDevice->Release();
    pEnumerator->Release();
    CoUninitialize();
}

// Function to restart Discord
void RestartDiscord() {
    system("taskkill /F /IM discord.exe");
    Sleep(3000); // Ensure Discord is closed

    char discordPath[MAX_PATH];
    if (GetEnvironmentVariableA("LOCALAPPDATA", discordPath, MAX_PATH)) {
        strcat_s(discordPath, "\\Discord\\Update.exe");
        ShellExecuteA(0, "open", discordPath, "--processStart Discord.exe", NULL, SW_SHOW);
        MessageBox(NULL, _T("Discord has been restarted."), _T("Notification"), MB_OK | MB_ICONINFORMATION);
    }
    else {
        MessageBox(NULL, _T("Failed to get Discord path."), _T("Error"), MB_ICONERROR);
    }
}

// Function to toggle GUI visibility
void ToggleWindow() {
    isWindowVisible = !isWindowVisible;
    ShowWindow(hWnd, isWindowVisible ? SW_SHOW : SW_HIDE);
}

// Window Procedure
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_PAINT: {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        RECT rect;
        GetClientRect(hwnd, &rect);

        FillRect(hdc, &rect, (HBRUSH)(COLOR_BTNSHADOW + 1)); // Dark background

        SetBkMode(hdc, TRANSPARENT);
        SetTextColor(hdc, RGB(240, 240, 240)); // Light gray text

        TextOut(hdc, 10, 10, _T("Jakacord"), 9);

        TCHAR gainText[50];
        _stprintf_s(gainText, _T("Gain Level: %d"), gainLevel);
        TextOut(hdc, 10, 120, gainText, _tcslen(gainText));

        EndPaint(hwnd, &ps);
        break;
    }
    case WM_HSCROLL:
        if ((HWND)lParam == hGainTrackbar) {
            gainLevel = SendMessage(hGainTrackbar, TBM_GETPOS, 0, 0);
            InvalidateRect(hwnd, NULL, TRUE);
            SetMicrophoneGain(gainLevel);
        }
        break;
    case WM_HOTKEY:
        if (wParam == 1) { // F5 hotkey
            ToggleWindow();
        }
        break;
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

// Function to create GUI
DWORD WINAPI OpenGUI(LPVOID lpParam) {
    hInstance = GetModuleHandle(NULL);

    WNDCLASS wc = {};
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = _T("Jaka");
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    RegisterClass(&wc);

    hWnd = CreateWindowEx(
        WS_EX_TOOLWINDOW, _T("Jaka"), _T("Jakacord"),
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        CW_USEDEFAULT, CW_USEDEFAULT, 450, 250,
        NULL, NULL, hInstance, NULL);

    if (!hWnd) return 1;

    RegisterHotKey(hWnd, 1, 0, VK_F5);

    hGainTrackbar = CreateWindowEx(
        0, TRACKBAR_CLASS, NULL, WS_CHILD | WS_VISIBLE | TBS_BOTH | TBS_NOTICKS,
        50, 150, 400, 30, hWnd, NULL, hInstance, NULL);

    SendMessage(hGainTrackbar, TBM_SETRANGE, TRUE, MAKELONG(0, 10000));
    SendMessage(hGainTrackbar, TBM_SETPOS, TRUE, gainLevel);

    MSG msg = {};
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    UnregisterHotKey(hWnd, 1);
    return 0;
}

// Entry point of the DLL - manages loading and unloading
extern "C" __declspec(dllexport) BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        AllocConsole();
        freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
        std::cout << "Jakacord (ur uncapped)" << std::endl;
        CreateThread(NULL, 0, OpenGUI, NULL, 0, NULL);
        break;
    case DLL_PROCESS_DETACH:
        FreeConsole();
        break;
    }
    return TRUE;
}





i need a better design for the gui