Gate = {}

FFI.cdef[[
	struct Gate {
		int objref;
		int definition_objref;
		bool in_queue;
		struct Port ports[1];
	};
]]

function Gate.new(self, objref, definition)
	local o = {
		objref = objref,
		definition = definition,
		ports = {},
		in_queue = false,
		logic = definition.logic,
	}
	setmetatable(o, self)
	self.__index = self
	return o
end

function Gate.addport(self, port)
	self.ports[#self.ports+1] = port
	Port.setgate(port, self)
end

function Gate.getportstate(gate, index)
	return gate.ports[index].group.state
end

function Gate.setportstate(self, index, state)
	Port.setstate(self.ports[index], state)
end

function Gate.initdata(self)
	self.data = {}
end

function Gate.getdata(self)
	return self.data
end

function Gate.getportisrising(self, index)
	return Port.isrising(self.ports[index])
end

function Gate.getportisfalling(self, index)
	return Port.isfalling(self.ports[index])
end

function Gate.cb(gate, ...)
	Simulation.queuecallback(GSim, gate, ...)
end

function Gate.queue(gate, delay)
	Simulation.queuegatelater(GSim, gate, delay)
end

function Gate.gettick(gate)
	return GSim.currenttick
end

function Gate.getdefinition(gate)
	return gate.definition
end

-- Logic functions

function Gate.init(gate)
	Gate.getdefinition(gate).init(gate)
end

function Gate.logic(gate)
	gate.logic(gate)
end

function Gate.input(gate, argv)
	Gate.getdefinition(gate).input(gate, argv)
end