-- 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 authorization terminal
-- Save as startup
--
-- Import:
-- pastebin get PASTE_CODE startup
-- reboot
--
-- Output:
-- redstone signal on OUTPUT_SIDE after puzzle completion

local OUTPUT_SIDE = "back"
local STATE_FILE = ".titan_surface_elevator_done"

local tokens = {
  "coupler",
  "mercy",
  "green",
  "awake"
}

local files = {
  {
    title = "MAINT / SHIFT 6",
    body = {
      "Daan pulled the drive part again.",
      "",
      "No request. No supervisor stamp.",
      "He left it on the intake desk.",
      "",
      "Mira asked what to call it.",
      "",
      "He wrote one word on tape:",
      "",
      "        COUPLER",
      "",
      "Then he locked Cage 7.",
      "",
      "No joke in chat after that."
    }
  },
  {
    title = "SECURITY / G-12",
    body = {
      "The cage came back empty.",
      "",
      "Wet prints crossed the ceiling.",
      "One badge lay under the grate.",
      "",
      "Badge owner still upstairs.",
      "Alive. Not helpful.",
      "",
      "Brake phrase replaced.",
      "",
      "Old phrase: DESCEND",
      "New phrase:",
      "",
      "        MERCY"
    }
  },
  {
    title = "ROUTE / SURFACE",
    body = {
      "Surface console lost lower access.",
      "",
      "That was intentional.",
      "",
      "The old map still shows three stops.",
      "The new map has one.",
      "",
      "Reception level only.",
      "Middle facility only.",
      "",
      "Printed on the relay tag:",
      "",
      "        GREEN"
    }
  },
  {
    title = "ALBEDO / LOCAL",
    body = {
      "Someone tried TITAN.",
      "Someone tried NEMESIS.",
      "Someone tried ADMIN.",
      "",
      "Albedo rejected all three.",
      "",
      "The accepted word was found in",
      "her own boot log.",
      "",
      "No greeting. No warning.",
      "",
      "Only:",
      "",
      "        AWAKE"
    }
  },
  {
    title = "NOTE / BRAM",
    body = {
      "Bram wrote this on paper.",
      "",
      "Paper. Actual paper.",
      "",
      "Said he wanted one thing here",
      "Albedo could not edit.",
      "",
      "\"If the lift starts by itself,",
      "don't run to the shaft.",
      "Run out.\"",
      "",
      "The note was folded inside",
      "an empty ration box."
    }
  }
}

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

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

local function header(title)
  clear()
  c(colors.lightBlue)
  print("[ TITAN DESCENT CONTROL ]")
  c(colors.gray)
  print("SURFACE LIFT NODE")
  print("---------------------------------------")
  if title then
    c(colors.white)
    print(title)
    c(colors.gray)
    print("---------------------------------------")
  end
  c(colors.white)
end

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

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

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

local function boot()
  output(armed())
end

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

local function drawLine(line)
  if line == "        COUPLER" or line == "        MERCY" or line == "        GREEN" or line == "        AWAKE" then
    c(colors.lime)
  elseif string.find(line, "Albedo") then
    c(colors.cyan)
  elseif string.find(line, "lower") or string.find(line, "ceiling") or string.find(line, "empty") then
    c(colors.orange)
  else
    c(colors.white)
  end

  print(line)
end

local function showFile(file)
  local index = 1
  local pageSize = 13

  while true do
    header(file.title)

    for i = index, math.min(index + pageSize - 1, #file.body) do
      drawLine(file.body[i])
    end

    c(colors.gray)
    print("")

    if index + pageSize <= #file.body then
      print("[key] next")
      os.pullEvent("key")
      index = index + pageSize
    else
      print("[key] back")
      os.pullEvent("key")
      return
    end
  end
end

local function readInput()
  c(colors.gray)
  write("> ")
  c(colors.white)
  return string.lower(read() or "")
end

local function status()
  header("STATUS")

  if armed() then
    c(colors.lime)
    print("DRIVE: COUPLED")
    c(colors.white)
    print("")
    print("Signal held on side:")
    c(colors.lime)
    print(OUTPUT_SIDE)
    c(colors.white)
    print("")
    print("If the redstone is wired,")
    print("the gearbox should be moving")
    print("or already seated.")
  else
    c(colors.orange)
    print("DRIVE: OPEN")
    c(colors.white)
    print("")
    print("Gearbox socket is empty.")
    print("Authorization file incomplete.")
    print("")
    print("Read local files.")
    print("Enter four tokens.")
  end

  waitKey()
end

local function authorize()
  if armed() then
    header("AUTHORIZATION")
    c(colors.lime)
    print("Already coupled.")
    waitKey()
    return
  end

  header("AUTHORIZATION")
  print("Enter four tokens.")
  print("")
  print("One word each.")
  print("No spaces.")
  print("")
  print("Token 1:")
  local a = readInput()

  print("")
  print("Token 2:")
  local b = readInput()

  print("")
  print("Token 3:")
  local d = readInput()

  print("")
  print("Token 4:")
  local e = readInput()

  if a == tokens[1] and b == tokens[2] and d == tokens[3] and e == tokens[4] then
    header("COUPLING")

    c(colors.white)
    print("Motor line accepted.")
    print("Brake phrase accepted.")
    print("Route accepted.")
    print("Local mind accepted.")
    print("")

    c(colors.cyan)
    print("ALBEDO:")
    c(colors.white)
    print("\"Fine.\"")
    print("")
    print("\"I am opening the nice door.\"")
    print("\"The rude door comes later.\"")

    writeState()
    output(true)

    waitKey()
  else
    header("AUTHORIZATION FAILED")

    c(colors.red)
    print("No coupling signal.")
    c(colors.white)
    print("")
    print("One or more tokens rejected.")
    print("")
    c(colors.cyan)
    print("ALBEDO:")
    c(colors.white)
    print("\"That was nearly typing.\"")

    waitKey()
  end
end

local function debug()
  header("DEBUG")
  print("RESET clears saved state.")
  print("ON forces signal.")
  print("OFF drops signal.")
  print("")
  local v = readInput()

  if v == "reset" then
    if fs.exists(STATE_FILE) then
      fs.delete(STATE_FILE)
    end
    output(false)
  elseif v == "on" then
    output(true)
  elseif v == "off" then
    output(false)
  end
end

boot()

while true do
  header()

  if armed() then
    c(colors.lime)
    print("DRIVE: COUPLED")
  else
    c(colors.orange)
    print("DRIVE: OPEN")
  end

  c(colors.white)
  print("")
  print("1. Status")
  print("2. MAINT / SHIFT 6")
  print("3. SECURITY / G-12")
  print("4. ROUTE / SURFACE")
  print("5. ALBEDO / LOCAL")
  print("6. NOTE / BRAM")
  print("7. Authorize drive")
  print("8. Debug")
  print("")
  c(colors.gray)
  print("Q. close")

  local input = readInput()

  if input == "q" or input == "quit" or input == "exit" then
    clear()
    c(colors.gray)
    print("SESSION CLOSED")
    return
  elseif input == "1" then
    status()
  elseif input == "2" then
    showFile(files[1])
  elseif input == "3" then
    showFile(files[2])
  elseif input == "4" then
    showFile(files[3])
  elseif input == "5" then
    showFile(files[4])
  elseif input == "6" then
    showFile(files[5])
  elseif input == "7" then
    authorize()
  elseif input == "8" then
    debug()
  else
    c(colors.red)
    print("Invalid.")
    sleep(0.6)
  end
end