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


Global:StatTrack( 1, true )


local function calcDist2D( pos1, pos2 )
  return math.sqrt( ( ( pos1.x - pos2.x ) ^ 2 ) + ( ( pos1.z - pos2.z ) ^ 2 ) )
  
end


local function calculateCircle( theta, radius )
  return radius * math.sin( theta ), radius * math.cos( theta )
  
end


local ASSETS_XML = "../../Assets/Xml/"
local Aster = Player:gAster()
local myData = Entity:Data()
local file


local rod3 = Global:FindEntityByName( "rod03", false )
local rod3Pos = rod3:SHR_gPosition()


local lantern = nil


file = "island_parts/rod01.xml"
local rod1_1      = Global:CreateEntityAt( ASSETS_XML .. file, rod3Pos.x + -1.5, rod3Pos.y + -383, rod3Pos.z + -4, 0, 0, 0 )
-- Hackiest hack in the history of hacks
Editor:AttachToIsland( 0, rod1_1:GetMyPointer(), ASSETS_XML .. file )

local rod1_1Pos   = rod1_1:SHR_gPosition()


file = "island_parts/rod02.xml"
local rod2_1    = Global:CreateEntityAt( ASSETS_XML .. file, rod3Pos.x + 3, rod3Pos.y + -293, rod3Pos.z + 40, 0, 0, 0 )
-- Hackiest hack in the history of hacks
Editor:AttachToIsland( 0, rod2_1:GetMyPointer(), ASSETS_XML .. file )

local rod2_2    = Global:CreateEntityAt( ASSETS_XML .. file, rod3Pos.x + 84, rod3Pos.y + -267, rod3Pos.z + -49, 0, 0, 0 )
-- Hackiest hack in the history of hacks
Editor:AttachToIsland( 0, rod2_2:GetMyPointer(), ASSETS_XML .. file )

local rod2_3    = Global:CreateEntityAt( ASSETS_XML .. file, rod3Pos.x + -18, rod3Pos.y + -250, rod3Pos.z + -18, 0, 0, 0 )
-- Hackiest hack in the history of hacks
Editor:AttachToIsland( 0, rod2_3:GetMyPointer(), ASSETS_XML .. file )

local rod2_4    = Global:CreateEntityAt( ASSETS_XML .. file, rod3Pos.x + 0, rod3Pos.y + -160, rod3Pos.z + 0, 0, 0, 0 )
-- Hackiest hack in the history of hacks
Editor:AttachToIsland( 0, rod2_4:GetMyPointer(), ASSETS_XML .. file )

local rod2_1Pos = rod2_1:SHR_gPosition()
local rod2_2Pos = rod2_2:SHR_gPosition()
local rod2_3Pos = rod2_3:SHR_gPosition()
local rod2_4Pos = rod2_4:SHR_gPosition()


file = "island_parts/cloud01.xml"
local cloud1_1    = Global:CreateEntityAt( ASSETS_XML .. file, rod3Pos.x + 52, rod3Pos.y + -346, rod3Pos.z + 13, 0, 0, 0 )
-- Hackiest hack in the history of hacks
Editor:AttachToIsland( 0, cloud1_1:GetMyPointer(), ASSETS_XML .. file )

local cloud1_1Pos = cloud1_1:SHR_gPosition()
local cloud1_1Rot = cloud1_1:SHR_gRotation()


file = "island_parts/cloud02.xml"
local cloud2_1    = Global:CreateEntityAt( ASSETS_XML .. file, rod3Pos.x + -1.5, rod3Pos.y + -370, rod3Pos.z + -70, 0, 0, 0 )
-- Hackiest hack in the history of hacks
Editor:AttachToIsland( 0, cloud2_1:GetMyPointer(), ASSETS_XML .. file )
local cloud2_2    = Global:CreateEntityAt( ASSETS_XML .. file, rod3Pos.x + -24, rod3Pos.y + -358, rod3Pos.z + 47, 0, 0, 0 )
-- Hackiest hack in the history of hacks
Editor:AttachToIsland( 0, cloud2_2:GetMyPointer(), ASSETS_XML .. file )

local cloud2_1Pos = cloud2_1:SHR_gPosition()
local cloud2_2Pos = cloud2_2:SHR_gPosition()
local cloud2_1Rot = cloud2_1:SHR_gRotation()
local cloud2_2Rot = cloud2_2:SHR_gRotation()


file = "island_parts/circ48.xml"
local circ48_1    = Global:CreateEntityAt( ASSETS_XML .. file, rod3Pos.x + 0, rod3Pos.y + -304, rod3Pos.z + 0, 0, 0, 0 )
-- Hackiest hack in the history of hacks
Editor:AttachToIsland( 0, circ48_1:GetMyPointer(), ASSETS_XML .. file )

local circ48_1Rot = circ48_1:SHR_gRotation()
         
      
file = "island_parts/circ38.xml"
local circ38_1    = Global:CreateEntityAt( ASSETS_XML .. file, rod3Pos.x + 0, rod3Pos.y + -304, rod3Pos.z + 0, 0, 0, 0 )
-- Hackiest hack in the history of hacks
Editor:AttachToIsland( 0, circ38_1:GetMyPointer(), ASSETS_XML .. file )

local circ38_1Rot = circ38_1:SHR_gRotation()


file = "entities/e_DefaultLight.xml" 
local light1_1    = Global:CreateEntityAt( ASSETS_XML .. file, rod2_4Pos.x + 0, rod2_4Pos.y - 205, rod2_4Pos.z + 0, 0, 0, 0 )
-- Hackiest hack in the history of hacks
Editor:AttachToIsland( 0, light1_1:GetMyPointer(), ASSETS_XML .. file )

light1_1:VIS_SetLightColor( 1.0, 0.0, 0.0 )


local HIGH_DIF = 5
local HIGH_DIF2 = HIGH_DIF + 5
local HIGH_DIF3 = HIGH_DIF2 + 3
local HIGH_DIF4 = HIGH_DIF3 + 5
local LIGHT_DIF = 1.0 / HIGH_DIF2
local THETA_INCR = ( 2 * 3.14 ) / HIGH_DIF
local THETA_INCR2 = ( 2 * 3.14 ) / 3
local OK_GO = -1
local PLAYER_DIST = 400


local rod3AltPos     = rod3Pos
local rod1_1AltPos   = rod1_1Pos
local rod2_1AltPos   = rod2_1Pos
local rod2_2AltPos   = rod2_2Pos
local rod2_3AltPos   = rod2_3Pos
local rod2_4AltPos   = rod2_4Pos
local cloud1_1AltPos = cloud1_1Pos
local cloud2_1AltPos = cloud2_1Pos
local cloud2_2AltPos = cloud2_2Pos
local cloud1_1AltRot = cloud1_1Rot
local cloud2_1AltRot = cloud2_1Rot
local cloud2_2AltRot = cloud2_2Rot
local circ48_1AltRot = circ48_1Rot
local circ38_1AltRot = circ38_1Rot


local rod1_1Dist   = calcDist2D( rod1_1Pos, rod3Pos )
local rod2_1Dist   = calcDist2D( rod2_1Pos, rod3Pos )
local rod2_2Dist   = calcDist2D( rod2_2Pos, rod3Pos )
local rod2_3Dist   = calcDist2D( rod2_3Pos, rod3Pos )
local cloud1_1Dist = calcDist2D( cloud1_1Pos, rod3Pos )
local cloud2_1Dist = calcDist2D( cloud2_1Pos, rod3Pos )
local cloud2_2Dist = calcDist2D( cloud2_2Pos, rod3Pos )


local rods =
  { 
    [ 1 ] = { rod = rod1_1,
              rodPos = rod1_1Pos,
              rodAltPos = rod1_1AltPos,
              radius = rod1_1Dist,
              theta_incr = THETA_INCR + .3,
              theta = 0
            },
    [ 2 ] = { rod = rod2_1,
              rodPos = rod2_1Pos,
              rodAltPos = rod2_1AltPos,
              radius = rod2_1Dist,
              theta_incr = THETA_INCR + .3,
              theta = .3
            },
    [ 3 ] = { rod = rod2_2,
              rodPos = rod2_2Pos,
              rodAltPos = rod2_2AltPos,
              radius = rod2_2Dist,
              theta_incr = -THETA_INCR + .2,
              theta = 1
            },
    [ 4 ] = { rod = rod2_3,
              rodPos = rod2_3Pos,
              rodAltPos = rod2_3AltPos,
              radius = rod2_3Dist,
              theta_incr = -THETA_INCR + .6,
              theta = 1.7
            }
  }
  
local clouds = 
  { 
    [ 1 ] = { cloud = cloud1_1,
              cloudPos = cloud1_1Pos,
              cloudAltPos = cloud1_1AltPos,
              cloudRot = cloud1_1Rot,
              cloudAltRot = cloud1_1AltRot,
              vec = vec3.normalize( vec3.subtract( vec3.construct( rod3Pos.x, cloud1_1Pos.y, rod3Pos.z ), cloud1_1Pos ) ),
              vec_incr = cloud1_1Dist / HIGH_DIF,
              theta_incr = -THETA_INCR2,
              up_incr = 15
            },
    [ 2 ] = { cloud = cloud2_1,
              cloudPos = cloud2_1Pos,
              cloudAltPos = cloud2_1AltPos,
              cloudRot = cloud2_1Rot,
              cloudAltRot = cloud2_1AltRot,
              vec = vec3.normalize( vec3.subtract( vec3.construct( rod3Pos.x, cloud2_1Pos.y, rod3Pos.z ), cloud2_1Pos ) ),
              vec_incr = cloud2_1Dist / HIGH_DIF,
              theta_incr = THETA_INCR2,
              up_incr = 5
            },
    [ 3 ] = { cloud = cloud2_2,
              cloudPos = cloud2_2Pos,
              cloudAltPos = cloud2_2AltPos,
              cloudRot = cloud2_2Rot,
              cloudAltRot = cloud2_2AltRot,
              vec = vec3.normalize( vec3.subtract( vec3.construct( rod3Pos.x, cloud2_2Pos.y, rod3Pos.z ), cloud2_2Pos ) ),
              vec_incr = cloud2_2Dist / HIGH_DIF,
              theta_incr = -THETA_INCR2,
              up_incr = 10
            }
  }
  
local circs = 
  { 
    [ 1 ] = { circ = circ48_1,
              circRot = circ48_1Rot,
              circAltRot = circ48_1AltRot,
              theta_incr = 360 / HIGH_DIF
            },
    [ 2 ] = { circ = circ38_1,
              circRot = circ38_1Rot,
              circAltRot = circ38_1AltRot,
              theta_incr = -360 / HIGH_DIF
            }
  }


local function updateRods()
  local time = Global:TimeElapsed() / 1000
  local i = 2
  local j = table.maxn( rods )
  while( i <= j )
  do
    rods[ i ].theta = rods[ i ].theta + ( rods[ i ].theta_incr * ( time ) )
    local offX, offZ = calculateCircle( rods[ i ].theta, rods[ i ].radius )
    rods[ i ].rodAltPos.x = rod3Pos.x + offX
    rods[ i ].rodAltPos.z = rod3Pos.z + offZ
    
    i = i + 1
  end
    
end


local function updateClouds()
  local time = Global:TimeElapsed() / 1000
  local i = 1
  local j = table.maxn( clouds )
  while( i <= j )
  do
    local cloudPos = clouds[ i ].cloudAltPos
    local cloudOff = clouds[ i ].vec
    clouds[ i ].cloudAltPos = vec3.add( cloudPos, vec3.multiply( cloudOff, time * clouds[ i ].vec_incr ) )
    
    i = i + 1
  end
    
end


local function updateClouds2()
  local time = Global:TimeElapsed() / 1000
  local i = 1
  local j = table.maxn( clouds )
  while( i <= j )
  do
    clouds[ i ].cloudAltPos.y = clouds[ i ].cloudAltPos.y + ( time * clouds[ i ].up_incr )
    
    clouds[ i ].cloudAltRot.y = clouds[ i ].cloudAltRot.y + ( clouds[ i ].theta_incr * time * 10)
    clouds[ i ].cloud:SHR_sRotation( 0, clouds[ i ].cloudAltRot.y, 0 )
    
    i = i + 1
  end
    
end


local function updateCircs()
  local time = Global:TimeElapsed() / 1000
  local i = 1
  local j = table.maxn( circs )
  while( i <= j )
  do
    circs[ i ].circAltRot.y = circs[ i ].circAltRot.y + ( circs[ i ].theta_incr * time )
    circs[ i ].circ:SHR_sRotation( 0, circs[ i ].circAltRot.y, 0 )
  
    i = i + 1
  end
    
end


updateRods()
while( 1 ) 
do

  rod3:SHR_sPosition( rod3AltPos.x, rod3AltPos.y, rod3AltPos.z )
  rod2_4:SHR_sPosition( rod2_4AltPos.x, rod2_4AltPos.y, rod2_4AltPos.z )
  light1_1:SHR_sPosition( rod2_4AltPos.x, rod2_4AltPos.y + -35, rod2_4AltPos.z )
  
  local a = 1
  local b = table.maxn( rods )
  while( a <= b )
  do
    local pos = rods[ a ].rodAltPos
    rods[ a ].rod:SHR_sPosition( pos.x, pos.y, pos.z )
    
    a = a + 1
  end
  
  a = 1
  b = table.maxn( clouds )
  while( a <= b )
  do
    local pos = clouds[ a ].cloudAltPos
    clouds[ a ].cloud:SHR_sPosition( pos.x, pos.y, pos.z )
    
    a = a + 1
  end
  coroutine.yield()
  
  if( OK_GO < 0 ) and
    ( vec3.magnitude( vec3.subtract( Aster:SHR_gPosition(), rod3Pos ) ) < PLAYER_DIST ) 
  then
    Global:StatTrack( 1, false )
    OK_GO = 0
  
  end
  
  if( OK_GO >= 0 and OK_GO <= HIGH_DIF )
  then
    local time = Global:TimeElapsed() / 1000
    OK_GO = OK_GO + time
    
    updateRods()
    updateClouds()
    updateCircs()
    
  
  else
    local time = Global:TimeElapsed() / 1000
    local i = 1
    local j = table.maxn( circs )
    while( i <= j )
    do
      circs[ i ].circ:SHR_sRotation( 0, 0, 0 )
    
      i = i + 1
    end
   
  end
  
  if( OK_GO >= HIGH_DIF and OK_GO <= HIGH_DIF2 )
  then
    local time = Global:TimeElapsed() / 1000
    OK_GO = OK_GO + time
    
    rod3AltPos.y = rod3AltPos.y + ( time * -10 )
    rod2_4AltPos.y = rod2_4AltPos.y + ( time * -10 )
    
    light1_1:VIS_SetLightRadius( light1_1:VIS_GetLightRadius() + ( time * 50 ) )
    
  end
  
  if( OK_GO >= HIGH_DIF2 and OK_GO <= HIGH_DIF3 )
  then
    local time = Global:TimeElapsed() / 1000
    OK_GO = OK_GO + time
    
    rod2_4AltPos.y = rod2_4AltPos.y + ( time * -15 )
    
    updateClouds2()
    
  end
  
  if( OK_GO >= HIGH_DIF2 and OK_GO <= HIGH_DIF3 )
  then
    local time = Global:TimeElapsed() / 1000
    OK_GO = OK_GO + time
    
    rod2_4AltPos.y = rod2_4AltPos.y + ( time * -15 )
    
    updateClouds2()
    
  end
  
  if( OK_GO >= HIGH_DIF3 and OK_GO <= HIGH_DIF4 ) 
  then
    if( lantern == nil )
    then
      local pos = clouds[ 1 ].cloudAltPos
      file = "entities/e_StandingLantern.xml"
      lantern = Global:CreateEntityAt( ASSETS_XML .. file, pos.x, pos.y + 1, pos.z, 270, 0, 0 )
      lantern:SPT_GiveNumber( "lit", 0 )
      lantern:SPT_GiveNumber( "musicLayer", 1 )
      lantern:SPT_GiveNumber( "musicAction", 0 )
      lantern:SPT_GiveString( "musicFile", "../../Assets/Sounds/music_end_1.mp3" )
      lantern:SPT_GiveString( "poem", "Empty, starlit halls~ A secret, hallowed place~ Will echoes grow and move beyond?~ It seems so grand, this quiet night" )
      lantern:SPT_GiveNumber( "started1", 1 ) 
      -- Hackiest hack in the history of hacks
      Editor:AttachToIsland( 0, lantern:GetMyPointer(), ASSETS_XML .. file )             
    end
    
    local time = Global:TimeElapsed() / 1000
    OK_GO = OK_GO + time
    
    rod2_4AltPos.y = rod2_4AltPos.y + ( time * 8.5 )
    
    local pos = lantern:SHR_gPosition()
    pos.y = pos.y + ( time )
    lantern:SHR_sPosition( pos.x, pos.y, pos.z )
    
  end
  
end