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

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

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

-- Name of state
local STATE_NAME = "MegaWhiteShark_Phase3_Dash" -- 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_Phase3_JustDive"

-- Timer
local WATER_PARTICLES_TIME = 0.5 -- a float number
local timer_particles = CTimer( WATER_PARTICLES_TIME ) -- do NOT touch this!!

-- Animation
local ANIMATION_NAME = "swim" -- a string

-- the position where the shark will Dash
local DASH_DESTINATION = Vector3( 0,0,0 )

local FIRST_PLATFORM_TO_DASH = Vector3( 0,0,0 )
local SECOND_PLATFORM_TO_DASH = Vector3( 0,0,0 )

local DASH_SPEED = 17.0

local FIRST_PLATFORM_DESTROYED = false
local SECOND_PLATFORM_DESTROYED = false

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

local function selectNextDash()

  -- increase current platform counter
  MWS_CURRENT_DASH = MWS_CURRENT_DASH + 1
  
  -- calc the mod of the current platform
  --MWS_CURRENT_DASH = math.mod( MWS_CURRENT_DASH, MWS_TOTAL_DASHES )
  
end

local function destroyFirstPlatform()

  local platform_name = MWS_SCRIPTED_DASH_SEQUENCE[MWS_CURRENT_DASH][0]
  
  -- tirar particules de chof!
  playSound( "Animated_entities/Common_events/Hit_impacts/water_splash", FIRST_PLATFORM_TO_DASH );
  throwAreaParticles( "unhide_water_big", FIRST_PLATFORM_TO_DASH, 1, 2 );
  
  -- fer invisible la plataforma
  invalidateEntityByName( platform_name )
  
  -- marcar com a destruida
  FIRST_PLATFORM_DESTROYED = true
end

local function destroySecondPlatform()

  local platform_name = MWS_SCRIPTED_DASH_SEQUENCE[MWS_CURRENT_DASH][1]
  
  -- tirar particules de chof!
  playSound( "Animated_entities/Common_events/Hit_impacts/water_splash", FIRST_PLATFORM_TO_DASH );
  throwAreaParticles( "unhide_water_big", SECOND_PLATFORM_TO_DASH, 1, 2 );
  
  -- fer invisible la plataforma
  invalidateEntityByName( platform_name )
  
  -- marcar com a destruida
  SECOND_PLATFORM_DESTROYED = true
end

local function checkPlatformsDestroyed(entity)

  local entity_pos_xz = getEntityPositionByID( entity:ID() )
  entity_pos_xz.y = 0
  
  local area_destroy_sq = 2*2 -- 2 meters squared

  if not( FIRST_PLATFORM_DESTROYED ) then
    -- 1) calcular distancia del boss a la platform en XZ
    local first_platform_XZ = Vector3( FIRST_PLATFORM_TO_DASH.x, 0, FIRST_PLATFORM_TO_DASH.z )

    -- 2) calcular si "d" esta dins del rang de destruccio de plataforma
    local d1 = distanceSquared( first_platform_XZ, entity_pos_xz )
    
    -- 3) si es correcte, enviar missatge a la plataforma i "destruirla" o amagarla
    if( d1 <= area_destroy_sq ) then
      destroyFirstPlatform()
    end
  end
  
  if not( SECOND_PLATFORM_DESTROYED ) then
    -- 1) calcular distancia del boss a la platform en XZ
    local second_platform_XZ = Vector3( SECOND_PLATFORM_TO_DASH.x, 0, SECOND_PLATFORM_TO_DASH.z )

    -- 2) calcular si "d" esta dins del rang de destruccio de plataforma
    local d2 = distanceSquared( second_platform_XZ, entity_pos_xz )
    
    -- 3) si es correcte, enviar missatge a la plataforma i "destruirla" o amagarla
    if( d2 <= area_destroy_sq ) then
      destroySecondPlatform()
    end
  end
   
  -- 5) si les dues han estat destruides: retornar TRUE
  --    sino, retornar FALSE
  if( FIRST_PLATFORM_DESTROYED and SECOND_PLATFORM_DESTROYED ) then
    return true
  else
    return false
  end
  
  
end

local function setDashMode(entity)
  entity:setDashMode( true )
end

local function unsetDashMode(entity)
  entity:setDashMode( false )
end

local function getDashDestination()

  local first_platform_to_dash = MWS_SCRIPTED_DASH_SEQUENCE[MWS_CURRENT_DASH][0]
  local second_platform_to_dash = MWS_SCRIPTED_DASH_SEQUENCE[MWS_CURRENT_DASH][1]
  
  local first_pos = getEntityPosition ( first_platform_to_dash )
  local second_pos = getEntityPosition ( second_platform_to_dash )
  
  FIRST_PLATFORM_TO_DASH = first_pos
  SECOND_PLATFORM_TO_DASH = second_pos
    
  local offset_vector = second_pos - first_pos

  local distance_offset = 1
  local new_dash_destination = second_pos + offset_vector * distance_offset
  
  return new_dash_destination
 
end

local function activateVisualFeedBack()
  
  local first_platform_to_dash = MWS_SCRIPTED_DASH_SEQUENCE[MWS_CURRENT_DASH][0]
  local second_platform_to_dash = MWS_SCRIPTED_DASH_SEQUENCE[MWS_CURRENT_DASH][1]
  
  local firstPlatformPos = getEntityPosition( MWS_SCRIPTED_DASH_SEQUENCE[MWS_CURRENT_DASH][0] );
  firstPlatformPos.y = firstPlatformPos.y + 2.0;
  throwParticles( "warning_platform", firstPlatformPos, NULL );
  
  local secondPlatformPos = getEntityPosition( MWS_SCRIPTED_DASH_SEQUENCE[MWS_CURRENT_DASH][1] );
  secondPlatformPos.y = secondPlatformPos.y + 2.0;
  throwParticles( "warning_platform", secondPlatformPos, NULL );
  
  setBlinkerByName( first_platform_to_dash, ColorRGBA(0.8,0.8,0.8,0.8), 10, 8 );
  setBlinkerByName( second_platform_to_dash, ColorRGBA(0.8,0.8,0.8,0.8), 10, 8 );

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

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

  -- play animation and restart the timer
  playAnimationCycle( entity:ID(), ANIMATION_NAME )
  
  timer_particles:restart()
  
  -- 1) calcular Dash destination, que es 2 metres mes enlla de la
  --    segona plataforma a la que se li fa el dash
  DASH_DESTINATION = getDashDestination()
  
  -- 2) calcular les posicions de les 2 plataformes a fer-lis Dash
  --    per poder saber si hi estem a prop, i en tal cas, tirar particules
  --    de chof i tambe poder desactivar-les (que no es pintin ni tinguin colisio)
  -- NOTA: ja es fa implicit en el getDashDestination aixi reaprofitem calculs
  
  -- 2.5) żactivar camera per a que segueixi la trajectoria del boss??
  
  -- 3) activar el dash mode i posar RUN_SPEED a el doble o el triple?
  --    aixo tambe hauria d'activar el megaParticules de chof a saco mentres esta
  --    en dash mode :D (com quan el player corre sobre l'aigua)
  setDashMode(entity)
  
  FIRST_PLATFORM_DESTROYED = false
  SECOND_PLATFORM_DESTROYED = false
  
  -- OPCIONAL
  -- posar FEEDBACK VISUAL a les lakeplants que es destruiran
  activateVisualFeedBack()

  
end


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

  -- just in case, activem el turn to de manera que la entity
  -- sempre miri cap a les plataformes
  
  if( FIRST_PLATFORM_DESTROYED ) then
    entity:turnTo( SECOND_PLATFORM_TO_DASH )
  else
    entity:turnTo( FIRST_PLATFORM_TO_DASH )
  end
  
  -- moure's a velocitat de dash
  entity:moveFront( DASH_SPEED )
  
  -- comprobar que estiguem a distancia de colisio amb les plataformes
  -- i si les DUES plataformes han estat destruides, canviem d'estat
  local platforms_destroyed = checkPlatformsDestroyed(entity)
    
  if( platforms_destroyed ) then
    changeEntityState( entity:ID(), OUT_STATE )
  end
  
  if( timer_particles:isOutOfTime() ) then
    throwParticles( "octopus_appear_water_big", entity:getPosition(), NULL );
  end
  
end


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

  -- remove animation cycle
  removeAnimationCycle( entity:ID(), ANIMATION_NAME )
  
  unsetDashMode(entity)
  
  selectNextDash()
  
end


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


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