
local function getBit(gate, val)
	local gatedata = Gate.getdata(gate)
	
	if gatedata.listenState=="wait" then
		if val==1 then
			gatedata.listenState = "getbits"
			gatedata.bitsReceived = 0
		end
	elseif gatedata.listenState=="getbits" then
		gatedata.valReceived = gatedata.valReceived + math.pow(2, textbrick2_bitsNeeded-1-gatedata.bitsReceived)*val
		gatedata.bitsReceived = gatedata.bitsReceived+1
		
		if gatedata.bitsReceived==textbrick2_bitsNeeded then
			gatedata.listenState = "terminate"
		end
	elseif gatedata.listenState=="terminate" then
		if val==1 then
			local v = gatedata.valReceived
			local iscolor = math.floor(v/256)==1 -- first bit
			if iscolor then
				local printdomain = (math.floor(v/128)%2)==1 and "terminal" or "terminalInv" -- 8th lowest bit
				local colorid = v % 64 -- last 6 bits
				gatedata.printdomain = printdomain
				gatedata.colorid = colorid
			else
				local printid     = v % 256 -- last 8 bits
				local printname   = textbrick2_idxToPrint[printid] or "space"
				gatedata.printname = printname
			end
			Gate.cb(gate, (gatedata.colorid or -1).." "..(gatedata.printdomain or "terminal").." "..(gatedata.printname or "_"))
		end
		
		gatedata.listenState = "wait"
		
		gatedata.bitsReceived = 0
		gatedata.valReceived = 0
	end
end

local function changeTo(gate, val)
	local gatedata = Gate.getdata(gate)
	
	local tick = Gate.gettick(gate)
	local ticks = tick-gatedata.lastTickChanged
	
	local bits = math.min(ticks, textbrick2_bitsNeeded+3)
	for i = 1, bits do
		getBit(gate, val)
	end
	
	gatedata.lastTickChanged = tick
end

return function(gate)
	if Gate.getportisrising(gate, 1) then
		changeTo(gate, 0)
	elseif Gate.getportisfalling(gate, 1) then
		changeTo(gate, 1)
	end
end
