-------------------------------------------------------------------------------
-- ****************************************************************************
--  Entity: Final Boss
--  State: Trapped (2)
--  Phase: 2 of 3
-- ****************************************************************************
-------------------------------------------------------------------------------

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

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

-- Name of state
local STATE_NAME = "MegaWhiteShark_Phase2_Trapped" -- 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 = "NO_STATE"

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

-- Time to speak
local TIME_TO_SPEAK = 5.0 -- a float number
local timer_to_speak = CTimer( TIME_TO_SPEAK ) -- do NOT touch this!!

local TIME_INVULNERABILITY = 0.6 -- a float number
local timer_invulnerability = CTimer( TIME_INVULNERABILITY ) -- do NOT touch this!!


-- Animation
local ANIMATION_NAME = "trapped2" -- a string
local ANIMATION_TIME = (230 - 160)/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!!

-- Coins
NUM_COINS_TO_THROW = 1
HIT_COUNT = 0
MAX_HITS = 3


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

--[[---------------------------------------------------------------------------
  isHitFromBack
-------------------------------------------------------------------------------
  Description: 
    - determines if the current entity has been hit from back or not
  Return:
    - true if entity is hit from back
    - false otherwise
  Params:
    - entity: the pointer to the entity
    - message: the message that contains extra information
  NOTE:
    - here we are assuming that the entity can ONLY be hit by the player
      which is exactly what happens in the game because the final boss can only
      receive damage from the player, but in a more complex scenario we should
      get the "attacking entity position" from the message extraInfo parameters
-----------------------------------------------------------------------------]]
local function isHitFromBack( entity, message )

  -- get the necessary vectors to make the dot_product calculation
  local entity_pos = entity:getPosition()
  local player_pos = getPlayerPosition()
  local entity_front = entity:getFront()
  
  local entity_to_player = player_pos - entity_pos
  local dot_product = vector3Dot( entity_front, entity_to_player )
  
  -- if the dot product is Negative, it means the entity was hit from it's back
  if( dot_product < 0.0 ) then
    return true
  end
  
  -- otherwise, return false
  return false
end






--[[---------------------------------------------------------------------------
  throwCoins
-------------------------------------------------------------------------------
  Description: 
    - throws some coins as a reward to the player for beating the boss
  Return:
    - n/a
  Params:
    - entity: the pointer to the entity (the final boss)
-----------------------------------------------------------------------------]]
local function throwCoins( entity )

	  local enemy_pos = getEntityPositionByID( entity:ID() )
	  local angle = 0.0;
	  local radius = 2.5;
	  
	  local player_pos = getPlayerPosition()
    local direction = player_pos - enemy_pos
	  local normalized_dir = vector3Normalize( direction )
	  
    for i = 0, NUM_COINS_TO_THROW, 1 do
	    direction = normalized_dir * radius
      local coin_pos = direction + enemy_pos
      
      local offset_y = -0.2
      coin_pos.y = enemy_pos.y + offset_y
      
      addTemporalCoin( enemy_pos, coin_pos, 10.0 )
      angle = angle + 0.2	  
	  end
 
end


--[[---------------------------------------------------------------------------
  processHitMessagePhase2
-------------------------------------------------------------------------------
  Description: 
    - determines how to handle a Hit Message and if it does damage to the
      Entity or it does not.
  Return:
    - true if message has been processed
    - false otherwise
  Params:
    - entity: the pointer to the entity who receives the message
    - message: the message itself
-----------------------------------------------------------------------------]]
local function processHitMessagePhase2( entity, message )

  -- if message sent by himself, mark it as processed and return true
  if ( message.Sender == message.Receiver ) then
    return true
  end
  
  -- if message sent by his weapon, mark it as processed and return true
  local sword_id = getExtraItemID( 0, entity:ID() )
  local shield_id = getExtraItemID( 1, entity:ID() )
  
  -- if message sent by its own sword...
  if( message.Sender == sword_id ) then
    return true
  
  -- if message sent by its own shield...
  elseif( message.Sender == shield_id ) then
    return true
  end
  
  -- otherwise increase hit count and if 3 change to ReceiveHit state
  if( timer_invulnerability:isOutOfTime() ) then
    HIT_COUNT = HIT_COUNT + 1
    throwCoins( entity )
    --setEntityInvulnerable( entity:ID(), true )
    
    playAnimationAction( entity:ID(), "trapped_hit" )
    
    -- Throw event finalBoss: sound
    finalBoss_hitStage2_trapped( entity:getPosition(), entity );
    
    timer_invulnerability:restart()
  end

  if( HIT_COUNT >= MAX_HITS ) then
    changeEntityState( entity:ID(), "MegaWhiteShark_Phase2_ReceiveHit" )
  end
    
  -- otherwise, message has not been processed and we must return false
  return false
end

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

-------------------------------------------------------------------------------
-- Enter
-------------------------------------------------------------------------------
MegaWhiteShark_Phase2_Trapped["Enter"] = function(entity)
 
  -- play animation and restart the timer
  playAnimationCycle( entity:ID(), ANIMATION_NAME )
  timer:restart()
  
  timer_invulnerability:restart()
  timer_to_speak:restart()
  
end


-------------------------------------------------------------------------------
-- Execute
-------------------------------------------------------------------------------
MegaWhiteShark_Phase2_Trapped["Execute"] = function(entity)
  
  -- Si es la ultima vida, i esta en aquest estat ha de sortir del trapped 
  -- i començar la cinematica endStage2
  
  if( timer:isOutOfTime() and entity:getLife() == 1 and isPlayerDead() == false ) then
    StartCutScene_FinalBoss_EndStage2()
	MWS_COMES_TO_TRAPPED = true;
    changeEntityState( entity:ID(), "MegaWhiteShark_Phase2_GetUp" );
  
  -- Throw lines of finalBoss, if the player don't hit 
  elseif( timer_to_speak:isOutOfTime() and HIT_COUNT < MAX_HITS - 3 ) then
    -- Throw event finalBoss: sound
    finalBoss_trappedStage2( entity:getPosition(), entity );
    timer_to_speak:restart();
    
  end

end

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

  -- remove animation cycle
  removeAnimationCycle( entity:ID(), ANIMATION_NAME )
  
  -- restart counters
  HIT_COUNT = 0
end


-------------------------------------------------------------------------------
-- OnMessage
-------------------------------------------------------------------------------
MegaWhiteShark_Phase2_Trapped["OnMessage"] = function(entity, message)

  -- Receive Hit
  if ( message.Msg == Telegram.Receive_Hit ) then
    return processHitMessagePhase2( entity, message )
  end

  -- if message NOT handled, return false
  return false
end


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