const coral = @import("coral");

const std = @import("std");

const ona = @import("ona");

const Actors = struct {
	instances: coral.stack.Sequential(ona.gfx.Point2D) = .{.allocator = coral.heap.allocator},
	quad_mesh_2d: ona.gfx.Handle = .none,
	body_texture: ona.gfx.Handle = .none,
};

const Player = struct {
	move_x: ona.act.Axis = .{.keys = .{.a, .d}},
	move_y: ona.act.Axis = .{.keys = .{.w, .s}},
};

pub fn main() !void {
	try ona.start_app(setup, .{
		.tick_rate = 60,
		.execution = .{.thread_share = 0.1},
	});
}

fn load(display: coral.Write(ona.gfx.Display), actors: coral.Write(Actors), assets: coral.Write(ona.gfx.Assets)) !void {
	display.res.width, display.res.height = .{1280, 720};
	actors.res.body_texture = try assets.res.open_file("actor.bmp");
	actors.res.quad_mesh_2d = try assets.res.open_quad_mesh_2d(@splat(1));

	try actors.res.instances.push_grow(.{0, 0});
}

fn exit(actors: coral.Write(Actors)) void {
	actors.res.instances.deinit();
}

fn render(queue: ona.gfx.Queue, actors: coral.Write(Actors)) !void {
	for (actors.res.instances.values) |instance| {
		try queue.commands.append(.{
			.instance_2d = .{
				.mesh_2d = actors.res.quad_mesh_2d,
				.texture = actors.res.body_texture,

				.transform = .{
					.origin = instance,
					.xbasis = .{64, 0},
					.ybasis = .{0, 64},
				},
			},
		});
	}
}

fn update(player: coral.Read(Player), actors: coral.Write(Actors), mapping: coral.Read(ona.act.Mapping)) !void {
	actors.res.instances.values[0] += .{
		mapping.res.axis_strength(player.res.move_x),
		mapping.res.axis_strength(player.res.move_y),
	};
}

fn setup(world: *coral.World, events: ona.App.Events) !void {
	try world.set_resource(.none, Actors{});
	try world.set_resource(.none, Player{});

	try world.on_event(events.load, coral.system_fn(load), .{.label = "load"});
	try world.on_event(events.update, coral.system_fn(update), .{.label = "update"});
	try world.on_event(events.exit, coral.system_fn(exit), .{.label = "exit"});
	try world.on_event(events.render, coral.system_fn(render), .{.label = "render actors"});
}