-------------------------------------------------------------------------------
-- ****************************************************************************
--  Entity: Final Boss
--  State: Shadow on Player (2)
--  Phase: 2 of 3
-- ****************************************************************************
-------------------------------------------------------------------------------

--[[
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/////                              Variables                              /////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
--]]

-- Define the table that will contain the state
MegaWhiteShark_Phase2_ShadowOnPlayer = {}

-- Name of state
local STATE_NAME = "MegaWhiteShark_Phase2_ShadowOnPlayer" -- a string
registerStateFSM( STATE_NAME )  -- do NOT touch this!!

-- Name of the state to change to when the necesary conditions are met
local OUT_STATE = "MegaWhiteShark_Phase2_FallToMiddlePlatform"

-- Timer
local TIME_IN_STATE = 8.0 -- a float number
local timer = CTimer( TIME_IN_STATE ) -- do NOT touch this!!

-- This state has NO animation!
-- Animation
local ANIMATION_NAME = "megapicat" -- a string
--local ANIMATION_TIME = (301 - 300)/30.0 -- nš frames / framerate = time duration
--ANIMATION_TIME = ANIMATION_TIME - 0.05 -- to avoid cuts in animation
--local timer_animation = CTimer( ANIMATION_TIME ) -- do NOT touch this!!

-- move during all the TIME_IN_STATE except for the last 2 seconds
local TIME_TO_BE_FIXED = 2.0
local TIME_TO_MOVE = TIME_IN_STATE - TIME_TO_BE_FIXED
local timer_to_move = CTimer( TIME_TO_MOVE )

-- flying pos
local FLYING_POSITION = Vector3(-87.686, 6.9, -125.895)

-- time to push
local TIME_TO_PUSH = 2.0
local timer_to_push = CTimer( TIME_TO_PUSH )

-- time to speak
local TIME_TO_SPEAK = 4.0
local timer_to_speak = CTimer( TIME_TO_SPEAK )
local isSpeak = false;

local STARTING_SHADOW_SIZE = 0.25
local ENDING_SHADOW_SIZE = 2.0

--[[
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/////                               Functions                             /////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
--]]

local function interpolate( curr_time, start_value, end_value )

  local result = end_value + (curr_time/TIME_IN_STATE)*(start_value - end_value)
  
  return result
end

--[[
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/////                               States                                /////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
--]]

-------------------------------------------------------------------------------
-- Enter
-------------------------------------------------------------------------------
MegaWhiteShark_Phase2_ShadowOnPlayer["Enter"] = function(entity)

  -- enfocar shark que esta en el Cel
  -- posar camara vertical (picada)
  -- la sombra es pinta al centre i apartir d'aqui segueix al player
  -- durant X segons
  --local player_pos = getPlayerPos
  --setEntityPosition( entity:ID(), MWS_CENTER_PLATFORM )
  playAnimationAction( entity:ID(), ANIMATION_NAME )
  
   -- set the general finalBoss platform camera 
  local functionOrder = "setCameraMode( 4, \"\", \"trackerCamera_RingFinalBoss_Stage2_MegaPicat\", 20.0 )";
  addOrderToSequencer ( functionOrder, 0.5 );
  
  -- Enable seaUrchins in the finalBoss Platform
  functionOrder = "throwSeaUrchinBattalion_finalBoss()";
  addOrderToSequencer ( functionOrder, 0.0 );

  -- restart the timer
  timer:restart()
  timer_to_push:restart()
  timer_to_speak:restart()
  timer_to_move:restart()
  
  -- place the final boss's shadow on the center of the platform
  -- but higher so it's not rendered literally ON the platform, but a few meters
  -- ahead
  --local center_platform = MWS_CENTER_PLATFORM
  --center_platform.y = 3.0
  --setEntityPosition( entity:ID(), center_platform )
  
  entity:activateShadowGameplay()
  
  --invalidateEntity( entity:ID() )
  --entity:setVisible( true )
  
  
  setEntityPosition( entity:ID(), FLYING_POSITION )
  
  setEntityScale( entity:ID(), STARTING_SHADOW_SIZE )
  
  isSpeak = false;
  
end


-------------------------------------------------------------------------------
-- Execute
-------------------------------------------------------------------------------
MegaWhiteShark_Phase2_ShadowOnPlayer["Execute"] = function(entity)

  -- Shadow should go from BIG to Small (where small is normal size)
  -- calculate the current shadow size
  local current_time = timer:getCountDown()
  local new_scale = interpolate( current_time, STARTING_SHADOW_SIZE, ENDING_SHADOW_SIZE )
  setEntityScale( entity:ID(), new_scale )
     
  local player_pos = getPlayerPosition()
  local enemy_pos = getEntityPositionByID( entity:ID() )
  
  -- we want to calculate the distance in a 2D plane and not in 3D!
  player_pos.y = 0
  enemy_pos.y = 0
  
  local dist_to_player_sq = distanceSquared( player_pos, enemy_pos )
  local radius_attack_area_sq = entity:getRadiusAttackAreaSquared()
  
  if( timer_to_speak:isOutOfTime() and isSpeak == false ) then
    -- Throw event finalBoss: sound
    finalBoss_duringJumpMp( entity:getPosition(), entity );
    isSpeak = true;
  end
  
  -- ONLY PUSH the final boss if it is inside the time scope
  -- of being moved
  if not ( timer_to_move:isOutOfTime() ) then
    
    -- push the finalBoss towards the player in a fast acceleration!
    if( timer_to_push:isOutOfTime() ) then
    
      -- if we are near the player, restart the push timer (so it doesn't magnetically follow
      -- the player)
      if( dist_to_player_sq < radius_attack_area_sq ) then
        timer_to_push:restart()
      
      -- otherwise: keep pushing
      else
        local direction = player_pos - enemy_pos
        direction.y = 0.0 -- this will push the final boss only in direction XZ
        local speed = math.sqrt( dist_to_player_sq )
        
        pushEntity( entity:ID(), direction, speed )
      end
    end
  end
  
  -- finally, if the miniGameplay has ended, change the state :)
  if( timer:isOutOfTime() ) then
    changeEntityState( entity:ID(), OUT_STATE )
  end
  
end


-------------------------------------------------------------------------------
-- Exit
-------------------------------------------------------------------------------
MegaWhiteShark_Phase2_ShadowOnPlayer["Exit"] = function(entity)

  -- reactivate the entity and its bounding boxes
  -- validateEntity( entity:ID() )

  -- notify the entity that the shadowGamePlay has ended
  entity:deactivateShadowGameplay()
  
  setEntityScale( entity:ID(), ENDING_SHADOW_SIZE )
  
  -- ja no es un cicle sino un action!
  --removeAnimationCycle( entity:ID(), "idle" )

end


-------------------------------------------------------------------------------
-- OnMessage
-------------------------------------------------------------------------------
MegaWhiteShark_Phase2_ShadowOnPlayer["OnMessage"] = function(entity, message)
  -- if message NOT handled, return false
  return false
end


-------------------------------------------------------------------------------
-- GetNameOfCurrentState
-------------------------------------------------------------------------------
MegaWhiteShark_Phase2_ShadowOnPlayer["GetNameOfCurrentState"] = function()
  return STATE_NAME
end
