local function comp_expert(pos)
   local spos = pos.x ..','.. pos.y ..','.. pos.z
   local meta = minetest.get_meta(pos)
   local start_pos = meta:get_string('start_pos') or ''
   local formspec =
      'formspec_version[6]'..
      'size[20,6]'..
      'position[.5,.8]'..
      'no_prepend[]'..
      'bgcolor[#00000000;false]'..
      'background[0,0;20,6;rob_opr_base_computer_gui.png]'..
      'scroll_container[.5,.5;12.5,3.5;queue;vertical;0.1]'..
      'list[nodemeta:'..spos..';queue;0,0;10,9]'..
      'scroll_container_end[]'..
      'scrollbaroptions[max=38]'..
      'scrollbar[12.75,.5;.25,3.5;vertical;queue;]'..
      'listcolors[#10101020;#257C4020]'..
      'list[detached:trash;main;13.25,2.875;1,1]'..
      'list[detached:program_cards;main;14.75,.5;4,2]'..
      'listring[detached:program_cards;main]'..
      'listring[nodemeta:'..spos..';queue]'..
      'listring[detached:trash;main]'..
      'textarea[3,4.25;14,1.5;;;Navigate the robot from the staring position to the end. Take control cards from the slots on the right, and place them in the queue. You can use the shift+click to move cards from the program stack to the queue, and from the queue to the trash. Good luck!]'..
      'button_exit[.5,4.5;2,1;;Exit]'..
      'button[17.5,4.5;2,1;start;Run]'
      return formspec
end

local function comp_configure(pos)
   local meta = minetest.get_meta(pos)
   local start_pos = meta:get_string('start_pos') or ''
   local formspec =
      'formspec_version[6]'..
      'size[20,6]'..
      'position[.5,.8]'..
      'no_prepend[]'..
      'bgcolor[#00000000;false]'..
      'background[0,;20,6;rob_opr_base_computer_gui.png]'..
      'textarea[.5,.5;19,2;;;Set the challenge configuration options here.]'..
      'field[.5,4.5;4,1;start_pos;Start Position;'..start_pos..']'..
      'button_exit[6.5,4.5;2,1;save;Save]'..
      'button_exit[17.5,4.5;2,1;;Discard]'
   return formspec
end

local computer_box = {
   type = 'fixed',
   fixed = {
      {-.375, -.625, .1875, .375, -.325, .5},
      {.1875, -1.5, .625, .3125, -.1875, .5}
   }
}

local computer_inspection = {
   '[It looks like this is used to control something, nuclear fusion maybe?]',
   '[This is just a touch fancier than my old Commodore 64.]',
   '[The real question here is can it run Doom?]',
   '[There doesn\'t appear to be any security that should prevent me from using this.]'
}

local computer_report = {
   '{Well did you try using it?}',
   '{That would be the control panel for the robot.}',
   '{Part of your training included think for yourself, I don\'t need to know about every little thing.}'
}

minetest.register_node('rob_opr_base:computer_3', {
   description = 'Control Computer (Expert Level)',
   drawtype = 'mesh',
   mesh = 'rob_opr_base_computer_1.obj',
   paramtype = 'light',
   paramtype2 = 'facedir',
   light_source = 1,
   tiles = {'rob_opr_base_computer_1.png'},
   groups = {oddly_breakable_by_hand = 3, configure = 1},
   collision_box = computer_box,
   selection_box = computer_box,
   on_construct = function(pos)
      local meta = minetest.get_meta(pos)
      local inv = meta:get_inventory()
      inv:set_size('queue', 60)
   end,
   on_rightclick = function(pos, node, clicker)
      local name = clicker:get_player_name()
      rob_opr_base.act_menu[name] = pos
      minetest.show_formspec(name, 'action_menu', rob_opr_base.action_menu('1111'))
   end,
   on_punch = function(pos, node, puncher)
      local name = puncher:get_player_name()
      rob_opr_base.act_menu[name] = pos
      minetest.show_formspec(name, 'comp_expert', comp_expert(pos))
   end,
   _on_use = function(pos, name)
      rob_opr_base.act_menu[name] = pos
      minetest.show_formspec(name, 'comp_expert', comp_expert(pos))
   end,
   _on_report = function(pos, name)
      minetest.chat_send_player(name, (minetest.colorize('#49adff', rob_opr_base.random_chat(computer_report))))
   end,
   _on_configure = function(pos, name)
      minetest.show_formspec(name, 'comp_configure', comp_configure(pos))
   end,
   _on_inspect = function(pos, name)
      minetest.chat_send_player(name, (minetest.colorize('#28b928', rob_opr_base.random_chat(computer_inspection))))
   end,
})

minetest.register_on_player_receive_fields(function(player, formname, fields)
   if formname == 'comp_expert' then
      local name = player:get_player_name()
      if fields.start then
         local pos = rob_opr_base.act_menu[name]
         local meta = minetest.get_meta(pos)
         local inv = meta:get_inventory()
         local steps = {}
         for i = 1,60 do
            local item = inv:get_stack('queue', i)
            if item then
               local def = item:get_definition()
               local vector = def.vector
               if vector then
                  steps[#steps+1] = def.vector
               end
            end
         end
         steps[#steps+1] = {x=0, y=0, z=0}
         local start_pos = meta:get_string('start_pos')
         local start = minetest.string_to_pos(start_pos)
         local robot = minetest.add_entity(start, 'rob_opr_base:robot_2')
         local robot_entity = robot:get_luaentity()
         robot_entity.node_timer = 0
         robot_entity.step = 1
         robot_entity.owner = name
         robot_entity.sequence = steps
      end
   elseif formname == 'comp_configure' then
      local name = player:get_player_name()
      if fields.save then
         local pos = rob_opr_base.config[name]
         local meta = minetest.get_meta(pos)
         meta:set_string('start_pos', fields.start_pos)
      end
   end
end)
