#include <windows.h>
#include <shobjidl.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    if (FAILED(hr)) {
        fprintf(stderr, "CoInitializeEx failed: 0x%lx\n", hr);
        exit(1);
    }

    char file[MAX_PATH] = {0};
    IFileSaveDialog *pFileSave = NULL;
    IShellItem *pItem = NULL;
    PWSTR pszFilePath = NULL;

    hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_ALL,
                          &IID_IFileSaveDialog, (void**)&pFileSave);

    if (SUCCEEDED(hr)) {
        COMDLG_FILTERSPEC rgSpec[] = {{L"All Files",      L"*.*"}};
        pFileSave->lpVtbl->SetFileTypes(pFileSave, ARRAYSIZE(rgSpec), rgSpec);

        pFileSave->lpVtbl->SetTitle(pFileSave, L"Save File As");

        DWORD dwFlags;
        pFileSave->lpVtbl->GetOptions(pFileSave, &dwFlags);
        pFileSave->lpVtbl->SetOptions(pFileSave, dwFlags | FOS_OVERWRITEPROMPT | FOS_PATHMUSTEXIST | FOS_NOCHANGEDIR);

        hr = pFileSave->lpVtbl->Show(pFileSave, NULL);

        if (SUCCEEDED(hr)) {
            printf("GetResult...\n");
            hr = pFileSave->lpVtbl->GetResult(pFileSave, &pItem);

            if (SUCCEEDED(hr)) {
                printf("GetDisplayName...\n");
                hr = pItem->lpVtbl->GetDisplayName(pItem, SIGDN_FILESYSPATH, &pszFilePath);

                if (SUCCEEDED(hr)) {
                    wcstombs(file, pszFilePath, MAX_PATH);
                    printf("Selected file: %s\n", file);
                }
            }
        }
    }

    if (pszFilePath) {
        CoTaskMemFree(pszFilePath);
    }
    if (pItem) {
        pItem->lpVtbl->Release(pItem);
    }
    if (pFileSave) {
        pFileSave->lpVtbl->Release(pFileSave);
    }
    CoUninitialize();

    if (FAILED(hr) || file[0] == '\0') {
        puts("File selection cancelled or failed.");
        exit(1);
    }

    FILE *f = fopen(file, "w");
    if (!f) {
        perror("Error opening file for writing");
        exit(1);
    }

    if (fprintf(f, "foo") < 0) {
        perror("Error writing to file");
        fclose(f);
        exit(1);
    } else {
        puts("Successfully wrote \"foo\" to the file.");
    }

    fclose(f);

    return 0;
}
