# module GTK
#   class Runtime
#     def __sdl_tick__ sdl_tick
#       @last_sdl_tick ||= sdl_tick
#       @sdl_tick = sdl_tick
#       # in the event of a slowdown, sdl attempts to catch up the simulation
#       # this prevents the simulation from running too fast
#       return if (sdl_tick - @last_sdl_tick) < 16

#       tick_argv

#       return if @no_tick

#       __sdl_tick__simulation__

#       if (@simulation_speed && @simulation_speed != 1)
#         (@simulation_speed - 1).abs.times do
#           __sdl_tick__simulation__
#         end
#       end

#       @last_sdl_tick = sdl_tick
#     rescue Exception => e
#       @last_tick_exception_global_at = Kernel.global_tick_count
#       @is_inside_tick = false
#       local_file_name = "logs/exceptions/game_state_#{@args.state.tick_count}.txt"
#       log_info "Game state and exception will be written to #{local_file_name} and logs/exceptions/current.txt."
#       pretty_print_exception_and_export! e
#       pause!
#     end
#   end
# end

def draw_tile_coords(args)
  mouse = args.inputs.mouse
  room_rect = args.state.room_rect.copy
  return unless mouse.has_focus
  return unless mouse.inside_rect?(room_rect)

  offset = args.state.room_offset

  tile_x = ((mouse.x - room_rect.x) / 32)
  tile_y = ((mouse.y - room_rect.y) / 32)

  local_mouse_coordinates = {x: mouse.x - offset.x, y: mouse.y - offset.y}

  tile_w = 32
  tile_h = 32

  grid_cell_count_w = (room_rect.w / tile_w).to_i
  grid_cell_count_h = (room_rect.h / tile_h).to_i

  line_color = Color::BROWN
  grid = []
  (1...grid_cell_count_w).each do | x_loc |
    line_hash = {x: (x_loc * tile_w), y: 0, x2: (x_loc * tile_w), y2: room_rect.h, primitive_marker: :line }.merge!(**line_color)
    grid << line_hash
  end

  (1...grid_cell_count_h).each do | y_loc |
    line_hash = {x: 0, y: (y_loc * tile_h), x2: room_rect.w, y2: (y_loc * tile_h), primitive_marker: :line }.merge!(**line_color)
    grid << line_hash
  end
  
  args.outputs[:buffer].primitives << grid
  args.outputs[:buffer].borders << room_rect.merge(**line_color).merge({x: 0, y: 0})
  draw_point = {
    x: (local_mouse_coordinates.x / tile_w).to_i * tile_w,
    y: (local_mouse_coordinates.y / tile_h).to_i * tile_h
  }
  alpha_value = (255 / 3).to_i

  args.outputs[:buffer].primitives << {x: draw_point.x, y: draw_point.y, w: tile_w, h: tile_h, **Color::BLACK, a: alpha_value, primitive_marker: :solid}

  args.outputs.labels << {x: offset.x, y: 75, text: "Tile X: #{tile_x.to_i}, Tile Y: #{tile_y.to_i}", r: 255, g: 255, b: 255}
  args.outputs.labels << {x: offset.x, y: 40, text: "Option/Alt Click to set the player location to highlighted cell.", r: 255, g: 255, b: 255, size_px: 16}

  kb = args.inputs.keyboard
  if kb.key_held.alt and mouse.down
    player_pos(args, tile_x.to_i, tile_y.to_i)
  end

  if kb.key_held.control && mouse.down
    add_item_money(args, tile_x, tile_y)
  end

  if kb.key_held.meta && mouse.down
    add_item_life(args, tile_x, tile_y)
  end

  if kb.key_held.z && mouse.down
    add_item_bomb(args, tile_x, tile_y)
  end

end

def show_controls_dialog(args)
  dialog_size = {w: 500, h: 500}
  dialog_position = {x: (args.grid.w / 2) - (dialog_size.w / 2), y: (args.grid.h / 2) - (dialog_size.h / 2)}
  dialog_rt_name = :dialog_rt
  dialog_rt = args.outputs[dialog_rt_name]
  dialog_rt.transient!
  dialog_rt.w = dialog_size.w
  dialog_rt.h = dialog_size.h

  text_color = Color::GREEN.copy
  dialog_bg_color = Color::BLACK.copy

  dialog_rt.solids << {x: 0, y: 0, w: dialog_size.w, h: dialog_size.h, **dialog_bg_color}
  dialog_rt.borders << {x: 0, y: 0, w: dialog_size.w, h: dialog_size.h, **Color::WHITE}

  labels = []
  labels.append( {x: (dialog_size.w / 2), y: dialog_size.h - 1, text: "Player Controls", alignment_enum: 1, **text_color})
  labels.append( {x: (dialog_size.w / 2), y: dialog_size.h - 157, text: "Debug Keys", alignment_enum: 1, **text_color})

  player_controls = [
    "Move Left: Left Arrow Key", "Move Right: Right Arrow Key", "Move Up: Up Arrow Key", "Move Down: Down Arrow Key",
    "Primary Weapon: F", "Secondary Weapon: A"
  ]
  debug_controls = [
    "1: Toggle Background Color ", "5: Turn on Garbage Collection", "%: Disable Garbage Collection",
    "\\: Show DragonRuby Version", "r: Reload current room from disk", "R: Reset game",
    "!: Toggle show room names", "@: Toggle show room links", "-: Decrease Player Move Speed", "=: Increase Player Move speed", "): Toggle Tile Coords",
    "Spacebar: Show/Hide Inventory"
  ]
  section_lines = [
    {x: 0, y: dialog_size.h - 155, x2: dialog_size.w, y2: dialog_size.h - 155, **Color::WHITE},
    {x: 0, y: dialog_size.h - 180, x2: dialog_size.w, y2: dialog_size.h - 180, **Color::WHITE},
    {x: 0, y: dialog_size.h - 25, x2: dialog_size.w, y2: dialog_size.h - 25, **Color::WHITE}
  ]

  BASE_POS = 30
  player_controls.each_with_index do | text, index |
    labels.append({x: 10, y: dialog_size.w - BASE_POS - (index * 20), text: text, **text_color})
  end

  BASE_POS = 185
  debug_controls.each_with_index do | text, index |
    labels.append({x: 10, y: dialog_size.h - BASE_POS - (index * 20), text: text, **text_color})
  end

  dialog_rt.lines << section_lines
  dialog_rt.labels << labels

  args.outputs.primitives << {x: dialog_position.x, y: dialog_position.y, w: dialog_size.w, h: dialog_size.h, primitive_marker: :sprite, path: dialog_rt_name}
end

def draw_debug_info args
  text_size = 12
  text_color = Color::WHITE
  # args.outputs.labels << {x: 10, y: 16.from_top, text: "should_transition: #{args.state.should_transition}", size_px: text_size, **text_color, font: args.state.text_font}
  # args.outputs.labels << {x: 10, y: 32.from_top, text: "room_transitioning: #{args.state.room_transitioning}", size_px: text_size, **text_color, font: args.state.text_font}

  args.outputs.labels << {x: 10, y: 16.from_top, text: "old_room.x: #{args.state.old_room_x}", size_px: text_size,**text_color, font: args.state.text_font}
  args.outputs.labels << {x: 10, y: 32.from_top, text: "new_room.x: #{args.state.new_room_x}", size_px: text_size, **text_color, font: args.state.text_font}
  args.outputs.labels << {x: 10, y: 64.from_top, text: "Player X: #{args.state.player.x}", size_px: text_size, **text_color, font: args.state.text_font}
  args.outputs.labels << {x: 10, y: 88.from_top, text: "Player Y: #{args.state.player.y}", size_px: text_size, **text_color, font: args.state.text_font}
  
  args.outputs.labels << {x: 250.from_right, y: 80.from_top, text: "Current Room X: #{args.state.player.current_room_coordinates.x}", size_px: text_size, **text_color, font: args.state.text_font}
  args.outputs.labels << {x: 250.from_right, y: 100.from_top, text: "Current Room Y: #{args.state.player.current_room_coordinates.y}", size_px: text_size, **text_color, font: args.state.text_font}
end

def draw_debug_rects(args)
  return if !args.state.show_debug_rects

  room_rect = {
    x: args.state.room_offset.x + args.state.room_rect.x,
    y: args.state.room_offset.y + args.state.room_rect.y,
    w: args.state.room_rect.w,
    h: args.state.room_rect.h
  }
  room_transition_rect = {
    x: args.state.room_offset.x + args.state.room_transition_rect.x,
    y: args.state.room_offset.y + args.state.room_transition_rect.y,
    w: args.state.room_transition_rect.w,
    h: args.state.room_transition_rect.h
  }
  args.outputs.borders << {**room_rect, **Color::RED}
  args.outputs.borders << {**room_transition_rect, **Color::GREEN}
end

