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

dofile( "../../Assets/Scripts/util_math.lua" )

--[[
Vine docking is a three part process:
1) identify that the vine is within docking distance and dock the vine
2) once docked spawn the next vine
3) thicken the vine to full girthyness
--]]

--------------------------------------------------------------------------------
-- Vars, part 1
--------------------------------------------------------------------------------

local myData = { 
                 musicLayer  = 1,                             -- Not needed for default
                 musicAction = -1,                            -- NO_OP
                 musicFile   = "../../Assets/Sounds/wind.mp3" -- Lame default sound
               }
local collisionOrb = {}
local finished         = false
local collidedWithVine = false
local guidingVine      = false
local embiggeningVine  = true
local vineID           = -1

local PLAYER = Player
local LANTERN = PLAYER:gLantern()

local ENTITY_GetMyPointer   = Entity.GetMyPointer
local ENTITY_GetID          = Entity.GetID
local ENTITY_SPT_GiveNumber = Entity.SPT_GiveNumber
local ENTITY_SHR_gPosition  = Entity.SHR_gPosition


--------------------------------------------------------------------------------
-- What happens when we've collided?
--------------------------------------------------------------------------------

local function Collided()
  collidedWithVine = true

  vineID = Global:gVineID()

  Global:NewVine( myData.spawnX, myData.spawnY, myData.spawnZ )
  
  LANTERN:SPT_GiveEntity( "lastDock", Entity:GetMyPointer() )
  LANTERN:SPT_GiveNumber( "minVineDist", myData.minLen )
  LANTERN:SPT_GiveNumber( "maxVineDist", myData.maxLen )
  
  Entity:VIS_SetLightRadius( .1 )
  
  Global:MusicLayer( myData.musicLayer, myData.musicAction, myData.musicFile )
end


--------------------------------------------------------------------------------
-- Tractor beam!
--------------------------------------------------------------------------------

local function Guiding()
  if( not guidingVine ) then
    Global:PlaySound2D( "../../Assets/Sounds/vine_dock.mp3" )
    
  end
  guidingVine = true
  return Global:DockingProcedure(myData.pos.x, myData.pos.y, myData.pos.z)
end


--------------------------------------------------------------------------------
-- Vars, part 2
--------------------------------------------------------------------------------

Entity:SHR_Refresh( myData, true, true, false, false )
Entity:SPT_RefreshNumbers( myData )
Entity:SPT_RefreshStrings( myData )


--calculate the position of the orb that checks collision with the vine
myData.rot.x = DEG_TO_RAD * myData.rot.x
myData.rot.y = DEG_TO_RAD * myData.rot.y
myData.rot.z = DEG_TO_RAD * myData.rot.z

local cx = math.cos(myData.rot.x)
local sx = math.sin(myData.rot.x)
local cy = math.cos(myData.rot.y)
local sy = math.sin(myData.rot.y)
local cz = math.cos(myData.rot.z)
local sz = math.sin(myData.rot.z)

--these are the columns of the concatinated rotation matrix for this entity
--local xPrime = { x = cy * cz,                 y = -cy * sz,                z = sy }
--local yPrime = { x = sx * sy * cz + cx * sz,  y = -sx * sy * sz + cx * cz, z = -sx * cy }
--local zPrime = { x = -cx * sy * cz + sx * sz, y = cx * sy * sz + sx * cz,  z = cx * cy }

--for shits and giggles, let's use the negated rows!
local xPrime = { x = -cy * cz, y = -sx * sy * cz - cx * sz, z = cx * sy * cz - sx * sz }
--local yPrime = { x = cy * sz,  y = sx * sy * sz - cx * cz,  z = sx * cy }
--local zPrime = { x = -sy,      y = sx * cy,                 z = -cx * cy }

collisionOrb = vec3.add(myData.pos, vec3.multiply(xPrime, 6))


--------------------------------------------------------------------------------
-- I'm in ur loops
--------------------------------------------------------------------------------
--[[
while( 1 ) 
do
  coroutine.yield()

  Global:AddDebugLine(myData.pos.x, myData.pos.y, myData.pos.z, collisionOrb.x, collisionOrb.y, collisionOrb.z)
  
  Entity:SPT_RefreshNumbers( myData )
  if( myData.forcedPenetration )
  then
    Collided()
    myData.forcedPenetration = nil
    
  end
  

  --we haven't collided yet, so we are either guiding or nowhere near the vine
  if( not collidedWithVine ) 
  then
    local pos    = Global:gVineEndPoint()
    local distSq = vec3.magnitudeSq( vec3.subtract( collisionOrb, pos ) )
    if( guidingVine or distSq < 36 )
    then
      --if we are done guiding the vine we have collided with it
      if( not Guiding() ) then
        Collided()
        
      end
    
    --the vine is close but not quite there, so make sure they don't get stuck
    elseif( distSq < 225 ) then
      Global:JustABitMoreVine()
      
    end
    
  --we have spawned the new vine so now we need to make the docked one thicker
  elseif( embiggeningVine ) then
    embiggeningVine = Global:EmbiggenVine( vineID )
    
  end
  
end
--]]
