-- FF_STORY_COMPUTER_GUARD
local function ff_story_computer_allowed()
  local label = os.getComputerLabel and os.getComputerLabel() or nil
  return fs.exists(".ff_story_computer")
    or fs.exists(".ff_titan_computer")
    or fs.exists(".ff_titan_program_id")
    or fs.exists(".ff_titan_allow_autoinstall")
    or fs.exists(".ff_titan_allow_autorun")
    or (label ~= nil and string.sub(string.lower(label), 1, 9) == "ff_titan:")
end

if not ff_story_computer_allowed() then
  return
end
-- TITAN GREEN SECTOR
-- LOWER HULL ACCESS BOARD
-- Save as: startup
--
-- Attach monitor if possible.
--
-- Inputs:
-- left   = pressure override
-- right  = quarantine release
-- back   = black clearance
-- top    = Albedo authorization or manual route lever
--
-- Output:
-- bottom = lower gate / iris door / command block

local PRESSURE_SIDE = "left"
local QUARANTINE_SIDE = "right"
local SECURITY_SIDE = "back"
local ALBEDO_SIDE = "top"
local OUTPUT_SIDE = "bottom"

local STATE_FILE = ".green_lower_access_open"
local FINAL_WORD = "DESCEND"

local function findMonitor()
  local mon = peripheral.find("monitor")
  if mon then
    mon.setTextScale(0.5)
    return mon
  end
  return nil
end

local monitor = findMonitor()

local function useTerminal()
  term.redirect(term.native and term.native() or term.current())
end

local function useMonitor()
  if monitor then term.redirect(monitor) end
end

local function hasColor()
  return term.isColor and term.isColor()
end

local function c(col)
  if hasColor() then term.setTextColor(col) end
end

local function bg(col)
  if hasColor() then term.setBackgroundColor(col) end
end

local function cls()
  bg(colors.black)
  term.clear()
  term.setCursorPos(1, 1)
end

local function writeLine(text, col)
  c(col or colors.white)
  print(text)
end

local function at(x, y, text, col)
  term.setCursorPos(x, y)
  c(col or colors.white)
  write(text)
end

local function center(y, text, col)
  local w = term.getSize()
  local x = math.floor((w - #text) / 2) + 1
  if x < 1 then x = 1 end
  at(x, y, text, col)
end

local function hline(y, col)
  local w = term.getSize()
  at(1, y, string.rep("-", w), col or colors.gray)
end

local function readClean()
  c(colors.white)
  write("> ")
  local s = read() or ""
  s = string.upper(s)
  s = string.gsub(s, "^%s+", "")
  s = string.gsub(s, "%s+$", "")
  return s
end

local function pause()
  c(colors.gray)
  print("")
  print("[key] back")
  os.pullEvent("key")
end

local function opened()
  return fs.exists(STATE_FILE)
end

local function saveOpened()
  local f = fs.open(STATE_FILE, "w")
  f.write("LOWER ACCESS OPEN")
  f.close()
end

local function setOutput(on)
  redstone.setOutput(OUTPUT_SIDE, on)
end

local function bootOutput()
  setOutput(opened())
end

local function pressureOK()
  return redstone.getInput(PRESSURE_SIDE)
end

local function quarantineOK()
  return redstone.getInput(QUARANTINE_SIDE)
end

local function securityOK()
  return redstone.getInput(SECURITY_SIDE)
end

local function albedoOK()
  return redstone.getInput(ALBEDO_SIDE)
end

local function allOK()
  return pressureOK() and quarantineOK() and securityOK() and albedoOK()
end

local function mark(ok)
  if ok then
    c(colors.lime)
    return "[X]"
  end
  c(colors.red)
  return "[ ]"
end

local function drawMonitor()
  if not monitor then return end

  useMonitor()
  cls()

  local w, h = term.getSize()

  center(1, "LOWER HULL ACCESS", colors.red)
  center(2, "TITAN GREEN SECTOR / ROUTE BOARD", colors.gray)
  hline(3, colors.red)

  at(2, 5, "BLACKSITE LOCKDOWN", colors.red)
  at(2, 6, "Remaining staff pathing invalid.", colors.gray)

  at(2, 8, "FACILITY INTEGRITY", colors.gray)
  at(28, 8, "78%", colors.white)

  at(2, 9, "EXTERNAL PRESSURE", colors.gray)
  at(28, 9, "240 o", colors.white)

  at(2, 10, "CONTAINMENT", colors.gray)
  at(28, 10, "RAGNAROK", colors.red)

  at(2, 11, "LOWER ROUTE", colors.gray)
  if opened() then
    at(28, 11, "OPEN", colors.lime)
  else
    at(28, 11, "SEALED", colors.red)
  end

  at(2, 13, "ACCESS REQUIREMENTS", colors.white)

  at(4, 15, "PRESSURE OVERRIDE", colors.white)
  at(31, 15, pressureOK() and "[X]" or "[ ]", pressureOK() and colors.lime or colors.red)

  at(4, 16, "QUARANTINE RELEASE", colors.white)
  at(31, 16, quarantineOK() and "[X]" or "[ ]", quarantineOK() and colors.lime or colors.red)

  at(4, 17, "BLACK CLEARANCE", colors.white)
  at(31, 17, securityOK() and "[X]" or "[ ]", securityOK() and colors.lime or colors.red)

  at(4, 18, "ALBEDO AUTHORIZATION", colors.white)
  at(31, 18, albedoOK() and "[X]" or "[ ]", albedoOK() and colors.lime or colors.red)

  at(2, 20, "LOCAL ROUTE NOTES", colors.orange)

  if opened() then
    at(4, 22, "Gate output is active.", colors.lime)
    at(4, 23, "Proceed to lower elevator contact.", colors.white)
  elseif allOK() then
    at(4, 22, "All inputs present.", colors.lime)
    at(4, 23, "Use terminal and enter final word.", colors.white)
  else
    at(4, 22, "Input chain incomplete.", colors.red)
    at(4, 23, "Check wing terminals.", colors.white)
  end

  if w > 58 then
    at(48, 5, "CONTAINMENT LOG", colors.red)
    at(48, 7, "13:22 pressure board accessed", colors.white)
    at(48, 8, "13:31 sample freezer ping", colors.orange)
    at(48, 9, "13:37 black card request denied", colors.white)
    at(48, 10, "13:41 lower bell heard once", colors.red)
    at(48, 11, "13:48 red route map hidden", colors.red)
    at(48, 12, "13:52 admin gate not responding", colors.orange)
    at(48, 13, "13:58 elevator contact absent", colors.red)
    at(48, 14, "14:02 local route board waiting", colors.white)

    at(48, 17, "ROUTE COMMAND", colors.gray)
    at(48, 18, "Final word stored locally.", colors.white)
    at(48, 19, "No database link present.", colors.white)
    at(48, 20, "No live reply expected.", colors.orange)

    at(48, 23, "If this monitor speaks, unplug it.", colors.red)
  end

  hline(h, colors.red)
end

local function terminalHeader(title)
  useTerminal()
  cls()
  c(colors.red)
  print("LOWER HULL ACCESS")
  c(colors.gray)
  print("GREEN ROUTE BOARD")
  print("---------------------------------------")
  if title then
    c(colors.white)
    print(title)
    c(colors.gray)
    print("---------------------------------------")
  end
  c(colors.white)
end

local function status()
  terminalHeader("STATUS")

  if opened() then
    writeLine("LOWER ROUTE: OPEN", colors.lime)
  else
    writeLine("LOWER ROUTE: SEALED", colors.red)
  end

  print("")
  writeLine("Pressure override:    " .. (pressureOK() and "OK" or "MISSING"), pressureOK() and colors.lime or colors.red)
  writeLine("Quarantine release:   " .. (quarantineOK() and "OK" or "MISSING"), quarantineOK() and colors.lime or colors.red)
  writeLine("Black clearance:      " .. (securityOK() and "OK" or "MISSING"), securityOK() and colors.lime or colors.red)
  writeLine("Albedo authorization: " .. (albedoOK() and "OK" or "MISSING"), albedoOK() and colors.lime or colors.red)

  print("")

  if allOK() and not opened() then
    writeLine("All inputs present.", colors.lime)
    writeLine("Run OPEN.")
  elseif not opened() then
    writeLine("Wing work incomplete.", colors.orange)
  else
    writeLine("Output is held ON.", colors.lime)
  end

  pause()
end

local function localFile()
  terminalHeader("LOCAL FILE")

  writeLine("LOWER HULL ROUTE")
  print("")
  writeLine("This board is not on the main database.")
  writeLine("It reads local wing outputs only.")
  print("")
  writeLine("If a wing terminal is solved,")
  writeLine("its redstone line should stay active.")
  print("")
  writeLine("Final word is written on the paper")
  writeLine("inside the reception drawer.")
  print("")
  writeLine("DESCEND", colors.lime)

  pause()
end

local function elevatorNote()
  terminalHeader("ELEVATOR NOTE")

  writeLine("After lower route opens:")
  print("")
  writeLine("Use the elevator control.")
  print("")
  writeLine("MIDDLE MOUSE BUTTON", colors.cyan)
  writeLine("or SCROLL WHEEL", colors.cyan)
  writeLine("selects the floor.", colors.cyan)
  print("")
  writeLine("RIGHT CLICK", colors.cyan)
  writeLine("confirms the selected floor.", colors.cyan)
  print("")
  writeLine("If red floor does not appear,")
  writeLine("the lower elevator contact is missing.")
  print("")
  writeLine("Signal should place or enable it.")

  pause()
end

local function openRoute()
  if opened() then
    terminalHeader("OPEN")
    writeLine("Route already open.", colors.lime)
    pause()
    return
  end

  terminalHeader("OPEN")

  if not allOK() then
    writeLine("Route denied.", colors.red)
    print("")
    writeLine("Missing input:")
    if not pressureOK() then writeLine("PRESSURE", colors.red) end
    if not quarantineOK() then writeLine("QUARANTINE", colors.red) end
    if not securityOK() then writeLine("BLACK CLEARANCE", colors.red) end
    if not albedoOK() then writeLine("ALBEDO", colors.red) end
    pause()
    return
  end

  writeLine("All inputs present.", colors.lime)
  print("")
  writeLine("Enter final word.")
  print("")

  local got = readClean()

  if got ~= FINAL_WORD then
    c(colors.red)
    print("")
    print("INCORRECT")
    sleep(0.8)

    terminalHeader("DENIED")
    writeLine("Input:", colors.gray)
    writeLine(got)
    print("")
    writeLine("Result:", colors.gray)
    writeLine("WRONG", colors.red)
    print("")
    writeLine("Check the local file.")
    pause()
    return
  end

  c(colors.lime)
  print("")
  print("CORRECT")
  sleep(0.8)

  saveOpened()
  setOutput(true)

  terminalHeader("ROUTE OPEN")
  writeLine("LOWER HULL ROUTE AUTHORIZED", colors.lime)
  print("")
  writeLine("Output is now held ON.")
  print("")
  writeLine("Use this output for:")
  writeLine("iris door relay")
  writeLine("red elevator contact")
  writeLine("lower access lights")
  print("")
  writeLine("Recommended command block:")
  c(colors.gray)
  print("setblock -454 74 -133")
  print("create:elevator_contact[facing=north]")
  pause()
end

bootOutput()

while true do
  drawMonitor()

  useTerminal()
  terminalHeader()

  if opened() then
    writeLine("LOWER ROUTE: OPEN", colors.lime)
  else
    writeLine("LOWER ROUTE: SEALED", colors.red)
  end

  print("")
  writeLine("1. Status")
  writeLine("2. Local file")
  writeLine("3. Elevator note")
  writeLine("O. OPEN")
  writeLine("Q. Close")
  print("")

  local input = readClean()

  if input == "Q" or input == "QUIT" or input == "EXIT" then
    cls()
    writeLine("SESSION CLOSED", colors.gray)
    return
  elseif input == "1" then
    status()
  elseif input == "2" then
    localFile()
  elseif input == "3" then
    elevatorNote()
  elseif input == "O" or input == "OPEN" then
    openRoute()
  else
    c(colors.red)
    print("Invalid.")
    sleep(0.7)
  end
end