// Show something on screen — a UIWindow with a colored UIViewController root.
//
// Builds on 5.7's AppDelegate. Inside `didFinishLaunching`, we:
//   1. [[UIWindow alloc] initWithFrame:CGRect]
//   2. [[UIViewController alloc] init]; set view.backgroundColor
//   3. window.rootViewController = vc
//   4. [window makeKeyAndVisible]
//
// We hardcode the frame to 1024×1024 to avoid the struct-return ABI of
// `[UIScreen mainScreen].bounds` for now — any frame bigger than the device
// covers the screen, modulo safe-area insets.
//
// `g_window` is a module-level global so the window outlives the IMP scope
// (no ARC; UIKit retains it as the key window anyway).

#import "modules/std.sx";
#import "modules/ffi/objc.sx";

#framework "UIKit";

UIApplicationMain :: (argc: i32, argv: *void, principal_class: *NSString, delegate_class: *NSString) -> i32 extern;

g_window : *void = ---;

// AppDelegate's `window` property. iOS queries this getter to discover the
// app's key window; without it, the legacy code path creates its own empty
// window and ignores anything we configure.
window_getter :: (self: *void, _cmd: *void) -> *void abi(.c) {
    return g_window;
}
window_setter :: (self: *void, _cmd: *void, w: *void) abi(.c) {
    g_window = w;
}

did_finish_launching :: (self: *void, _cmd: *void, app: *void, opts: *void) -> u8 abi(.c) {
    UIWindow         := objc_getClass("UIWindow".ptr);
    UIViewController := objc_getClass("UIViewController".ptr);
    UIColor          := objc_getClass("UIColor".ptr);

    sel_alloc            := sel_registerName("alloc".ptr);
    sel_init             := sel_registerName("init".ptr);
    sel_init_with_scene  := sel_registerName("initWithWindowScene:".ptr);
    sel_view             := sel_registerName("view".ptr);
    sel_system_blue      := sel_registerName("systemBlueColor".ptr);
    sel_set_bg           := sel_registerName("setBackgroundColor:".ptr);
    sel_set_root_vc      := sel_registerName("setRootViewController:".ptr);
    sel_make_key_visible := sel_registerName("makeKeyAndVisible".ptr);
    sel_connected_scenes := sel_registerName("connectedScenes".ptr);
    sel_any_object       := sel_registerName("anyObject".ptr);

    msg_o   : (*void, *void)               -> *void abi(.c) = xx objc_msgSend;
    msg_v   : (*void, *void)               -> void abi(.c) = xx objc_msgSend;
    msg_oo  : (*void, *void, *void)        -> void abi(.c) = xx objc_msgSend;
    msg_ooo : (*void, *void, *void)        -> *void abi(.c) = xx objc_msgSend;

    // Modern iOS path: get the connected windowScene, then construct the
    // window via initWithWindowScene: so UIKit auto-sizes it and attaches
    // it to the display in one step.
    scenes := msg_o(app, sel_connected_scenes);
    scene  := msg_o(scenes, sel_any_object);
    if scene == xx 0 { NSLog(xx "[sx] scene NULL\n"); return 1; }
    NSLog(xx "[sx] scene: ok\n");

    win_raw := msg_o(UIWindow, sel_alloc);
    g_window = msg_ooo(win_raw, sel_init_with_scene, scene);
    NSLog(xx "[sx] window: ok\n");

    vc_raw := msg_o(UIViewController, sel_alloc);
    vc     := msg_o(vc_raw, sel_init);
    msg_oo(g_window, sel_set_root_vc, vc);

    blue := msg_o(UIColor, sel_system_blue);
    view := msg_o(vc, sel_view);
    msg_oo(view, sel_set_bg, blue);
    msg_oo(g_window, sel_set_bg, blue);

    msg_v(g_window, sel_make_key_visible);
    NSLog(xx "[sx] makeKeyAndVisible done\n");
    return 1;
}

main :: () -> i32 {
    UIResponder := objc_getClass("UIResponder".ptr);
    SxAppDelegate := objc_allocateClassPair(UIResponder, "SxAppDelegate".ptr, 0);

    class_addMethod(SxAppDelegate,
        sel_registerName("application:didFinishLaunchingWithOptions:".ptr),
        xx did_finish_launching, "c@:@@".ptr);
    class_addMethod(SxAppDelegate,
        sel_registerName("window".ptr),
        xx window_getter, "@@:".ptr);
    class_addMethod(SxAppDelegate,
        sel_registerName("setWindow:".ptr),
        xx window_setter, "v@:@".ptr);

    objc_registerClassPair(SxAppDelegate);
    return UIApplicationMain(0, xx 0, xx 0, xx "SxAppDelegate");
}
