/*
 * el_native_target.h — Native widget declarations for el programs targeting
 * native desktop UI (AppKit / GTK4 / Win32).
 *
 * This header is designed to be included AFTER el_runtime.h without conflict:
 *   - It does NOT redefine el_to_float, el_from_float, or any el_runtime.h
 *     static inlines.
 *   - It does NOT redeclare __println, __print, or other functions whose
 *     return types differ between el_seed.h and el_runtime.h.
 *   - It adds: native widget builtins + float arithmetic helpers that the
 *     current el_runtime.h omits but elc still emits calls to.
 *
 * Usage:
 *   Inject via -include at compile time, OR #include it after el_runtime.h.
 *
 *   clang -DEL_TARGET_MACOS -include el_native_target.h -c my_app.c ...
 */

#pragma once

#include <stdint.h>
#include <stdlib.h>

/* el_val_t must already be defined by el_runtime.h or el_seed.h. */
#ifndef EL_VAL_T_DEFINED
typedef int64_t el_val_t;
#endif

/* ── Float arithmetic helpers ───────────────────────────────────────────────
 * elc emits calls to float_div / float_mul etc. for Float-typed expressions.
 * These were in el_runtime.c through v1.0.0-20260501 but are missing from the
 * current el_runtime.h. Redeclared here as static inline to avoid link deps.
 * Only defined if not already declared (old runtimes that still have them). */

#ifndef EL_FLOAT_OPS_DEFINED
#define EL_FLOAT_OPS_DEFINED

/* el_to_float / el_from_float — bit-cast between el_val_t and double.
 * Defined as static inline in both el_runtime.h and el_seed.h; we do NOT
 * redefine them here. We rely on one of those headers being included first. */

static inline el_val_t float_div(el_val_t a, el_val_t b) {
    union { double d; int64_t i; } ua, ub, ur;
    ua.i = a; ub.i = b;
    ur.d = (ub.d != 0.0) ? (ua.d / ub.d) : 0.0;
    return ur.i;
}

static inline el_val_t float_mul(el_val_t a, el_val_t b) {
    union { double d; int64_t i; } ua, ub, ur;
    ua.i = a; ub.i = b; ur.d = ua.d * ub.d;
    return ur.i;
}

static inline el_val_t float_add(el_val_t a, el_val_t b) {
    union { double d; int64_t i; } ua, ub, ur;
    ua.i = a; ub.i = b; ur.d = ua.d + ub.d;
    return ur.i;
}

static inline el_val_t float_sub(el_val_t a, el_val_t b) {
    union { double d; int64_t i; } ua, ub, ur;
    ua.i = a; ub.i = b; ur.d = ua.d - ub.d;
    return ur.i;
}

static inline el_val_t float_lt(el_val_t a, el_val_t b) {
    union { double d; int64_t i; } ua, ub;
    ua.i = a; ub.i = b;
    return (el_val_t)(ua.d < ub.d);
}

static inline el_val_t float_gt(el_val_t a, el_val_t b) {
    union { double d; int64_t i; } ua, ub;
    ua.i = a; ub.i = b;
    return (el_val_t)(ua.d > ub.d);
}

static inline el_val_t float_lte(el_val_t a, el_val_t b) {
    union { double d; int64_t i; } ua, ub;
    ua.i = a; ub.i = b;
    return (el_val_t)(ua.d <= ub.d);
}

static inline el_val_t float_gte(el_val_t a, el_val_t b) {
    union { double d; int64_t i; } ua, ub;
    ua.i = a; ub.i = b;
    return (el_val_t)(ua.d >= ub.d);
}

static inline el_val_t float_eq(el_val_t a, el_val_t b) {
    union { double d; int64_t i; } ua, ub;
    ua.i = a; ub.i = b;
    return (el_val_t)(ua.d == ub.d);
}

#endif /* EL_FLOAT_OPS_DEFINED */

/* ── Native widget system (macOS AppKit) ────────────────────────────────────
 * Available when compiled with -DEL_TARGET_MACOS and linked with el_appkit.m.
 * Widget handles are opaque int64_t slot indices; -1 = invalid. */

#ifdef EL_TARGET_MACOS

/* Initialisation */
void      __native_init(void);
void      __native_run_loop(void);

/* Window */
el_val_t  __window_create(el_val_t title, el_val_t width, el_val_t height,
                           el_val_t min_width, el_val_t min_height);
void      __window_show(el_val_t handle);
void      __window_set_title(el_val_t handle, el_val_t title);

/* Layout containers */
el_val_t  __vstack_create(el_val_t spacing);
el_val_t  __hstack_create(el_val_t spacing);
el_val_t  __zstack_create(void);
el_val_t  __scroll_create(void);

/* Widgets */
el_val_t  __label_create(el_val_t text);
el_val_t  __button_create(el_val_t label);
el_val_t  __text_field_create(el_val_t placeholder);
el_val_t  __text_area_create(el_val_t placeholder);
el_val_t  __image_create(el_val_t path_or_name);

/* Widget properties */
void      __widget_set_text(el_val_t handle, el_val_t text);
el_val_t  __widget_get_text(el_val_t handle);
void      __widget_set_color(el_val_t handle, el_val_t r, el_val_t g,
                              el_val_t b, el_val_t a);
void      __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g,
                                 el_val_t b, el_val_t a);
void      __widget_set_font(el_val_t handle, el_val_t family,
                             el_val_t size, el_val_t bold);
void      __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right,
                                el_val_t bottom, el_val_t left);
void      __widget_set_width(el_val_t handle, el_val_t width);
void      __widget_set_height(el_val_t handle, el_val_t height);
void      __widget_set_flex(el_val_t handle, el_val_t flex);
void      __widget_set_corner_radius(el_val_t handle, el_val_t radius);
void      __widget_set_disabled(el_val_t handle, el_val_t disabled);
void      __widget_set_hidden(el_val_t handle, el_val_t hidden);

/* Layout / tree */
void      __widget_add_child(el_val_t parent, el_val_t child);
void      __widget_remove_child(el_val_t parent, el_val_t child);
void      __widget_destroy(el_val_t handle);

/* Events */
void      __widget_on_click(el_val_t handle, el_val_t fn_name);
void      __widget_on_change(el_val_t handle, el_val_t fn_name);
void      __widget_on_submit(el_val_t handle, el_val_t fn_name);

/* Manifest reader */
el_val_t  __manifest_read(el_val_t path);

#endif /* EL_TARGET_MACOS */

/* ── Native widget system (Linux GTK4) ──────────────────────────────────────
 * Available when compiled with -DEL_TARGET_LINUX and linked with el_gtk4.c.
 * Widget handles are opaque int64_t slot indices; -1 = invalid.
 * All functions have the same signatures as EL_TARGET_MACOS above. */

#ifdef EL_TARGET_LINUX

/* Initialisation */
void      __native_init(void);
void      __native_run_loop(void);

/* Window */
el_val_t  __window_create(el_val_t title, el_val_t width, el_val_t height,
                           el_val_t min_width, el_val_t min_height);
void      __window_show(el_val_t handle);
void      __window_set_title(el_val_t handle, el_val_t title);

/* Layout containers */
el_val_t  __vstack_create(el_val_t spacing);
el_val_t  __hstack_create(el_val_t spacing);
el_val_t  __zstack_create(void);
el_val_t  __scroll_create(void);

/* Widgets */
el_val_t  __label_create(el_val_t text);
el_val_t  __button_create(el_val_t label);
el_val_t  __text_field_create(el_val_t placeholder);
el_val_t  __text_area_create(el_val_t placeholder);
el_val_t  __image_create(el_val_t path_or_name);

/* Widget properties */
void      __widget_set_text(el_val_t handle, el_val_t text);
el_val_t  __widget_get_text(el_val_t handle);
void      __widget_set_color(el_val_t handle, el_val_t r, el_val_t g,
                              el_val_t b, el_val_t a);
void      __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g,
                                 el_val_t b, el_val_t a);
void      __widget_set_font(el_val_t handle, el_val_t family,
                             el_val_t size, el_val_t bold);
void      __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right,
                                el_val_t bottom, el_val_t left);
void      __widget_set_width(el_val_t handle, el_val_t width);
void      __widget_set_height(el_val_t handle, el_val_t height);
void      __widget_set_flex(el_val_t handle, el_val_t flex);
void      __widget_set_corner_radius(el_val_t handle, el_val_t radius);
void      __widget_set_disabled(el_val_t handle, el_val_t disabled);
void      __widget_set_hidden(el_val_t handle, el_val_t hidden);

/* Layout / tree */
void      __widget_add_child(el_val_t parent, el_val_t child);
void      __widget_remove_child(el_val_t parent, el_val_t child);
void      __widget_destroy(el_val_t handle);

/* Events */
void      __widget_on_click(el_val_t handle, el_val_t fn_name);
void      __widget_on_change(el_val_t handle, el_val_t fn_name);
void      __widget_on_submit(el_val_t handle, el_val_t fn_name);

/* Manifest reader — same JSON output as EL_TARGET_MACOS */
el_val_t  __manifest_read(el_val_t path);

#endif /* EL_TARGET_LINUX */

/* ── Native widget system (Windows Win32) ───────────────────────────────────
 * Available when compiled with -DEL_TARGET_WIN32 and linked with el_win32.c.
 * Widget handles are opaque int64_t slot indices; -1 = invalid.
 * Link: el_win32.obj comctl32.lib user32.lib gdi32.lib */

#ifdef EL_TARGET_WIN32

/* Initialisation */
void      __native_init(void);
void      __native_run_loop(void);

/* Window */
el_val_t  __window_create(el_val_t title, el_val_t width, el_val_t height,
                           el_val_t min_width, el_val_t min_height);
void      __window_show(el_val_t handle);
void      __window_set_title(el_val_t handle, el_val_t title);

/* Layout containers */
el_val_t  __vstack_create(el_val_t spacing);
el_val_t  __hstack_create(el_val_t spacing);
el_val_t  __zstack_create(void);
el_val_t  __scroll_create(void);

/* Widgets */
el_val_t  __label_create(el_val_t text);
el_val_t  __button_create(el_val_t label);
el_val_t  __text_field_create(el_val_t placeholder);
el_val_t  __text_area_create(el_val_t placeholder);
el_val_t  __image_create(el_val_t path_or_name);

/* Widget properties */
void      __widget_set_text(el_val_t handle, el_val_t text);
el_val_t  __widget_get_text(el_val_t handle);
void      __widget_set_color(el_val_t handle, el_val_t r, el_val_t g,
                              el_val_t b, el_val_t a);
void      __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g,
                                 el_val_t b, el_val_t a);
void      __widget_set_font(el_val_t handle, el_val_t family,
                             el_val_t size, el_val_t bold);
void      __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right,
                                el_val_t bottom, el_val_t left);
void      __widget_set_width(el_val_t handle, el_val_t width);
void      __widget_set_height(el_val_t handle, el_val_t height);
void      __widget_set_flex(el_val_t handle, el_val_t flex);
void      __widget_set_corner_radius(el_val_t handle, el_val_t radius);
void      __widget_set_disabled(el_val_t handle, el_val_t disabled);
void      __widget_set_hidden(el_val_t handle, el_val_t hidden);

/* Layout / tree */
void      __widget_add_child(el_val_t parent, el_val_t child);
void      __widget_remove_child(el_val_t parent, el_val_t child);
void      __widget_destroy(el_val_t handle);

/* Events */
void      __widget_on_click(el_val_t handle, el_val_t fn_name);
void      __widget_on_change(el_val_t handle, el_val_t fn_name);
void      __widget_on_submit(el_val_t handle, el_val_t fn_name);

/* Manifest reader */
el_val_t  __manifest_read(el_val_t path);

#endif /* EL_TARGET_WIN32 */

/* ── Native widget system (iOS UIKit) ───────────────────────────────────────
 * Available when compiled with -DEL_TARGET_IOS and linked with el_uikit.m.
 * Widget handles are opaque int64_t slot indices; -1 = invalid.
 *
 * iOS lifecycle note: UIApplicationMain never returns. The el program must
 * store its UI-build logic in a void(*)(void) function pointer, assign it to
 * el_main_entry_fn, then call __native_run_loop. ElAppDelegate invokes
 * el_main_entry_fn inside didFinishLaunchingWithOptions.
 * Call el_uikit_set_args(argc, argv) from main() before __native_run_loop. */

#ifdef EL_TARGET_IOS

/* Lifecycle entry-function hook — set before calling __native_run_loop. */
extern void (*el_main_entry_fn)(void);

/* Forward argc/argv from main() to UIApplicationMain. */
void      el_uikit_set_args(int argc, char** argv);

/* Initialisation */
void      __native_init(void);
void      __native_run_loop(void);

/* Window */
el_val_t  __window_create(el_val_t title, el_val_t width, el_val_t height,
                           el_val_t min_width, el_val_t min_height);
void      __window_show(el_val_t handle);
void      __window_set_title(el_val_t handle, el_val_t title);

/* Layout containers */
el_val_t  __vstack_create(el_val_t spacing);
el_val_t  __hstack_create(el_val_t spacing);
el_val_t  __zstack_create(void);
el_val_t  __scroll_create(void);

/* Widgets */
el_val_t  __label_create(el_val_t text);
el_val_t  __button_create(el_val_t label);
el_val_t  __text_field_create(el_val_t placeholder);
el_val_t  __text_area_create(el_val_t placeholder);
el_val_t  __image_create(el_val_t path_or_name);

/* Widget properties */
void      __widget_set_text(el_val_t handle, el_val_t text);
el_val_t  __widget_get_text(el_val_t handle);
void      __widget_set_color(el_val_t handle, el_val_t r, el_val_t g,
                              el_val_t b, el_val_t a);
void      __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g,
                                 el_val_t b, el_val_t a);
void      __widget_set_font(el_val_t handle, el_val_t family,
                             el_val_t size, el_val_t bold);
void      __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right,
                                el_val_t bottom, el_val_t left);
void      __widget_set_width(el_val_t handle, el_val_t width);
void      __widget_set_height(el_val_t handle, el_val_t height);
void      __widget_set_flex(el_val_t handle, el_val_t flex);
void      __widget_set_corner_radius(el_val_t handle, el_val_t radius);
void      __widget_set_disabled(el_val_t handle, el_val_t disabled);
void      __widget_set_hidden(el_val_t handle, el_val_t hidden);

/* Layout / tree */
void      __widget_add_child(el_val_t parent, el_val_t child);
void      __widget_remove_child(el_val_t parent, el_val_t child);
void      __widget_destroy(el_val_t handle);

/* Events */
void      __widget_on_click(el_val_t handle, el_val_t fn_name);
void      __widget_on_change(el_val_t handle, el_val_t fn_name);
void      __widget_on_submit(el_val_t handle, el_val_t fn_name);

/* Manifest reader */
el_val_t  __manifest_read(el_val_t path);

#endif /* EL_TARGET_IOS */

/* ── Native widget system (Android JNI) ─────────────────────────────────────
 * Available when compiled with -DEL_TARGET_ANDROID and linked with
 * libelruntime.so (which includes el_android.c compiled by the NDK build).
 * Widget handles are opaque int64_t slot indices; -1 = invalid.
 *
 * Java companion: ElBridge.java (package com.neuron.el) must be compiled into
 * the APK. The Activity must call ElBridge.init(this) before any widget ops.
 *
 * Link flags (in Android.mk or CMakeLists.txt):
 *   -landroid -llog -ldl */

#ifdef EL_TARGET_ANDROID

/* Initialisation */
void      __native_init(void);
void      __native_run_loop(void);   /* no-op on Android */

/* Window */
el_val_t  __window_create(el_val_t title, el_val_t width, el_val_t height,
                           el_val_t min_width, el_val_t min_height);
void      __window_show(el_val_t handle);
void      __window_set_title(el_val_t handle, el_val_t title);

/* Layout containers */
el_val_t  __vstack_create(el_val_t spacing);
el_val_t  __hstack_create(el_val_t spacing);
el_val_t  __zstack_create(void);
el_val_t  __scroll_create(void);

/* Widgets */
el_val_t  __label_create(el_val_t text);
el_val_t  __button_create(el_val_t label);
el_val_t  __text_field_create(el_val_t placeholder);
el_val_t  __text_area_create(el_val_t placeholder);
el_val_t  __image_create(el_val_t path_or_name);

/* Widget properties */
void      __widget_set_text(el_val_t handle, el_val_t text);
el_val_t  __widget_get_text(el_val_t handle);
void      __widget_set_color(el_val_t handle, el_val_t r, el_val_t g,
                              el_val_t b, el_val_t a);
void      __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g,
                                 el_val_t b, el_val_t a);
void      __widget_set_font(el_val_t handle, el_val_t family,
                             el_val_t size, el_val_t bold);
void      __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right,
                                el_val_t bottom, el_val_t left);
void      __widget_set_width(el_val_t handle, el_val_t width);
void      __widget_set_height(el_val_t handle, el_val_t height);
void      __widget_set_flex(el_val_t handle, el_val_t flex);
void      __widget_set_corner_radius(el_val_t handle, el_val_t radius);
void      __widget_set_disabled(el_val_t handle, el_val_t disabled);
void      __widget_set_hidden(el_val_t handle, el_val_t hidden);

/* Layout / tree */
void      __widget_add_child(el_val_t parent, el_val_t child);
void      __widget_remove_child(el_val_t parent, el_val_t child);
void      __widget_destroy(el_val_t handle);

/* Events */
void      __widget_on_click(el_val_t handle, el_val_t fn_name);
void      __widget_on_change(el_val_t handle, el_val_t fn_name);
void      __widget_on_submit(el_val_t handle, el_val_t fn_name);

/* Manifest reader */
el_val_t  __manifest_read(el_val_t path);

#endif /* EL_TARGET_ANDROID */

/* ── Native widget system (LVGL v9 — embedded / microcontroller) ─────────────
 * Available when compiled with -DEL_TARGET_LVGL and linked with el_lvgl.c
 * and the LVGL library (lvgl.a or lvgl source tree).
 *
 * Target platforms: ESP32, STM32, industrial panels. Any system with 256KB+
 * RAM and an LVGL-compatible display driver. No OS required.
 *
 * Widget handles are opaque int64_t slot indices; -1 = invalid.
 *
 * Bare-metal / no dynamic linker:
 *   Compile with -DEL_LVGL_NO_DLSYM and provide:
 *     el_val_t el_lvgl_dispatch(const char *fn, el_val_t a, el_val_t b);
 *
 * Compile:
 *   gcc -DEL_TARGET_LVGL -I./lvgl el_lvgl.c -c -o el_lvgl.o
 *   # Then link with lvgl.a. */

#ifdef EL_TARGET_LVGL

/* Initialisation */
void      __native_init(void);
void      __native_run_loop(void);

/* Window */
el_val_t  __window_create(el_val_t title, el_val_t width, el_val_t height,
                           el_val_t min_width, el_val_t min_height);
void      __window_show(el_val_t handle);
void      __window_set_title(el_val_t handle, el_val_t title);

/* Layout containers */
el_val_t  __vstack_create(el_val_t spacing);
el_val_t  __hstack_create(el_val_t spacing);
el_val_t  __zstack_create(void);
el_val_t  __scroll_create(void);

/* Widgets */
el_val_t  __label_create(el_val_t text);
el_val_t  __button_create(el_val_t label);
el_val_t  __text_field_create(el_val_t placeholder);
el_val_t  __text_area_create(el_val_t placeholder);
el_val_t  __image_create(el_val_t path_or_name);

/* Widget properties */
void      __widget_set_text(el_val_t handle, el_val_t text);
el_val_t  __widget_get_text(el_val_t handle);
void      __widget_set_color(el_val_t handle, el_val_t r, el_val_t g,
                              el_val_t b, el_val_t a);
void      __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g,
                                 el_val_t b, el_val_t a);
void      __widget_set_font(el_val_t handle, el_val_t family,
                             el_val_t size, el_val_t bold);
void      __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right,
                                el_val_t bottom, el_val_t left);
void      __widget_set_width(el_val_t handle, el_val_t width);
void      __widget_set_height(el_val_t handle, el_val_t height);
void      __widget_set_flex(el_val_t handle, el_val_t flex);
void      __widget_set_corner_radius(el_val_t handle, el_val_t radius);
void      __widget_set_disabled(el_val_t handle, el_val_t disabled);
void      __widget_set_hidden(el_val_t handle, el_val_t hidden);

/* Layout / tree */
void      __widget_add_child(el_val_t parent, el_val_t child);
void      __widget_remove_child(el_val_t parent, el_val_t child);
void      __widget_destroy(el_val_t handle);

/* Events */
void      __widget_on_click(el_val_t handle, el_val_t fn_name);
void      __widget_on_change(el_val_t handle, el_val_t fn_name);
void      __widget_on_submit(el_val_t handle, el_val_t fn_name);

/* Manifest reader — same JSON output as all other native targets */
el_val_t  __manifest_read(el_val_t path);

#endif /* EL_TARGET_LVGL */

/* ── Native widget system (SDL2 — embedded / Pi) ────────────────────────────
 * Available when compiled with -DEL_TARGET_SDL2 and linked with el_sdl2.c.
 * Widget handles are opaque int64_t slot indices; -1 = invalid.
 *
 * Target: Raspberry Pi Zero, embedded Linux, any system with a framebuffer
 * and SDL2 available. No GTK, no desktop environment required.
 *
 * Compile:
 *   gcc -DEL_TARGET_SDL2 $(sdl2-config --cflags) -c el_sdl2.c -o el_sdl2.o
 * Link:
 *   $(sdl2-config --libs) -lSDL2_ttf -lSDL2_image -ldl */

#ifdef EL_TARGET_SDL2

/* Initialisation */
void      __native_init(void);
void      __native_run_loop(void);

/* Window */
el_val_t  __window_create(el_val_t title, el_val_t width, el_val_t height,
                           el_val_t min_width, el_val_t min_height);
void      __window_show(el_val_t handle);
void      __window_set_title(el_val_t handle, el_val_t title);

/* Layout containers */
el_val_t  __vstack_create(el_val_t spacing);
el_val_t  __hstack_create(el_val_t spacing);
el_val_t  __zstack_create(void);
el_val_t  __scroll_create(void);

/* Widgets */
el_val_t  __label_create(el_val_t text);
el_val_t  __button_create(el_val_t label);
el_val_t  __text_field_create(el_val_t placeholder);
el_val_t  __text_area_create(el_val_t placeholder);
el_val_t  __image_create(el_val_t path_or_name);

/* Widget properties */
void      __widget_set_text(el_val_t handle, el_val_t text);
el_val_t  __widget_get_text(el_val_t handle);
void      __widget_set_color(el_val_t handle, el_val_t r, el_val_t g,
                              el_val_t b, el_val_t a);
void      __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g,
                                 el_val_t b, el_val_t a);
void      __widget_set_font(el_val_t handle, el_val_t family,
                             el_val_t size, el_val_t bold);
void      __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right,
                                el_val_t bottom, el_val_t left);
void      __widget_set_width(el_val_t handle, el_val_t width);
void      __widget_set_height(el_val_t handle, el_val_t height);
void      __widget_set_flex(el_val_t handle, el_val_t flex);
void      __widget_set_corner_radius(el_val_t handle, el_val_t radius);
void      __widget_set_disabled(el_val_t handle, el_val_t disabled);
void      __widget_set_hidden(el_val_t handle, el_val_t hidden);

/* Layout / tree */
void      __widget_add_child(el_val_t parent, el_val_t child);
void      __widget_remove_child(el_val_t parent, el_val_t child);
void      __widget_destroy(el_val_t handle);

/* Events */
void      __widget_on_click(el_val_t handle, el_val_t fn_name);
void      __widget_on_change(el_val_t handle, el_val_t fn_name);
void      __widget_on_submit(el_val_t handle, el_val_t fn_name);

/* Manifest reader */
el_val_t  __manifest_read(el_val_t path);

#endif /* EL_TARGET_SDL2 */
