class 'Tutorial' (GlobalScript)

class 'TutorialPointer'

function TutorialPointer:__init(script, locked_obj, text, offset, pointer_offset)
  self.script = script
  self.locked_obj = locked_obj
  self.use_item_in_hand = nil

  self.hiding = false

  local obj_center_pos = Position(0, 0)
  if(locked_obj ~= nil) then
    obj_center_pos = locked_obj:safe_position() + locked_obj:safe_dimensions():vector() / 2
  end

  -- renderables
  self.back_renderable = script:add_renderable(script.hint_back_id)
  self.back_renderable:set_position(obj_center_pos + offset)
  self.back_renderable:set_alpha(0)

  self.pointer_renderable = script:add_renderable(script.pointer_id)
  self.pointer_renderable:set_position(obj_center_pos + pointer_offset)
  self.pointer_renderable:set_alpha(0)

  self.text_renderable = script:add_text_renderable()
  self.text_renderable:set_text_key(text)
  self.text_renderable:set_max_width(script.text_dim:lx())
  self.text_renderable:set_lines_h_align('left')
  self.text_renderable:set_h_align('center')
  self.text_renderable:set_v_align('center')
  self.text_renderable:set_font(script.text_font_id)
  self.text_renderable:set_color(script.text_color:red(), script.text_color:green(), script.text_color:blue())
  self.text_renderable:set_line_offset(script.text_line_offset)
  self.text_renderable:set_dimensions(script.text_dim)
  self.text_renderable:set_position(self.back_renderable:position() + script.text_pos)
  self.text_renderable:set_alpha(0)

  -- controllers
  self.back_controller = script:create_controller(self.back_renderable)
  self.back_controller:alpha(1, script.pointer_show_time)

  self.pointer_controller = script:create_controller(self.pointer_renderable)
  self.pointer_controller:alpha(1, script.pointer_show_time)

  self.text_controller = script:create_controller(self.text_renderable)
  self.text_controller:alpha(1, script.pointer_show_time)
end

function TutorialPointer:update(dt)
  if(not self.hiding and self.locked_obj ~= nil and not self.locked_obj:visible()) then self:hide() end

  if(self.hiding and self.back_controller ~= nil and self.back_controller:time() >= self.back_controller:total_time()) then
    self.back_controller:remove()
    self.pointer_controller:remove()
    self.text_controller:remove()
    self.back_controller = nil
    self.pointer_controller = nil
    self.text_controller = nil

    self.back_renderable:remove()
    self.text_renderable:remove()
    self.pointer_renderable:remove()
  end
end

function TutorialPointer:complete(dt)
  return self.hiding and self.back_controller == nil
end

function TutorialPointer:hide()
  self.back_controller:remove()
  self.pointer_controller:remove()
  self.text_controller:remove()

  self.hiding = true

  self.back_controller = self.script:create_controller(self.back_renderable)
  self.back_controller:alpha(0, self.script.pointer_hide_time)

  self.pointer_controller = self.script:create_controller(self.pointer_renderable)
  self.pointer_controller:alpha(0, self.script.pointer_hide_time)

  self.text_controller = self.script:create_controller(self.text_renderable)
  self.text_controller:alpha(0, self.script.pointer_hide_time)
end

function Tutorial:__init() super()
  self.tutorial_disabled_mark = 'tutorial_disabled'
  self.tutorial_enabled_mark = 'tutorial_enabled'

  self.hint_back_id = 'tutorial/hint_back'
  self.pointer_id = 'tutorial/pointer'
  self.hint_back_offset = Position(50, -102)
  self.pointer_offset = Position(-33, -71)

  self.text_font_id = 'Trajan'
  self.text_color = Color(255, 255, 255)
  self.text_line_offset = 0
  self.text_pos = Position(32, 22)
  self.text_dim = Dimensions(380, 110)

  self.pointer_show_time = 0.5
  self.pointer_hide_time = 0.5

  self.dialog_showed = 'need_tutorial'
  self.inventory_item_name = 'shipci'
  self.container_name = 'zoom02'
  self.inventory_item_on_target_item = 'i_forceps'
  self.inventory_item_on_target_target = 'z02_knife'
  self.hos_description = true
  self.hos_hint = true
  self.minigame = true
  self.minigame_skip = true

  self.dialog_showing = false

  self.pointer = nil
  self.last_scene_time = 0
end

function Tutorial:on_attach()
  self:listen_event('attach_scene')
  self:listen_event('hint_button_pressed')

  self.last_scene_time = 0
end

function Tutorial:on_event(name)
  if(name == 'attach_scene') then
    self.last_scene_time = 0
  elseif(name == 'hint_button_pressed') then
    if(self.pointer ~= nil) then
      self.pointer:hide()
    end
  end
end

function Tutorial:on_mouse_move()
end

function Tutorial:on_lb_down()
  if(self.pointer ~= nil) then
    local scene = self:game():current_scene()
    local need_cancel = true
    local need_hide = false
    if(not self.pointer.hiding) then
      if(self.pointer.locked_obj == nil) then
        need_cancel = true
        need_hide = true
      elseif(self.pointer.use_item_in_hand ~= nil) then
        local target_name = scene:item_in_hand_target()
        local item_in_hand = scene:item_in_hand()
        if(self.pointer.locked_obj:name() == target_name and item_in_hand == self.pointer.use_item_in_hand) then
          need_cancel = false
          need_hide = true
        end
        if(#item_in_hand == 0) then
          local obj = scene:overed_object()
          if(obj ~= nil and obj:name() == self.pointer.locked_obj:name()) then
            need_cancel = false
            need_hide = false
          end
        end
      else
        local obj = scene:overed_object()
        if(obj ~= nil and obj:name() == self.pointer.locked_obj:name()) then
          need_cancel = false
          need_hide = true
        end
      end
    end
    if(need_cancel) then
      if(#scene:item_in_hand() ~= 0) then
        scene:reset_item_in_hand(true)
      end
      scene:cancel_input_event()
    end
    if(need_hide) then
      self.pointer:hide()
    end
  end
end

function Tutorial:on_update(dt)
  self.last_scene_time = self.last_scene_time + dt

  if(self.pointer ~= nil) then
    self.pointer:update(dt)
    if(self.pointer:complete()) then
      self.pointer = nil
      if(self:all_complete()) then
        self:remove()
        return
      end
    else
      return
    end
  end

  local scene = self:game():current_scene()

  if(scene == nil) then return end

  if(self.dialog_showed ~= nil) then
    scene:show_dialog(self.dialog_showed, true)
    self.dialog_showed = nil
    self.dialog_showing = true
  end

  if(scene:have_global_mark(self.tutorial_enabled_mark)) then
    self.dialog_showing = false
    scene:reset_global_mark(self.tutorial_enabled_mark)
  end

  if(not self.dialog_showing) then
    self:process(scene)
  end

  if(scene:have_global_mark(self.tutorial_disabled_mark)) then
    scene:reset_global_mark(self.tutorial_disabled_mark)
    self:remove()
    return
  end
end

function Tutorial:process(scene)
  if(self.inventory_item_name ~= nil and scene:object(self.inventory_item_name) ~= nil) then -- inventory item
    local obj = scene:object(self.inventory_item_name)
    self.pointer = TutorialPointer(self, obj, 'root/tutorial/@this_is_inventory_item', self.hint_back_offset + Position(0, -120), self.pointer_offset + Position(10, -30))
    self.inventory_item_name = nil
  elseif(self.container_name ~= nil and scene:object(self.container_name) ~= nil) then -- container
    local obj = scene:object(self.container_name)
    self.pointer = TutorialPointer(self, obj, 'root/tutorial/@this_is_container', self.hint_back_offset + Position(-270, -200), self.pointer_offset + Position(0, -50))
    self.container_name = nil
  elseif(self.inventory_item_on_target_item ~= nil and self:game():item_in_inventory(self.inventory_item_on_target_item) and scene:object(self.inventory_item_on_target_target) ~= nil) then -- inventory item on target
    local obj = scene:object(self.inventory_item_on_target_target)
    if(obj:visible()) then
      self.pointer = TutorialPointer(self, obj, 'root/tutorial/@use_inventory_item_on_target', self.hint_back_offset + Position(-270, -150), self.pointer_offset + Position(0, -30))
      self.pointer.use_item_in_hand = self.inventory_item_on_target_item
      self.inventory_item_on_target_item = nil
      self.inventory_item_on_target_target = nil
    end
  elseif(self.hos_description and scene:is_hos()) then -- hos
    if(self.last_scene_time > 1) then
      self.pointer = TutorialPointer(self, nil, 'root/tutorial/@this_is_items_by_name_list', Position(418, 400), Position(606, 580))
      self.pointer.pointer_renderable:set_above_interface(true)
      self.hos_description = false
    end
  elseif(self.hos_hint and scene:is_hos()) then -- hos hint
    self.pointer = TutorialPointer(self, nil, 'root/tutorial/@this_is_hos_hint', Position(770, 400) - wide_screen_offset(), Position(1180, 580) - wide_screen_offset())
    self.pointer.pointer_renderable:set_above_interface(true)
    self.hos_hint = false
  elseif(self.minigame and #self:game():game_info() ~= 0) then -- minigame
    if(self.last_scene_time > 1) then
      self.pointer = TutorialPointer(self, nil, 'root/tutorial/@this_is_items_minigame_desc', Position(418, 385), Position(606, 565))
      self.pointer.pointer_renderable:set_above_interface(true)
      self.minigame = false
    end
  elseif(self.minigame_skip and #self:game():game_info() ~= 0) then -- skip minigame
    self.pointer = TutorialPointer(self, nil, 'root/tutorial/@this_is_minigame_skip', Position(770, 400) - wide_screen_offset(), Position(1180, 580) - wide_screen_offset())
    self.pointer.pointer_renderable:set_above_interface(true)
    --self.pointer.pointer_renderable:set_angle(180, Position(34, 40))
    self.minigame_skip = false
  end
end

function Tutorial:all_complete()
  return self.dialog_showed == nil and self.inventory_item_name == nil and self.container_name == nil and self.inventory_item_on_target_item == nil and self.inventory_item_on_target_target == nil and self.hos_description == false and self.hos_hint == false and self.minigame == false and self.minigame_skip == false
end

function Tutorial:save(ios)
  ios:save(0)
  ios:save(self.dialog_showed)
  ios:save(self.inventory_item_name)
  ios:save(self.container_name)
  ios:save(self.inventory_item_on_target_item)
  ios:save(self.inventory_item_on_target_target)
  ios:save(self.hos_description)
  ios:save(self.hos_hint)
  ios:save(self.minigame)
  ios:save(self.minigame_skip)
  ios:save(self.dialog_showing)
end

function Tutorial:load(ios)
  local ver = ios:load()
  self.dialog_showed = ios:load()
  self.inventory_item_name = ios:load()
  self.container_name = ios:load()
  self.inventory_item_on_target_item = ios:load()
  self.inventory_item_on_target_target = ios:load()
  self.hos_description = ios:load()
  self.hos_hint = ios:load()
  self.minigame = ios:load()
  self.minigame_skip = ios:load()
  self.dialog_showing = ios:load()
end