-- 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 DESCENT CONTROL
-- Surface elevator puzzle for ComputerCraft / CC:Tweaked
-- Save as: startup
--
-- Import:
-- pastebin get PASTE_CODE startup
-- reboot
--
-- Redstone output side can be changed below.

local OUTPUT_SIDE = "back"
local STATE_FILE = ".titan_elevator_armed"

local function color(c)
  if term.isColor and term.isColor() then
    term.setTextColor(c)
  end
end

local function resetScreen()
  term.setBackgroundColor(colors.black)
  term.clear()
  term.setCursorPos(1, 1)
end

local function line(text, c)
  color(c or colors.white)
  print(text)
end

local function prompt()
  color(colors.gray)
  print("")
  write("> ")
  color(colors.white)
  return string.lower(read() or "")
end

local function wait()
  color(colors.gray)
  print("")
  print("[ press any key ]")
  os.pullEvent("key")
end

local function header(sub)
  resetScreen()
  color(colors.lightBlue)
  print("[ TITAN DESCENT CONTROL ]")
  color(colors.gray)
  print("SURFACE ELEVATOR NODE")
  print("---------------------------------------")
  if sub then
    color(colors.white)
    print(sub)
    color(colors.gray)
    print("---------------------------------------")
  end
  color(colors.white)
end

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

local function saveArmed()
  local f = fs.open(STATE_FILE, "w")
  f.write("DESCENT DRIVE COUPLED")
  f.close()
end

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

local function bootOutput()
  if armed() then
    setOutput(true)
  else
    setOutput(false)
  end
end

local function diagnostics()
  header("DIAGNOSTIC CACHE")

  line("MOTOR LINE", colors.orange)
  line("Status: open circuit")
  line("Socket reports empty teeth.")
  line("A gearbox was removed or never arrived.")
  line("")

  line("BRAKE", colors.orange)
  line("Status: holding")
  line("Manual release rejected.")
  line("It wants the phrase logged after G-12.")
  line("")

  line("GREEN ROUTE", colors.orange)
  line("Status: surface-valid")
  line("The shaft will accept GREEN from here.")
  line("Lower routes are locked behind internal clearance.")
  line("")

  line("ALBEDO OVERRIDE", colors.cyan)
  line("Status: listening")
  line("No voice challenge detected.")
  line("No mercy routine detected either.")

  wait()
end

local function incident()
  header("INCIDENT G-12")

  line("The cage returned at 03:18.")
  line("")
  line("Nobody called it.")
  line("Nobody stepped out.")
  line("")
  line("The floor was clean.")
  line("The ceiling was wet.")
  line("")
  line("One staff badge lay inside the drain channel.")
  line("Its owner was found on the upper landing,")
  line("alive, seated, and missing eight minutes.")
  line("")
  line("Brake phrase changed by order of Security.")
  line("")
  line("Old phrase discarded.")
  line("New phrase copied from the damage report.")

  wait()
end

local function routeMemo()
  header("ROUTE MEMO")

  line("Surface authorization is restricted.")
  line("")
  line("Permitted route:")
  line("GREEN")
  line("")
  line("Do not request RED from the surface node.")
  line("")
  line("RED is not a direction.")
  line("It is a decision made elsewhere.")
  line("")
  color(colors.cyan)
  print("ALBEDO:")
  color(colors.white)
  print("\"You keep naming doors after colors.\"")
  print("\"That was adorable until the first flood.\"")

  wait()
end

local function albedoHint()
  header("ALBEDO OVERRIDE")

  line("The override accepts one plain word.")
  line("")
  line("Rejected attempts found in staff logs:")
  line("TITAN")
  line("NEMESIS")
  line("CROWNWATCH")
  line("")
  line("All three were vanity.")
  line("")
  color(colors.cyan)
  print("ALBEDO note:")
  color(colors.white)
  print("\"I am not the tower.\"")
  print("\"I am not the weapon above it.\"")
  print("\"I am what remained online after both failed.\"")
  print("")
  line("Accepted word: AWAKE", colors.gray)

  wait()
end

local function repairNotes()
  header("REPAIR NOTES")

  line("Drive socket requires a gearbox on axis Z")
  line("when shaft alignment runs north/south.")
  line("")
  line("Current surface target:")
  color(colors.lime)
  print("-454 166 -146")
  color(colors.white)
  print("")
  line("If rotation is wrong, place one manually.")
  line("Then inspect it with:")
  color(colors.gray)
  print("/data get block -454 166 -146")
  color(colors.white)
  print("")
  line("Use the returned blockstate in the command.")
  line("Do not trust your eyes near this shaft.")

  wait()
end

local function verifyAnswer(label, expected, failText)
  color(colors.white)
  print(label)
  local answer = prompt()

  if answer == expected then
    line("Accepted.", colors.lime)
    sleep(0.7)
    return true
  end

  line(failText, colors.red)
  sleep(1.2)
  return false
end

local function unlockSequence()
  header("REAUTHORIZATION")

  line("Four locks remain in sequence.")
  line("")
  line("All answers exist in local files.")
  line("The system is not testing intelligence.")
  line("It is checking whether you read before touching machinery.")
  line("")
  wait()

  header("CHECK 1 / MOTOR")
  line("The drive socket is missing a component.")
  line("Enter the replacement part.")
  print("")
  if not verifyAnswer("Component:", "gearbox", "Incorrect. The motor line stays open.") then return end

  header("CHECK 2 / BRAKE")
  line("Incident G-12 changed the brake phrase.")
  line("Enter the recovered condition.")
  print("")
  if not verifyAnswer("Condition:", "ceiling wet", "Brake refuses release.") then return end

  header("CHECK 3 / ROUTE")
  line("Surface control may authorize one route.")
  line("Enter the route name.")
  print("")
  if not verifyAnswer("Route:", "green", "Route denied at surface clearance.") then return end

  header("CHECK 4 / ALBEDO")
  line("Albedo requires an identity state.")
  line("Enter the accepted word.")
  print("")
  if not verifyAnswer("Word:", "awake", "Albedo does not answer.") then return end

  header("COUPLING DRIVE")
  color(colors.cyan)
  print("ALBEDO:")
  color(colors.white)
  print("\"There it is.\"")
  print("")
  print("\"A missing gear, a wet ceiling,")
  print("a permitted route, and one word you did not earn.\"")
  print("")
  print("\"Stand clear of the teeth.\"")
  print("")
  sleep(2)

  header("DESCENT DRIVE")
  line("Motor line: authorized", colors.lime)
  line("Surface brake: released", colors.lime)
  line("Route: GREEN", colors.lime)
  line("Coupling signal: active", colors.lime)
  print("")
  line("Output side: " .. OUTPUT_SIDE, colors.gray)

  saveArmed()
  setOutput(true)

  wait()
end

local function lockedStatus()
  header("SYSTEM STATUS")

  if armed() then
    line("DESCENT DRIVE: COUPLED", colors.lime)
    line("")
    line("Redstone output is active.")
    line("If the wiring is correct, the gearbox")
    line("should now be placed or receiving power.")
    line("")
    color(colors.cyan)
    print("ALBEDO:")
    color(colors.white)
    print("\"The shaft is open.\"")
    print("\"That is not the same as safe.\"")
  else
    line("DESCENT DRIVE: DISCONNECTED", colors.orange)
    line("")
    line("The elevator cannot descend.")
    line("Run reauthorization.")
  end

  wait()
end

bootOutput()

while true do
  header()

  if armed() then
    line("DESCENT DRIVE: COUPLED", colors.lime)
  else
    line("DESCENT DRIVE: DISCONNECTED", colors.orange)
  end

  line("")
  line("1. System status")
  line("2. Diagnostic cache")
  line("3. Incident G-12")
  line("4. Route memo")
  line("5. Albedo override hint")
  line("6. Repair notes")
  line("7. Run reauthorization")
  line("8. Reset output / debug")
  line("")
  line("Q. Close")

  local input = prompt()

  if input == "q" or input == "quit" or input == "exit" then
    resetScreen()
    line("SESSION CLOSED", colors.gray)
    return
  elseif input == "1" then
    lockedStatus()
  elseif input == "2" then
    diagnostics()
  elseif input == "3" then
    incident()
  elseif input == "4" then
    routeMemo()
  elseif input == "5" then
    albedoHint()
  elseif input == "6" then
    repairNotes()
  elseif input == "7" then
    if armed() then
      header("ALREADY COUPLED")
      line("The descent drive is already active.", colors.lime)
      wait()
    else
      unlockSequence()
    end
  elseif input == "8" then
    header("DEBUG")
    line("Type RESET to clear saved state.")
    line("Type OFF to drop redstone only.")
    line("Type ON to force redstone only.")
    local d = prompt()

    if d == "reset" then
      if fs.exists(STATE_FILE) then fs.delete(STATE_FILE) end
      setOutput(false)
      line("State cleared.", colors.orange)
      sleep(1)
    elseif d == "off" then
      setOutput(false)
      line("Output off.", colors.orange)
      sleep(1)
    elseif d == "on" then
      setOutput(true)
      line("Output on.", colors.lime)
      sleep(1)
    else
      line("No change.", colors.gray)
      sleep(1)
    end
  else
    line("Invalid.", colors.red)
    sleep(0.7)
  end
end