------ All content © 2008 DigiPen (USA) Corporation, all rights reserved. ------
-- Author: Hamza M. Hutchinson
-- Updated: 04/03/2008


--------------------------------------------------------------------------------
-- Fuctions!
-- This might look redundant, but avoids costly global lookup
--------------------------------------------------------------------------------

local ENTITY = Entity
local PLAYER = Player

local GLOBAL_TimeElapsed             = Global.TimeElapsed
local GLOBAL_gVineEndPoint           = Global.gVineEndPoint
local GLOBAL_IsGameButtonPressed     = Global.IsGameButtonPressed
local GLOBAL_ControllerConnected     = Global.ControllerConnected
local GLOBAL_CreateEntity            = Global.CreateEntity
local GLOBAL_CreateEntityAt          = Global.CreateEntityAt
local GLOBAL_DeleteEntityByPtr       = Global.DeleteEntityByPtr
local GLOBAL_ClampCameraZoomMinMax   = Global.ClampCameraZoomMinMax
local GLOBAL_TurnOnOffFFSound        = Global.TurnOnOffFFSound
local GLOBAL_FindEntityByName        = Global.FindEntityByName
local GLOBAL_FireflySpawnMsg         = Global.FireflySpawnMsg

local ENTITY_SHR_sPosition           = Entity.SHR_sPosition
local ENTITY_SHR_gPosition           = Entity.SHR_gPosition
local ENTITY_SHR_sVelocity           = Entity.SHR_sVelocity
local ENTITY_SHR_gVelocity           = Entity.SHR_gVelocity

local ENTITY_SPT_GiveNumber          = Entity.SPT_GiveNumber
local ENTITY_SPT_GiveString          = Entity.SPT_GiveString
local ENTITY_SPT_RefreshNumbers      = Entity.SPT_RefreshNumbers

local ENTITY_GetMyPointer            = Entity.GetMyPointer



--------------------------------------------------------------------------------
-- Var Par
--------------------------------------------------------------------------------
local myData      = {}
local LANTERN     = Player:gLantern()
local ASTER       = Player:gAster()
local MOON        = GLOBAL_FindEntityByName( "Moon", false )
local ZOOM        = 700

local elapsedTime = 0
local tText       = 0
local tJump       = 0
local tSlides     = 0

local vX = 0
local vY = 0
local vZ = 0

local pX = 0
local pY = 0
local pZ = 0

local WAITING_FOR_JUMP    = 1
local WAITING_FOR_LANDING = 2
local WAITING_FOR_CREDITS = 3

local currentState = WAITING_FOR_JUMP



--------------------------------------------------------------------------------
-- What's your function, conjunction junction...
--------------------------------------------------------------------------------
local function AddText( text )
  local len = string.len( text )

  local CHAR_WIDTH = ( 0.6 / 40.0 ) * len
  local CHAR_TIME = 200 * len
  tText = tText + CHAR_TIME

  Global:AddPopupTextToQueue( text, CHAR_TIME, ( 1 - CHAR_WIDTH ) / 2, .75 )

end

----------------------------------------------------------------------------
----------------------------------------------------------------------------
local textIndx = 0
local function SubmitText()
  elapsedTime = elapsedTime + GLOBAL_TimeElapsed()

  if( elapsedTime >= tText )
  then
    elapsedTime = 0
    tText = 0

    if( textIndx == 0 )
    then
      textIndx = 2
      AddText( "It is now time to make the jump ..." )

    else
      textIndx = 0
      if( GLOBAL_ControllerConnected() )
      then
        AddText( "Press (A) to jump ..." )
      else
        AddText( "Press SPACE to jump ..." )
      end

    end

  end
  
end

----------------------------------------------------------------------------
----------------------------------------------------------------------------
local function LaunchAsterToTheTopOfTheMoon() --some wicked magic... ask if me (Hamza) if your interested
    local AsterPos = ENTITY_SHR_gPosition( ASTER )

    local dx  = myData.MoonX - AsterPos.x
    local dy  = myData.MoonY + myData.MoonR - AsterPos.y
    local dz  = myData.MoonZ - AsterPos.z
    local dy1 = dy + 30
    dy1	      = ClampMin( dy1, 30 )
    local dy2 = dy1 - dy

    local tUp  = math.sqrt( dy1 / 5 )
    tJump      = tUp + math.sqrt( dy2 / 5 )
    local vy   = 10 * tUp
    local dist = math.sqrt( dx * dx + dz * dz )
    local vxz  = dist / tJump

    vX = vxz * dx / dist
    vY = vy
    vZ = vxz * dz / dist

    pX = AsterPos.x
    pY = AsterPos.y
    pZ = AsterPos.z

    --ENTITY_SHR_sVelocity( ASTER, vX, vY, vZ )

    GLOBAL_CreateEntity( "../../Assets/Xml/entities/e_VineFire.XML" )
    GLOBAL_CreateEntityAt( "../../Assets/Xml/entities/e_ParticleFlash.XML", AsterPos.x, AsterPos.y, AsterPos.z, 0, 0, 0 )

end

----------------------------------------------------------------------------
----------------------------------------------------------------------------
local function StartTheEndingSlideshow()
  local slideshow = GLOBAL_CreateEntity( "../../Assets/Xml/entities/game_Slideshow.xml" )

  local tSlide = 8000
  local tTransition = 1500
  local slideCount = 4

  ENTITY_SPT_GiveString( slideshow, "ShowName", "OutroSlides0" )
  ENTITY_SPT_GiveNumber( slideshow, "TimePerSlide", tSlide )
  ENTITY_SPT_GiveNumber( slideshow, "TransitionTime", tTransition )
  ENTITY_SPT_GiveNumber( slideshow, "SlideCount", slideCount )
  
  tSlides = slideCount * tSlide + ( slideCount + 1 ) * tTransition

  ENTITY_SPT_GiveString( slideshow, "Text1", " " )
  ENTITY_SPT_GiveNumber( slideshow, "Height1", .3 ) -- Height does not have to be specified
  ENTITY_SPT_GiveString( slideshow, "Text2", "A journey has many hills and valleys" )
  ENTITY_SPT_GiveNumber( slideshow, "Height2", .3 ) -- Height does not have to be specified
  ENTITY_SPT_GiveString( slideshow, "Text3", "Gazing at the Moon under foot" )
  ENTITY_SPT_GiveNumber( slideshow, "Height3", .7 ) -- Height does not have to be specified
  ENTITY_SPT_GiveString( slideshow, "Text4", "Remembering the beginning of this dream" )
  ENTITY_SPT_GiveNumber( slideshow, "Height4", .7 ) -- Height does not have to be specified

end

----------------------------------------------------------------------------
----------------------------------------------------------------------------
local function PlaceAsterOnTheMoon()
  local moon = GLOBAL_FindEntityByName( "Moon", false )
  local mPos = ENTITY_SHR_gPosition( moon )
  local aster = GLOBAL_FindEntityByName( "Aster", false )
  ENTITY_SHR_sPosition( aster, mPos.x + 10, mPos.y + 10, mPos.z )

end

----------------------------------------------------------------------------
----------------------------------------------------------------------------
local function TellAsterAndLanternTheEndIsOver()
  ENTITY_SPT_GiveNumber( LANTERN, "endSequence", 1 )
  ENTITY_SPT_GiveNumber( ASTER, "endSequence", 1 )
end

--------------------------------------------------------------------------------
-- Loop
--------------------------------------------------------------------------------
local moonswitched = false
while( 1 ) 
do
  coroutine.yield()

  ENTITY = Entity

  ENTITY_SPT_RefreshNumbers( ENTITY, myData )
  
  if( currentState == WAITING_FOR_JUMP ) --Waiting for the jump
  then
    if( GLOBAL_IsGameButtonPressed( 0 ) )
    then
      currentState = WAITING_FOR_LANDING
      elapsedTime  = 0

      --ENTITY_SPT_GiveNumber( MOON, "SpawnFF", 1 )
      GLOBAL_FireflySpawnMsg( myData.MoonR + 15, 0.0, 0.0,
                              myData.MoonX, myData.MoonY, myData.MoonZ,
                              100,
                              2 )

      LaunchAsterToTheTopOfTheMoon()
      Global:SetShadow( 0 )

    else
      SubmitText()

      local VineEnd = GLOBAL_gVineEndPoint()
      ENTITY_SHR_sPosition( ASTER, VineEnd.x, VineEnd.y, VineEnd.z )

    end

  elseif( currentState == WAITING_FOR_LANDING ) --Waiting for downward velocity
  then
    GLOBAL_ClampCameraZoomMinMax(ZOOM, ZOOM)

    local dt = GLOBAL_TimeElapsed() / 1000

    vY = vY - 10 * dt

    pX = pX + vX * dt
    pY = pY + vY * dt
    pZ = pZ + vZ * dt

    ENTITY_SHR_sPosition( ASTER, pX, pY, pZ )

    elapsedTime = elapsedTime + dt
    if( elapsedTime > tJump )
    then
      currentState = WAITING_FOR_CREDITS
      elapsedTime  = 0

      TellAsterAndLanternTheEndIsOver()
      StartTheEndingSlideshow()

    end

  elseif( currentState == WAITING_FOR_CREDITS )
  then
    GLOBAL_ClampCameraZoomMinMax(ZOOM, ZOOM)

    local dt = GLOBAL_TimeElapsed()
    elapsedTime = elapsedTime + dt
    if( elapsedTime > tSlides )
    then
      currentState = nil
      elapsedTime  = 0

      GLOBAL_CreateEntity( "../../Assets/Xml/entities/game_CreditsMan.xml" )
      GLOBAL_TurnOnOffFFSound( false )

    elseif( elapsedTime > tSlides / 2 ) and ( not moonswitched )
    then
      moonswitched = true
      local moon = GLOBAL_FindEntityByName( "Moon", false )
      moon:SHR_sRotation( 90, 0, 0 )

    end

  end

end
