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

el_val_t native_init(void);
el_val_t native_run_loop(void);
el_val_t manifest_read(el_val_t path);
el_val_t manifest_title(el_val_t m);
el_val_t manifest_width(el_val_t m);
el_val_t manifest_height(el_val_t m);
el_val_t manifest_min_width(el_val_t m);
el_val_t manifest_min_height(el_val_t m);
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);
el_val_t window_from_manifest(el_val_t manifest_path);
el_val_t window_show(el_val_t handle);
el_val_t window_set_title(el_val_t handle, el_val_t title);
el_val_t vstack(el_val_t spacing);
el_val_t vstack_tight(void);
el_val_t hstack(el_val_t spacing);
el_val_t zstack(void);
el_val_t scroll(void);
el_val_t label(el_val_t text);
el_val_t button(el_val_t label);
el_val_t text_field(el_val_t placeholder);
el_val_t text_area(el_val_t placeholder);
el_val_t image(el_val_t path_or_name);
el_val_t widget_set_text(el_val_t handle, el_val_t text);
el_val_t widget_get_text(el_val_t handle);
el_val_t widget_set_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a);
el_val_t widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a);
el_val_t widget_set_font(el_val_t handle, el_val_t family, el_val_t size, el_val_t bold);
el_val_t widget_set_padding(el_val_t handle, el_val_t top, el_val_t right, el_val_t bottom, el_val_t left);
el_val_t widget_set_padding_all(el_val_t handle, el_val_t p);
el_val_t widget_set_padding_xy(el_val_t handle, el_val_t px, el_val_t py);
el_val_t widget_set_width(el_val_t handle, el_val_t width);
el_val_t widget_set_height(el_val_t handle, el_val_t height);
el_val_t widget_set_flex(el_val_t handle, el_val_t flex);
el_val_t widget_set_corner_radius(el_val_t handle, el_val_t radius);
el_val_t widget_set_disabled(el_val_t handle, el_val_t disabled);
el_val_t widget_set_hidden(el_val_t handle, el_val_t hidden);
el_val_t widget_add_child(el_val_t parent, el_val_t child);
el_val_t widget_remove_child(el_val_t parent, el_val_t child);
el_val_t widget_destroy(el_val_t handle);
el_val_t widget_on_click(el_val_t handle, el_val_t fn_name);
el_val_t widget_on_change(el_val_t handle, el_val_t fn_name);
el_val_t widget_on_submit(el_val_t handle, el_val_t fn_name);
el_val_t hex_channel(el_val_t s, el_val_t offset);
el_val_t hex_nibble(el_val_t c);
el_val_t color_hex_r(el_val_t hex);
el_val_t color_hex_g(el_val_t hex);
el_val_t color_hex_b(el_val_t hex);
el_val_t color_hex_a(el_val_t hex);
el_val_t widget_set_color_hex(el_val_t handle, el_val_t hex);
el_val_t widget_set_bg_color_hex(el_val_t handle, el_val_t hex);
el_val_t style_surface(el_val_t handle);
el_val_t style_button_primary(el_val_t handle);
el_val_t style_label_body(el_val_t handle);
el_val_t style_label_heading(el_val_t handle);
el_val_t style_label_muted(el_val_t handle);

el_val_t TOKEN_PRIMARY;
el_val_t TOKEN_ON_PRIMARY;
el_val_t TOKEN_BACKGROUND;
el_val_t TOKEN_ON_BG;
el_val_t TOKEN_SURFACE;
el_val_t TOKEN_ON_SURFACE;
el_val_t TOKEN_OUTLINE;
el_val_t TOKEN_ERROR;

el_val_t native_init(void) {
  __native_init();
  return 0;
}

el_val_t native_run_loop(void) {
  __native_run_loop();
  return 0;
}

el_val_t manifest_read(el_val_t path) {
  return __manifest_read(path);
  return 0;
}

el_val_t manifest_title(el_val_t m) {
  return json_get_string(m, EL_STR("title"));
  return 0;
}

el_val_t manifest_width(el_val_t m) {
  return json_get_int(m, EL_STR("width"));
  return 0;
}

el_val_t manifest_height(el_val_t m) {
  return json_get_int(m, EL_STR("height"));
  return 0;
}

el_val_t manifest_min_width(el_val_t m) {
  return json_get_int(m, EL_STR("min_width"));
  return 0;
}

el_val_t manifest_min_height(el_val_t m) {
  return json_get_int(m, EL_STR("min_height"));
  return 0;
}

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) {
  return __window_create(title, width, height, min_width, min_height);
  return 0;
}

el_val_t window_from_manifest(el_val_t manifest_path) {
  el_val_t m = manifest_read(manifest_path);
  el_val_t title = manifest_title(m);
  el_val_t w = manifest_width(m);
  el_val_t h = manifest_height(m);
  el_val_t mw = manifest_min_width(m);
  el_val_t mh = manifest_min_height(m);
  el_val_t safe_w = ({ el_val_t _if_result_1 = 0; if ((w > 0)) { _if_result_1 = (w); } else { _if_result_1 = (1200); } _if_result_1; });
  el_val_t safe_h = ({ el_val_t _if_result_2 = 0; if ((h > 0)) { _if_result_2 = (h); } else { _if_result_2 = (800); } _if_result_2; });
  el_val_t safe_mw = ({ el_val_t _if_result_3 = 0; if ((mw > 0)) { _if_result_3 = (mw); } else { _if_result_3 = (600); } _if_result_3; });
  el_val_t safe_mh = ({ el_val_t _if_result_4 = 0; if ((mh > 0)) { _if_result_4 = (mh); } else { _if_result_4 = (400); } _if_result_4; });
  el_val_t safe_t = ({ el_val_t _if_result_5 = 0; if ((str_len(title) > 0)) { _if_result_5 = (title); } else { _if_result_5 = (EL_STR("App")); } _if_result_5; });
  return window_create(safe_t, safe_w, safe_h, safe_mw, safe_mh);
  return 0;
}

el_val_t window_show(el_val_t handle) {
  __window_show(handle);
  return 0;
}

el_val_t window_set_title(el_val_t handle, el_val_t title) {
  __window_set_title(handle, title);
  return 0;
}

el_val_t vstack(el_val_t spacing) {
  return __vstack_create(spacing);
  return 0;
}

el_val_t vstack_tight(void) {
  return __vstack_create(0);
  return 0;
}

el_val_t hstack(el_val_t spacing) {
  return __hstack_create(spacing);
  return 0;
}

el_val_t zstack(void) {
  return __zstack_create();
  return 0;
}

el_val_t scroll(void) {
  return __scroll_create();
  return 0;
}

el_val_t label(el_val_t text) {
  return __label_create(text);
  return 0;
}

el_val_t button(el_val_t label) {
  return __button_create(label);
  return 0;
}

el_val_t text_field(el_val_t placeholder) {
  return __text_field_create(placeholder);
  return 0;
}

el_val_t text_area(el_val_t placeholder) {
  return __text_area_create(placeholder);
  return 0;
}

el_val_t image(el_val_t path_or_name) {
  return __image_create(path_or_name);
  return 0;
}

el_val_t widget_set_text(el_val_t handle, el_val_t text) {
  __widget_set_text(handle, text);
  return 0;
}

el_val_t widget_get_text(el_val_t handle) {
  return __widget_get_text(handle);
  return 0;
}

el_val_t widget_set_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a) {
  __widget_set_color(handle, r, g, b, a);
  return 0;
}

el_val_t widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a) {
  __widget_set_bg_color(handle, r, g, b, a);
  return 0;
}

el_val_t widget_set_font(el_val_t handle, el_val_t family, el_val_t size, el_val_t bold) {
  el_val_t bold_int = ({ el_val_t _if_result_6 = 0; if (bold) { _if_result_6 = (1); } else { _if_result_6 = (0); } _if_result_6; });
  __widget_set_font(handle, family, size, bold_int);
  return 0;
}

el_val_t widget_set_padding(el_val_t handle, el_val_t top, el_val_t right, el_val_t bottom, el_val_t left) {
  __widget_set_padding(handle, top, right, bottom, left);
  return 0;
}

el_val_t widget_set_padding_all(el_val_t handle, el_val_t p) {
  __widget_set_padding(handle, p, p, p, p);
  return 0;
}

el_val_t widget_set_padding_xy(el_val_t handle, el_val_t px, el_val_t py) {
  __widget_set_padding(handle, py, px, py, px);
  return 0;
}

el_val_t widget_set_width(el_val_t handle, el_val_t width) {
  __widget_set_width(handle, width);
  return 0;
}

el_val_t widget_set_height(el_val_t handle, el_val_t height) {
  __widget_set_height(handle, height);
  return 0;
}

el_val_t widget_set_flex(el_val_t handle, el_val_t flex) {
  __widget_set_flex(handle, flex);
  return 0;
}

el_val_t widget_set_corner_radius(el_val_t handle, el_val_t radius) {
  __widget_set_corner_radius(handle, radius);
  return 0;
}

el_val_t widget_set_disabled(el_val_t handle, el_val_t disabled) {
  el_val_t d = ({ el_val_t _if_result_7 = 0; if (disabled) { _if_result_7 = (1); } else { _if_result_7 = (0); } _if_result_7; });
  __widget_set_disabled(handle, d);
  return 0;
}

el_val_t widget_set_hidden(el_val_t handle, el_val_t hidden) {
  el_val_t h = ({ el_val_t _if_result_8 = 0; if (hidden) { _if_result_8 = (1); } else { _if_result_8 = (0); } _if_result_8; });
  __widget_set_hidden(handle, h);
  return 0;
}

el_val_t widget_add_child(el_val_t parent, el_val_t child) {
  __widget_add_child(parent, child);
  return 0;
}

el_val_t widget_remove_child(el_val_t parent, el_val_t child) {
  __widget_remove_child(parent, child);
  return 0;
}

el_val_t widget_destroy(el_val_t handle) {
  __widget_destroy(handle);
  return 0;
}

el_val_t widget_on_click(el_val_t handle, el_val_t fn_name) {
  __widget_on_click(handle, fn_name);
  return 0;
}

el_val_t widget_on_change(el_val_t handle, el_val_t fn_name) {
  __widget_on_change(handle, fn_name);
  return 0;
}

el_val_t widget_on_submit(el_val_t handle, el_val_t fn_name) {
  __widget_on_submit(handle, fn_name);
  return 0;
}

el_val_t hex_channel(el_val_t s, el_val_t offset) {
  el_val_t hi = str_slice(s, offset, (offset + 1));
  el_val_t lo = str_slice(s, (offset + 1), (offset + 2));
  el_val_t h = hex_nibble(hi);
  el_val_t l = hex_nibble(lo);
  return ((h * 16) + l);
  return 0;
}

el_val_t hex_nibble(el_val_t c) {
  if (str_eq(c, EL_STR("0"))) {
    return 0;
  }
  if (str_eq(c, EL_STR("1"))) {
    return 1;
  }
  if (str_eq(c, EL_STR("2"))) {
    return 2;
  }
  if (str_eq(c, EL_STR("3"))) {
    return 3;
  }
  if (str_eq(c, EL_STR("4"))) {
    return 4;
  }
  if (str_eq(c, EL_STR("5"))) {
    return 5;
  }
  if (str_eq(c, EL_STR("6"))) {
    return 6;
  }
  if (str_eq(c, EL_STR("7"))) {
    return 7;
  }
  if (str_eq(c, EL_STR("8"))) {
    return 8;
  }
  if (str_eq(c, EL_STR("9"))) {
    return 9;
  }
  if (str_eq(c, EL_STR("a"))) {
    return 10;
  }
  if (str_eq(c, EL_STR("b"))) {
    return 11;
  }
  if (str_eq(c, EL_STR("c"))) {
    return 12;
  }
  if (str_eq(c, EL_STR("d"))) {
    return 13;
  }
  if (str_eq(c, EL_STR("e"))) {
    return 14;
  }
  if (str_eq(c, EL_STR("f"))) {
    return 15;
  }
  if (str_eq(c, EL_STR("A"))) {
    return 10;
  }
  if (str_eq(c, EL_STR("B"))) {
    return 11;
  }
  if (str_eq(c, EL_STR("C"))) {
    return 12;
  }
  if (str_eq(c, EL_STR("D"))) {
    return 13;
  }
  if (str_eq(c, EL_STR("E"))) {
    return 14;
  }
  if (str_eq(c, EL_STR("F"))) {
    return 15;
  }
  return 0;
  return 0;
}

el_val_t color_hex_r(el_val_t hex) {
  el_val_t s = ({ el_val_t _if_result_9 = 0; if (str_starts_with(hex, EL_STR("#"))) { _if_result_9 = (str_slice(hex, 1, str_len(hex))); } else { _if_result_9 = (hex); } _if_result_9; });
  el_val_t v = hex_channel(s, 0);
  return float_div(int_to_float(v), el_from_float(255.0));
  return 0;
}

el_val_t color_hex_g(el_val_t hex) {
  el_val_t s = ({ el_val_t _if_result_10 = 0; if (str_starts_with(hex, EL_STR("#"))) { _if_result_10 = (str_slice(hex, 1, str_len(hex))); } else { _if_result_10 = (hex); } _if_result_10; });
  el_val_t v = hex_channel(s, 2);
  return float_div(int_to_float(v), el_from_float(255.0));
  return 0;
}

el_val_t color_hex_b(el_val_t hex) {
  el_val_t s = ({ el_val_t _if_result_11 = 0; if (str_starts_with(hex, EL_STR("#"))) { _if_result_11 = (str_slice(hex, 1, str_len(hex))); } else { _if_result_11 = (hex); } _if_result_11; });
  el_val_t v = hex_channel(s, 4);
  return float_div(int_to_float(v), el_from_float(255.0));
  return 0;
}

el_val_t color_hex_a(el_val_t hex) {
  el_val_t s = ({ el_val_t _if_result_12 = 0; if (str_starts_with(hex, EL_STR("#"))) { _if_result_12 = (str_slice(hex, 1, str_len(hex))); } else { _if_result_12 = (hex); } _if_result_12; });
  if (str_len(s) < 8) {
    return el_from_float(1.0);
  }
  el_val_t v = hex_channel(s, 6);
  return float_div(int_to_float(v), el_from_float(255.0));
  return 0;
}

el_val_t widget_set_color_hex(el_val_t handle, el_val_t hex) {
  widget_set_color(handle, color_hex_r(hex), color_hex_g(hex), color_hex_b(hex), color_hex_a(hex));
  return 0;
}

el_val_t widget_set_bg_color_hex(el_val_t handle, el_val_t hex) {
  widget_set_bg_color(handle, color_hex_r(hex), color_hex_g(hex), color_hex_b(hex), color_hex_a(hex));
  return 0;
}

el_val_t style_surface(el_val_t handle) {
  widget_set_bg_color_hex(handle, TOKEN_SURFACE);
  widget_set_corner_radius(handle, 8);
  return 0;
}

el_val_t style_button_primary(el_val_t handle) {
  widget_set_bg_color_hex(handle, TOKEN_PRIMARY);
  widget_set_color_hex(handle, TOKEN_ON_PRIMARY);
  widget_set_corner_radius(handle, 8);
  widget_set_padding_xy(handle, 16, 8);
  return 0;
}

el_val_t style_label_body(el_val_t handle) {
  widget_set_color_hex(handle, TOKEN_ON_BG);
  widget_set_font(handle, EL_STR("system"), 14, 0);
  return 0;
}

el_val_t style_label_heading(el_val_t handle) {
  widget_set_color_hex(handle, TOKEN_ON_BG);
  widget_set_font(handle, EL_STR("system"), 20, 1);
  return 0;
}

el_val_t style_label_muted(el_val_t handle) {
  widget_set_color_hex(handle, TOKEN_OUTLINE);
  widget_set_font(handle, EL_STR("system"), 12, 0);
  return 0;
}

int el_vessel_main(int _argc, char** _argv) {
  el_runtime_init_args(_argc, _argv);
  TOKEN_PRIMARY = EL_STR("#60a5fa");
  TOKEN_ON_PRIMARY = EL_STR("#0f172a");
  TOKEN_BACKGROUND = EL_STR("#0f172a");
  TOKEN_ON_BG = EL_STR("#f8fafc");
  TOKEN_SURFACE = EL_STR("#1e293b");
  TOKEN_ON_SURFACE = EL_STR("#f8fafc");
  TOKEN_OUTLINE = EL_STR("#475569");
  TOKEN_ERROR = EL_STR("#f87171");
  return 0;
}

