local reactors={"nuclear_reactor_0","back","nuclear_reactor_1"}
local monitors={{"monitor_7"},{"monitor_10"},{"monitor_9"}}
local mainmon={"monitor_8"}
local mfseInput="front"
local mainOutput="back"

print("Wojbie's nuclear control active")
--nuclear_reactor_0
--Globals

local lockdown=false
local status="Debug"
local heat=0
local rods={
["empty"]={name="Empty",active=false,size=1},

--Uranium
	--Active
[30207]={name="Uranium",active=true,size=10000},
[30102]={name="Uran-2",active=true,size=10000},
[30101]={name="Uran-4",active=true,size=10000},
	--Depleted
[30053]={name="Uran-D",active=false,size=1},
[30055]={name="Uran2-D",active=false,size=1},
[30054]={name="Uran4-D",active=false,size=1},

--MOX
	--Active
[30059]={name="MOX",active=true,size=5000},
[30061]={name="MOX-2",active=true,size=5000},
[30060]={name="MOX-4",active=true,size=5000},
	--Depleted
[30056]={name="MOX-D",active=false,size=1},
[30058]={name="MOX2-D",active=false,size=1},
[30057]={name="MOX4-D",active=false,size=1},
}

local function stamp(A)
local logo
if turtle then
logo="__          __     _  _      _       \n\\ \\        / /    (_)| |    (_)      \n \\ \\  /\\  / /___   _ | |__   _   ___ \n  \\ \\/  \\/ // _ \\ | || '_ \\ | | / _ \\\n   \\  /\\  /| (_) || || |_) || ||  __/\n    \\/  \\/  \\___/ | ||_.__/ |_| \\___|\n                 _/ |                \n                |__/                 "
else
logo=" __      __                __                      \n/\\ \\  __/\\ \\           __ /\\ \\       __            \n\\ \\ \\/\\ \\ \\ \\    ___  /\\_\\\\ \\ \\____ /\\_\\      __   \n \\ \\ \\ \\ \\ \\ \\  / __'\\\\/\\ \\\\ \\ '__'\\\\/\\ \\   /'__'\\ \n  \\ \\ \\_/ \\_\\ \\/\\ \\L\\ \\\\ \\ \\\\ \\ \\L\\ \\\\ \\ \\ /\\  __/ \n   \\ '\\___x___/\\ \\____/_\\ \\ \\\\ \\_,__/ \\ \\_\\\\ \\____\\\n    '\\/__//__/  \\/___//\\ \\_\\ \\\\/___/   \\/_/ \\/____/\n                      \\ \\____/                     \n                       \\/___/                      "
end
	local _, cy = term.getCursorPos()
	term.setCursorPos(1,type(A)=="number" and A or cy)
	print(logo)
end

stamp()
if turtle then print("I am not supposed to be run on turtle") end

local manymeta={
["__index"]=function (tab, key)

	return function(...)
		local ret
		local tArgs={...}
		for i,k in ipairs(tab) do
			if k[key] then ret={k[key](unpack(tArgs))} end
			if #ret>0 then break end
		end
		return unpack(ret)
	end

end,
["__call"]=function (tab, ...)
	local ret={}
	local tArgs={...}
	if #tArgs==0 then return end
	local key=table.remove(tArgs,1)
	for i,k in ipairs(tab) do
		if k[key] then ret[i]={k[key](unpack(tArgs))} end
	end
	return ret
end

}

local function wrapAll()

for i,k in ipairs(reactors) do
	reactors[i]= peripheral.wrap(k)
	if not reactors[i] then error("Wrong reactor side "..tostring(k)) end
	if monitors[i] then
		for j,l in ipairs(monitors[i]) do
			monitors[i][j]=peripheral.wrap(l)
			if not monitors[i][j] then error("Wrong monitor side "..tostring(k)) end
		end
		setmetatable(monitors[i],manymeta)
		monitors[i].write(i)
	end
end
setmetatable(reactors,manymeta)
for i,k in ipairs(mainmon) do
	mainmon[i]= peripheral.wrap(k)
	if not mainmon[i] then error("Wrong Main Monitor side "..tostring(k)) end
end
setmetatable(mainmon,manymeta)
if not mainmon.isColor() then error("Main Monitor nneds to be Advanced") end

end

local function cwrite(A,B,C)
	if not C then C=term end
    local w, h = C.getSize()
	local _, cy = C.getCursorPos()
    C.setCursorPos(math.floor(w / 2 - #A / 2 + 1.5),type(B)=="number" and B or cy)
    C.write(A)
end

local function timeleft(A)
    local sec=A%60
    A=A-sec
    local min=A%3600
    A=A-min
    min=min/60
    local hours=A/3600
	return string.format("%01d:%02d:%02d",hours,min,sec)
end

wrapAll()

local function visuals()
	while true do
		local total=0
		for i,k in ipairs(reactors) do
			local curRod=1
			local curExt=rods["empty"]
			for l=13,18 do
				local temp=k.getStackInSlot(l)
				if temp and temp.id and rods[temp.id] then
					curRod=temp.dmg
					curExt=rods[temp.id]
					break
				end
			end
			monitors[i].clear()
			local visheat=k.getHeat()/k.getMaxHeat()*100
			cwrite(tostring(math.floor(visheat*100)/100).."%",1,monitors[i])
			cwrite(visheat>80 and "Heat!" or ( curExt.active and "Stable" or "Offline"),2,monitors[i])
			cwrite(curExt.name,3,monitors[i])
			local left=curExt.active and 0-(curRod-curExt.size) or 0
			cwrite(tostring(left/curExt.size*100).."%",4,monitors[i])
			cwrite(timeleft(left),5,monitors[i])
			total=left>total and left or total
		end
		mainmon.clear()
		cwrite(tostring(math.floor(heat*100)/100).."%",1,mainmon)
		cwrite(status,3,mainmon)
		cwrite(timeleft(total),5,mainmon)
		sleep(1)
	end
end

local function controler()
	local timer=os.startTimer(1)
	local event
	while true do
		event={os.pullEvent()}
		if event[1]=="timer" and event[2]==timer then
			timer=os.startTimer(1)
			--if redstone.getInput(mainOutput) and not redstone.getOutput(mainOutput) then redstone.setOutput(mainOutput,false) status="Manual"
			if lockdown then redstone.setOutput(mainOutput,false) operating=false status="!SCRAM!"
			else 
				local heats=reactors("getHeat")
				local maxs=reactors("getMaxHeat")
				heat=0
				for i,k in ipairs(heats) do
					local curHeat=k[1]/maxs[i][1]*100
					heat = curHeat>heat and curHeat or heat
				end
				if heat>80 then redstone.setOutput(mainOutput,false) status="Heat!"
				else
					if redstone.getInput(mfseInput) then redstone.setOutput(mainOutput,false) status="Pause"
					else redstone.setOutput(mainOutput,true) status="Working" end
				end
			end
		elseif event[1]=="monitor_touch" then lockdown=(not lockdown) redstone.setOutput(mainOutput,false)
		elseif event[1]=="terminate" then status="Offline" lockdown=true redstone.setOutput(mainOutput,false) print("Cooling Down Reactors") sleep(2) break
		end
	end
end

--Non-termination point
local oldpullEvent=os.pullEvent
os.pullEvent=os.pullEventRaw

local ok, param = pcall( function()
parallel.waitForAny(visuals,controler) --working
--visuals()
end )

print("Emergency Stop") 
redstone.setOutput(mainOutput,false)
print("Emergency Stop Confirmed - Terminating") 

if not ok then
	printError( param )
end

--Restoring normal termination
os.pullEvent=oldpullEvent
