void sim_init(int num_gates, int num_nets);
void sim_add_gate(int gateid, int logic_func_id, char* logic_func_name, int num_out_ports, char* data);
void sim_add_net(int netid, int num_gates_update);
void sim_connect_out_port(int gateid, int index, int netid);
void sim_connect_in_port(int gateid, int index, int netid);
void sim_tick(int count);
void sim_get_net_state(int netid);
void sim_get_port_state(int gateid, int index);
void sim_set_net_state(int netid);
void sim_set_port_state(int gateid, int index);
void sim_delete_net(int netid);
void sim_delete_gate(int gateid);

////////

void sim_create(unsigned int datalen, char* text);

#include <stdlib.h>
#include <assert.h>

typedef unsigned int uint;
typedef unsigned long long u64;

void sim_copy_logic_function(
	char** prog,
	char* in_queue,
	char* out_port_states,
	int logic_func,
	char** port_in_net_states,
	char** port_out_net_inqueue,
	char** port_out_net_update_func,
	int num_ports_in,
	int num_ports_out
) {
	// todo: indata = inport net state pointers, outport net in queue pointers, outport net update function pointers
}

void sim_compile_gate(char** prog, char** data, int** idat, u64* indata) {
	int num_ports_in  = *(indata++);
	int num_ports_out = *(indata++);
	int in_queue      = *(indata++);
	int logic_func    = *(indata++);
	
	char* port_in_net_states[256];
	sim_copy_logic_function( // copy logic function into program
		prog,
		*data,
		(*data)+1,
		logic_func,
		&indata,
		num_ports_in,
		num_ports_out
	);
	
	*(*data++) = in_queue; // alloc bool for in queue
	for(int i=0; i<num_ports_out; i++) { // alloc bool for each output state
		*((*data)++) = *(indata++);
	}
}

void sim_compile_net_function(char** prog, char* in_queue, int* gates, u64** indata, int num_gates_update) {
	
}

void sim_compile_net(char** prog, char** data, int** idat, u64* indata) {
	int num_gates_update = *(indata++);
	int num_ports_on     = *(indata++);
	int in_queue         = *(indata++);
	
	sim_compile_net_function(prog, *data, *idat, &indata, num_gates_update);
	
	*((*data)++) = in_queue;
	*((*idat)++) = num_ports_on;
}