/*
 * DWN - Desktop Window Manager
 * retoor <retoor@molodetz.nl>
 * Screenshot capture API
 */

#ifndef DWN_SCREENSHOT_H
#define DWN_SCREENSHOT_H

#include <stdbool.h>
#include <stddef.h>
#include <pthread.h>
#include <X11/Xlib.h>

typedef enum {
    SCREENSHOT_OK = 0,
    SCREENSHOT_ERROR_INVALID_ARG,
    SCREENSHOT_ERROR_X11,
    SCREENSHOT_ERROR_PNG,
    SCREENSHOT_ERROR_NO_MEMORY,
    SCREENSHOT_ERROR_WINDOW_NOT_FOUND
} ScreenshotStatus;

typedef enum {
    SCREENSHOT_STATE_IDLE,
    SCREENSHOT_STATE_PENDING,
    SCREENSHOT_STATE_COMPLETED,
    SCREENSHOT_STATE_ERROR
} ScreenshotState;

typedef enum {
    SCREENSHOT_MODE_FULLSCREEN,
    SCREENSHOT_MODE_WINDOW,
    SCREENSHOT_MODE_ACTIVE,
    SCREENSHOT_MODE_AREA
} ScreenshotMode;

typedef struct {
    unsigned char *data;
    size_t size;
    int width;
    int height;
} ScreenshotResult;

typedef struct ScreenshotRequest {
    ScreenshotMode mode;
    Window window;
    int x, y, width, height;

    ScreenshotResult result;
    ScreenshotStatus status;
    ScreenshotState state;

    void (*callback)(struct ScreenshotRequest *req);
    void *user_data;

    pthread_t thread;
    struct ScreenshotRequest *next;
} ScreenshotRequest;

bool screenshot_init(void);
void screenshot_cleanup(void);

ScreenshotStatus screenshot_capture_fullscreen(ScreenshotResult *result);
ScreenshotStatus screenshot_capture_window(Window window, ScreenshotResult *result);
ScreenshotStatus screenshot_capture_active(ScreenshotResult *result);
ScreenshotStatus screenshot_capture_area(int x, int y, int width, int height, ScreenshotResult *result);

ScreenshotRequest *screenshot_capture_async(ScreenshotMode mode,
                                            void (*callback)(ScreenshotRequest *));
ScreenshotRequest *screenshot_capture_window_async(Window window,
                                                   void (*callback)(ScreenshotRequest *));
ScreenshotRequest *screenshot_capture_area_async(int x, int y, int w, int h,
                                                 void (*callback)(ScreenshotRequest *));

void screenshot_process_pending(void);
void screenshot_cancel(ScreenshotRequest *req);

char *screenshot_to_base64(const ScreenshotResult *result, size_t *out_len);
void screenshot_result_free(ScreenshotResult *result);

const char *screenshot_status_string(ScreenshotStatus status);

#endif
