/*
 * DWN - Desktop Window Manager
 * Layout Plugin Interface
 */

#ifndef LAYOUT_PLUGIN_H
#define LAYOUT_PLUGIN_H

#include "core/wm_types.h"
#include "core/wm_client.h"

#ifdef __cplusplus
extern "C" {
#endif

/*==============================================================================
 * Layout Plugin API Version
 *============================================================================*/

#define WM_LAYOUT_PLUGIN_API_VERSION 1

/*==============================================================================
 * Forward Declarations
 *============================================================================*/

typedef struct LayoutPlugin LayoutPlugin;
typedef struct LayoutContext LayoutContext;

/*==============================================================================
 * Layout Geometry
 *============================================================================*/

/**
 * Layout geometry for a single client.
 */
typedef struct {
    int x, y;
    int width, height;
    bool floating;      /* If true, layout doesn't manage this client */
    bool fullscreen;    /* If true, client should be fullscreen */
    bool hidden;        /* If true, client should be hidden */
} WmLayoutGeometry;

/**
 * Work area for layout calculations.
 */
typedef struct {
    int x, y;
    int width, height;
    int padding_top;
    int padding_bottom;
    int padding_left;
    int padding_right;
    int gap;
} WmLayoutWorkArea;

/*==============================================================================
 * Layout Configuration
 *============================================================================*/

/**
 * Layout configuration parameter.
 */
typedef struct {
    const char *name;
    const char *description;
    union {
        int int_value;
        float float_value;
        bool bool_value;
        const char *string_value;
    } default_value;
    enum {
        WM_LAYOUT_PARAM_INT,
        WM_LAYOUT_PARAM_FLOAT,
        WM_LAYOUT_PARAM_BOOL,
        WM_LAYOUT_PARAM_STRING,
        WM_LAYOUT_PARAM_CHOICE
    } type;
    /* For PARAM_CHOICE */
    const char **choices;
    int num_choices;
} WmLayoutParameter;

/**
 * Layout configuration instance.
 */
typedef struct {
    WmLayoutParameter *parameters;
    int num_parameters;
    void *user_data;  /* Plugin can store parsed config here */
} WmLayoutConfig;

/*==============================================================================
 * Layout State
 *============================================================================*/

/**
 * Opaque layout state per workspace.
 * Layout plugins can store workspace-specific state here.
 */
typedef struct WmLayoutState WmLayoutState;

/*==============================================================================
 * Layout Context
 *============================================================================*/

/**
 * Context passed to layout operations.
 */
struct LayoutContext {
    /* Workspace info */
    WmWorkspaceId workspace;
    WmLayoutWorkArea work_area;
    
    /* Client counts */
    int client_count;
    int master_count;
    int stack_count;
    
    /* Layout parameters */
    float master_ratio;
    int master_count_target;
    int gap;
    
    /* Configuration */
    WmLayoutConfig *config;
    
    /* Layout state (managed by plugin) */
    WmLayoutState *state;
    
    /* User data (for plugin use) */
    void *user_data;
};

/*==============================================================================
 * Layout Plugin Interface
 *============================================================================*/

/**
 * Layout plugin interface vtable.
 * All layouts must implement these functions.
 */
typedef struct {
    /* Version check */
    int api_version;
    
    /* Metadata */
    const char *name;
    const char *description;
    const char *author;
    const char *version;
    
    /* Configuration */
    WmLayoutParameter *parameters;
    int num_parameters;
    
    /* Lifecycle */
    bool (*init)(LayoutPlugin *plugin);
    void (*shutdown)(LayoutPlugin *plugin);
    
    /* State management */
    WmLayoutState* (*state_create)(LayoutPlugin *plugin, WmWorkspaceId workspace);
    void (*state_destroy)(LayoutPlugin *plugin, WmLayoutState *state);
    void (*state_reset)(LayoutPlugin *plugin, WmLayoutState *state);
    
    /* Configuration */
    bool (*config_parse)(LayoutPlugin *plugin, WmLayoutConfig *config, 
                         const char *key, const char *value);
    void (*config_apply)(LayoutPlugin *plugin, WmLayoutConfig *config);
    
    /* Layout calculation */
    bool (*arrange)(LayoutPlugin *plugin, LayoutContext *ctx,
                    AbstractClient **clients, int num_clients,
                    WmLayoutGeometry *geometries);
    
    /* Client operations */
    void (*client_added)(LayoutPlugin *plugin, LayoutContext *ctx, 
                         AbstractClient *client);
    void (*client_removed)(LayoutPlugin *plugin, LayoutContext *ctx,
                           AbstractClient *client);
    void (*client_floating_changed)(LayoutPlugin *plugin, LayoutContext *ctx,
                                     AbstractClient *client, bool floating);
    
    /* Layout manipulation */
    void (*inc_master)(LayoutPlugin *plugin, LayoutContext *ctx, int delta);
    void (*set_master_ratio)(LayoutPlugin *plugin, LayoutContext *ctx, float ratio);
    void (*set_master_count)(LayoutPlugin *plugin, LayoutContext *ctx, int count);
    void (*swap_master)(LayoutPlugin *plugin, LayoutContext *ctx);
    void (*rotate)(LayoutPlugin *plugin, LayoutContext *ctx, bool clockwise);
    
    /* Mouse resizing support */
    void (*resize_master)(LayoutPlugin *plugin, LayoutContext *ctx, 
                          int x, int y, int *new_master_count, float *new_ratio);
    
} LayoutPluginInterface;

/*==============================================================================
 * Layout Plugin Structure
 *============================================================================*/

/**
 * Layout plugin instance.
 */
struct LayoutPlugin {
    /* Interface vtable */
    const LayoutPluginInterface *interface;
    
    /* Plugin handle (for dynamic loading) */
    void *handle;
    
    /* Plugin path */
    char *path;
    
    /* Enabled state */
    bool enabled;
    
    /* Global configuration */
    WmLayoutConfig config;
    
    /* Per-workspace states */
    WmLayoutState **workspace_states;
    int num_workspaces;
    
    /* Plugin-private data */
    void *user_data;
};

/*==============================================================================
 * Layout Manager
 *============================================================================*/

/**
 * Layout manager handles all loaded layouts.
 */
typedef struct LayoutManager LayoutManager;

/**
 * Get the global layout manager.
 */
LayoutManager* wm_layout_manager_get(void);

/**
 * Initialize the layout manager.
 */
bool wm_layout_manager_init(void);

/**
 * Shutdown the layout manager.
 */
void wm_layout_manager_shutdown(void);

/**
 * Register a layout plugin.
 */
bool wm_layout_manager_register(LayoutManager *mgr, LayoutPlugin *plugin);

/**
 * Unregister a layout plugin.
 */
void wm_layout_manager_unregister(LayoutManager *mgr, LayoutPlugin *plugin);

/**
 * Load a layout plugin from a file.
 */
LayoutPlugin* wm_layout_manager_load(LayoutManager *mgr, const char *path);

/**
 * Unload a layout plugin.
 */
void wm_layout_manager_unload(LayoutManager *mgr, LayoutPlugin *plugin);

/**
 * Get a loaded layout by name.
 */
LayoutPlugin* wm_layout_manager_get_layout(LayoutManager *mgr, const char *name);

/**
 * Get the default layout.
 */
LayoutPlugin* wm_layout_manager_get_default(LayoutManager *mgr);

/**
 * Set the default layout.
 */
void wm_layout_manager_set_default(LayoutManager *mgr, LayoutPlugin *plugin);

/**
 * Get list of available layouts.
 */
const char** wm_layout_manager_list(LayoutManager *mgr, int *count);

/*==============================================================================
 * Layout Operations
 *============================================================================*/

/**
 * Apply a layout to a workspace.
 */
bool wm_layout_arrange(LayoutPlugin *plugin, WmWorkspaceId workspace);

/**
 * Apply layout to specific clients.
 */
bool wm_layout_arrange_clients(LayoutPlugin *plugin, LayoutContext *ctx,
                                AbstractClient **clients, int num_clients);

/**
 * Create a layout context for a workspace.
 */
bool wm_layout_context_init(LayoutContext *ctx, WmWorkspaceId workspace);

/**
 * Clean up a layout context.
 */
void wm_layout_context_cleanup(LayoutContext *ctx);

/*==============================================================================
 * Built-in Layouts
 *============================================================================*/

/* Tiling layout */
extern const LayoutPluginInterface wm_layout_tiling;

/* Floating layout */
extern const LayoutPluginInterface wm_layout_floating;

/* Monocle (maximized) layout */
extern const LayoutPluginInterface wm_layout_monocle;

/* Grid layout */
extern const LayoutPluginInterface wm_layout_grid;

/* Spiral layout */
extern const LayoutPluginInterface wm_layout_spiral;

/* Dwindle layout */
extern const LayoutPluginInterface wm_layout_dwindle;

/*==============================================================================
 * Plugin Entry Point
 *============================================================================*/

/**
 * Layout plugins must export this function.
 */
typedef const LayoutPluginInterface* (*LayoutPluginEntryFunc)(void);

#define WM_LAYOUT_PLUGIN_ENTRY "wm_layout_plugin_entry"

/*==============================================================================
 * Helper Macros
 *============================================================================*/

#define WM_LAYOUT_REGISTER(name, iface) \
    __attribute__((unused)) static const LayoutPluginInterface* wm_layout_plugin_entry(void) { return &(iface); }

/* Typedef for built-in layout getters */
typedef const LayoutPluginInterface* (*WmLayoutBuiltinFunc)(void);

#ifdef __cplusplus
}
#endif

#endif /* LAYOUT_PLUGIN_H */
