/*
 * DWN - Desktop Window Manager
 * Widget Plugin Interface
 * Panel components (taskbar, clock, workspaces, etc.)
 */

#ifndef WIDGET_PLUGIN_H
#define WIDGET_PLUGIN_H

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

#ifdef __cplusplus
extern "C" {
#endif

/*==============================================================================
 * Widget Plugin API Version
 *============================================================================*/

#define WM_WIDGET_PLUGIN_API_VERSION 1

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

typedef struct WidgetPlugin WidgetPlugin;
typedef struct WidgetContext WidgetContext;
typedef struct WidgetInstance WidgetInstance;

/*==============================================================================
 * Widget Position
 *============================================================================*/

typedef enum {
    WM_WIDGET_POSITION_LEFT,
    WM_WIDGET_POSITION_CENTER,
    WM_WIDGET_POSITION_RIGHT
} WmWidgetPosition;

/*==============================================================================
 * Widget Size Constraints
 *============================================================================*/

typedef struct {
    int min_width;
    int min_height;
    int max_width;
    int max_height;
    bool expand_horizontal;  /* Take available horizontal space */
    bool expand_vertical;    /* Take available vertical space */
} WmWidgetConstraints;

/*==============================================================================
 * Widget Geometry
 *============================================================================*/

typedef struct {
    int x, y;
    int width, height;
} WmWidgetGeometry;

/*==============================================================================
 * Widget State
 *============================================================================*/

typedef enum {
    WM_WIDGET_STATE_NORMAL = 0,
    WM_WIDGET_STATE_HOVERED = (1 << 0),
    WM_WIDGET_STATE_PRESSED = (1 << 1),
    WM_WIDGET_STATE_ACTIVE = (1 << 2),
    WM_WIDGET_STATE_DISABLED = (1 << 3),
    WM_WIDGET_STATE_HIDDEN = (1 << 4),
    WM_WIDGET_STATE_URGENT = (1 << 5)
} WmWidgetState;

/*==============================================================================
 * Widget Context
 *============================================================================*/

struct WidgetContext {
    /* Position in panel */
    WmWidgetPosition position;
    
    /* Geometry */
    WmWidgetGeometry geometry;
    WmWidgetConstraints constraints;
    
    /* Panel info */
    WmRect panel_geometry;
    bool is_top_panel;
    
    /* Rendering context */
    void *render_context;  /* Backend-specific (X11 GC, cairo, etc.) */
    WmColor bg_color;
    WmColor fg_color;
    
    /* Font */
    void *font;  /* Opaque font handle */
    int font_size;
    
    /* User data */
    void *user_data;
};

/*==============================================================================
 * Widget Event Types
 *============================================================================*/

typedef enum {
    WM_WIDGET_EVENT_NONE,
    WM_WIDGET_EVENT_MOUSE_ENTER,
    WM_WIDGET_EVENT_MOUSE_LEAVE,
    WM_WIDGET_EVENT_MOUSE_MOVE,
    WM_WIDGET_EVENT_BUTTON_PRESS,
    WM_WIDGET_EVENT_BUTTON_RELEASE,
    WM_WIDGET_EVENT_SCROLL,
    WM_WIDGET_EVENT_KEY_PRESS,
    WM_WIDGET_EVENT_FOCUS_IN,
    WM_WIDGET_EVENT_FOCUS_OUT,
    WM_WIDGET_EVENT_UPDATE,        /* Request to redraw */
    WM_WIDGET_EVENT_CONFIGURE,     /* Size/position changed */
    WM_WIDGET_EVENT_DATA_CHANGED   /* External data changed */
} WmWidgetEventType;

typedef struct {
    WmWidgetEventType type;
    WmWidgetGeometry widget_geometry;
    union {
        struct { int x, y; } point;
        struct { int button; int x, y; } button;
        struct { int delta; bool horizontal; } scroll;
        struct { unsigned int keycode; unsigned int state; } key;
    } data;
} WmWidgetEvent;

/*==============================================================================
 * Widget Configuration
 *============================================================================*/

typedef struct {
    const char *name;
    const char *value;
} WmWidgetConfigOption;

typedef struct {
    WmWidgetConfigOption *options;
    int num_options;
} WmWidgetConfig;

/*==============================================================================
 * Widget Information
 *============================================================================*/

typedef struct {
    const char *id;              /* Unique identifier */
    const char *name;            /* Display name */
    const char *description;     /* Description */
    const char *author;          /* Author */
    const char *version;         /* Version */
    
    /* Default constraints */
    WmWidgetConstraints default_constraints;
    
    /* Default position */
    WmWidgetPosition default_position;
    
    /* Configuration schema */
    const char **config_options;  /* List of accepted config option names */
    int num_config_options;
} WmWidgetInfo;

/*==============================================================================
 * Widget Plugin Interface
 *============================================================================*/

typedef struct {
    /* Version check */
    int api_version;
    
    /* Metadata */
    WmWidgetInfo info;
    
    /* Lifecycle */
    bool (*init)(WidgetPlugin *plugin);
    void (*shutdown)(WidgetPlugin *plugin);
    
    /* Instance management */
    WidgetInstance* (*instance_create)(WidgetPlugin *plugin, 
                                        const WmWidgetConfig *config);
    void (*instance_destroy)(WidgetPlugin *plugin, WidgetInstance *instance);
    void (*instance_configure)(WidgetPlugin *plugin, WidgetInstance *instance,
                               const WmWidgetConfig *config);
    
    /* Rendering */
    void (*render)(WidgetPlugin *plugin, WidgetInstance *instance,
                   WidgetContext *ctx);
    
    /* Event handling */
    bool (*handle_event)(WidgetPlugin *plugin, WidgetInstance *instance,
                         const WmWidgetEvent *event);
    
    /* Update notification */
    void (*update)(WidgetPlugin *plugin, WidgetInstance *instance);
    
    /* Size calculation */
    void (*get_preferred_size)(WidgetPlugin *plugin, WidgetInstance *instance,
                               int *width, int *height);
    
} WidgetPluginInterface;

/*==============================================================================
 * Widget Instance
 *============================================================================*/

struct WidgetInstance {
    /* Plugin that created this instance */
    WidgetPlugin *plugin;
    
    /* Instance state */
    WmWidgetState state;
    WmWidgetGeometry geometry;
    WmWidgetConstraints constraints;
    
    /* Configuration */
    WmWidgetConfig config;
    
    /* Context */
    WidgetContext *context;
    
    /* Plugin-private data */
    void *user_data;
    
    /* Linked list for panel */
    WidgetInstance *next;
    WidgetInstance *prev;
};

/*==============================================================================
 * Widget Plugin Structure
 *============================================================================*/

struct WidgetPlugin {
    /* Interface vtable */
    const WidgetPluginInterface *interface;
    
    /* Plugin handle (for dynamic loading) */
    void *handle;
    
    /* Plugin path */
    char *path;
    
    /* Enabled state */
    bool enabled;
    
    /* Instances */
    WidgetInstance *instances;
    int instance_count;
    
    /* Plugin-private data */
    void *user_data;
};

/*==============================================================================
 * Widget Manager
 *============================================================================*/

typedef struct WidgetManager WidgetManager;

/**
 * Get the global widget manager.
 */
WidgetManager* wm_widget_manager_get(void);

/**
 * Initialize the widget manager.
 */
bool wm_widget_manager_init(void);

/**
 * Shutdown the widget manager.
 */
void wm_widget_manager_shutdown(void);

/**
 * Register a widget plugin.
 */
bool wm_widget_manager_register(WidgetManager *mgr, WidgetPlugin *plugin);

/**
 * Unregister a widget plugin.
 */
void wm_widget_manager_unregister(WidgetManager *mgr, WidgetPlugin *plugin);

/**
 * Load a widget plugin from a file.
 */
WidgetPlugin* wm_widget_manager_load(WidgetManager *mgr, const char *path);

/**
 * Unload a widget plugin.
 */
void wm_widget_manager_unload(WidgetManager *mgr, WidgetPlugin *plugin);

/**
 * Get a loaded widget by ID.
 */
WidgetPlugin* wm_widget_manager_get_widget(WidgetManager *mgr, const char *id);

/**
 * Get list of available widgets.
 */
const char** wm_widget_manager_list(WidgetManager *mgr, int *count);

/*==============================================================================
 * Widget Instance Operations
 *============================================================================*/

/**
 * Create a widget instance.
 */
WidgetInstance* wm_widget_create_instance(WidgetPlugin *plugin,
                                          const WmWidgetConfig *config);

/**
 * Destroy a widget instance.
 */
void wm_widget_destroy_instance(WidgetInstance *instance);

/**
 * Render a widget instance.
 */
void wm_widget_render(WidgetInstance *instance, WidgetContext *ctx);

/**
 * Send an event to a widget instance.
 */
bool wm_widget_send_event(WidgetInstance *instance, const WmWidgetEvent *event);

/**
 * Update a widget instance (request redraw).
 */
void wm_widget_update(WidgetInstance *instance);

/**
 * Get preferred size for a widget instance.
 */
void wm_widget_get_preferred_size(WidgetInstance *instance, 
                                  int *width, int *height);

/*==============================================================================
 * Widget Panel Integration
 *============================================================================*/

typedef struct WidgetPanel WidgetPanel;

/**
 * Create a widget panel (container for widget instances).
 */
WidgetPanel* wm_widget_panel_create(void);

/**
 * Destroy a widget panel.
 */
void wm_widget_panel_destroy(WidgetPanel *panel);

/**
 * Add a widget instance to a panel.
 */
void wm_widget_panel_add(WidgetPanel *panel, WidgetInstance *instance,
                         WmWidgetPosition position);

/**
 * Remove a widget instance from a panel.
 */
void wm_widget_panel_remove(WidgetPanel *panel, WidgetInstance *instance);

/**
 * Arrange widgets in a panel.
 */
void wm_widget_panel_arrange(WidgetPanel *panel, const WmRect *panel_geometry);

/**
 * Render all widgets in a panel.
 */
void wm_widget_panel_render(WidgetPanel *panel);

/**
 * Handle mouse event in a panel.
 */
bool wm_widget_panel_handle_event(WidgetPanel *panel, 
                                  const WmWidgetEvent *event);

/*==============================================================================
 * Built-in Widgets
 *============================================================================*/

/* Workspace switcher widget */
extern const WidgetPluginInterface wm_widget_workspaces;

/* Taskbar widget */
extern const WidgetPluginInterface wm_widget_taskbar;

/* Clock widget */
extern const WidgetPluginInterface wm_widget_clock;

/* System tray widget */
extern const WidgetPluginInterface wm_widget_systray;

/* CPU/Memory monitor widget */
extern const WidgetPluginInterface wm_widget_system_stats;

/* News ticker widget */
extern const WidgetPluginInterface wm_widget_news;

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

typedef const WidgetPluginInterface* (*WidgetPluginEntryFunc)(void);

#define WM_WIDGET_PLUGIN_ENTRY "wm_widget_plugin_entry"

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

#define WM_WIDGET_REGISTER(name, iface) \
    static const WidgetPluginInterface* wm_widget_plugin_entry(void) { return &(iface); }

#ifdef __cplusplus
}
#endif

#endif /* WIDGET_PLUGIN_H */
