local game = ...

local game_over_menu = {}  -- The game-over menu.

local music
local background_img
local hero_was_visible
local hero_dead_sprite
local hero_dead_x, hero_dead_y
local fade_sprite
local fairy_sprite
local cursor_position
local state

-- state can be one of:
-- "waiting_start": The game-over scene will start soon.
-- "closing_game": Fade-out on the game screen.
-- "red_screen": Red screen during a small delay.
-- "opening_menu": Fade-in on the game-over menu.
-- "saved_by_fairy": The player is being saved by a fairy.
-- "waiting_end": The game will be resumed soon.
-- "resume_game": The game can be resumed.
-- "menu": The player can choose an option in the game-over menu.
-- "finished": An action was validated in the menu.

function game:on_game_over_started()
  -- Attach the game-over menu to the map so that the map's fade-out
  -- effect applies to it when restarting the game.
  if game:get_hero():is_condition_active('cursed') then game:get_hero():stop_cursed() end -- Otherwise sword is permanently disabled!
  if game:get_value("times_died") == nil then game:set_value("times_died", 0) end
  game:set_value("times_died", game:get_value("times_died") + 1)
  sol.menu.start(game:get_map(), game_over_menu)
end

function game_over_menu:on_started()
  local hero = game:get_hero()
  hero_was_visible = hero:is_visible()
  hero:set_visible(false)
  music = sol.audio.get_music()
  background_img = sol.surface.load("languages/" .. sol.language.get_language() .. "/images/gameover_menu.png")
  local tunic = game:get_ability("tunic")
  hero_dead_sprite = sol.sprite.create("hero/tunic" .. tunic)
  hero_dead_sprite:set_animation("hurt")
  hero_dead_sprite:set_direction(hero:get_direction())
  hero_dead_sprite:set_paused(true)
  fade_sprite = sol.sprite.create("hud/gameover_fade")
  fairy_sprite = sol.sprite.create("entities/items")
  fairy_sprite:set_animation("fairy")
  state = "waiting_start"

  local map = game:get_map()
  local camera_x, camera_y = map:get_camera():get_position()
  local hero_x, hero_y = hero:get_position()
  hero_dead_x = hero_x - camera_x
  hero_dead_y = hero_y - camera_y

  sol.timer.start(self, 500, function()
    state = "closing_game"
    sol.audio.stop_music()
    fade_sprite:set_animation("close")
    fade_sprite.on_animation_finished = function()
      if state == "closing_game" then
        state = "red_screen"
        sol.audio.play_sound("hero_dying")
        hero_dead_sprite:set_paused(false)
        hero_dead_sprite:set_direction(0)
        hero_dead_sprite:set_animation("dying")
        sol.timer.start(self, 2000, function()
          state = "opening_menu"
          fade_sprite:set_animation("open")
        end)
      elseif state == "opening_menu" then
        local bottle_with_fairy = game:get_first_bottle_with(7)
        if bottle_with_fairy ~= nil then
          -- Has a fairy.
          state = "saved_by_fairy"

          -- Make the bottle empty.
          bottle_with_fairy:set_variant(1)
          fairy_sprite:set_xy(hero_dead_x + 12, hero_dead_y + 21)
          local movement = sol.movement.create("target")
          movement:set_target(240, 22)
          movement:set_speed(96)

          movement:start(fairy_sprite, function()
            state = "waiting_end"
            game:add_life(7 * 4)  -- Restore 7 hearts and some stamina.
            game:add_stamina(80)
            sol.timer.start(self, 1000, function()
              state = "resume_game"
              sol.audio.play_music(music)
              game:stop_game_over()
              sol.menu.stop(self)
            end)
          end)
        else
          -- No fairy: game over.
          state = "menu"
          sol.audio.play_music("game_over", false)
          fairy_sprite:set_xy(76, 112)  -- Cursor.
          cursor_position = 0
        end

      end
    end
  end)
end

function game_over_menu:on_finished()
  local hero = game:get_hero()
  if hero ~= nil then
    hero:set_visible(hero_was_visible)
  end
  music = nil
  background_img = nil
  hero_dead_sprite = nil
  fade_sprite = nil
  fairy_sprite = nil
  cursor_position = nil
  state = nil
  sol.timer.stop_all(self)
end

local black = {0, 0, 0}
local red = {224, 32, 32}

function game_over_menu:on_draw(dst_surface)
  if state ~= "waiting_start" and state ~= "closing_game" then
    -- Hide the whole map.
    dst_surface:fill_color(black)
  end

  if state == "closing_game"
      or state == "opening_menu" then
    fade_sprite:draw(dst_surface, hero_dead_x, hero_dead_y)
  elseif state == "red_screen" then
    dst_surface:fill_color(red)
  end

  if state == "menu" or state == "finished" then
    background_img:draw(dst_surface)
    fairy_sprite:draw(dst_surface)
  elseif state ~= "resume_game" then
    hero_dead_sprite:draw(dst_surface, hero_dead_x, hero_dead_y)
    if state == "saved_by_fairy" then
      fairy_sprite:draw(dst_surface)
    end
  end
end

function game_over_menu:on_command_pressed(command)
  if state ~= "menu" then
    -- Commands are not available during the game-over opening animations.
    return
  end

  if command == "down" then
    sol.audio.play_sound("cursor")
    cursor_position = (cursor_position + 1) % 4
    local fairy_x, fairy_y = fairy_sprite:get_xy()
    fairy_y = 112 + cursor_position * 16
    fairy_sprite:set_xy(fairy_x, fairy_y)
  elseif command == "up" then
    sol.audio.play_sound("cursor")
    cursor_position = (cursor_position + 3) % 4
    local fairy_x, fairy_y = fairy_sprite:get_xy()
    fairy_y = 112 + cursor_position * 16
    fairy_sprite:set_xy(fairy_x, fairy_y)
  elseif command == "action" or command == "attack" then

    state = "finished"
    sol.audio.play_sound("danger")
    game.hud:set_enabled(false)
    game:add_life(7 * 4)  -- Restore 7 hearts.
    if game:get_stamina() <= 80 then game:add_stamina(80) end  -- Restore some stamina if it's too low.

    if cursor_position == 0 then
      -- Save and continue.
      game:save()
      game:start()
    elseif cursor_position == 1 then
      -- Save and quit.
      game:save()
      sol.main.reset()
    elseif cursor_position == 2 then
      -- Continue without saving.
      game:start()
    elseif cursor_position == 3 then
      -- Quit without saving.
      sol.main.reset()
    end
  end
end