function lerp( a, b, delta )
	return (a * (1.0 - delta) + b * delta)
end
function normalize( a, b )
	local len = math.sqrt( a*a + b*b )
	return a/len, b/len
end

local heartsCorners = 
{
	-- florist1
	{
		{ 194, 60 },
		{ 366, 55 },
		{ 378, 250 },
		{ 205, 260 },
		{ 194, 60 },
	},
	-- salon1
	{
		{ 535, 46 },
		{ 710, 55 },
		{ 700, 250 },
		{ 526, 240 },
		{ 535, 46 },
	},
}

local heartsCenter = 
{
	-- florist1
	{ 290, 150 },
	-- salon1
	{ 618, 142 },
}

local heartCorners = heartsCorners[transitionScene]
local heartCenter = heartsCenter[transitionScene]

function DoTwinkles()
	local twinkMgr = root:CreateEmptyInstance( "twinkMgr" )
	twinkMgr.life = 4.0
	twinkMgr.radius = 400
	twinkMgr.particles = {}
	twinkMgr.particleIdx = 0
	twinkMgr:SetX( 0 )
	twinkMgr:SetY( 0 )
	function twinkMgr:OnUpdate()
		self.life = self.life - 1/60
		if self.life <= 0 then
			self:DeleteSelf()
		else
			-- create white particles a decreasing distance inwards from center
			for i=0, 1, 1 do
				local partOwner = self:CreateEmptyInstance( "partOwner" .. self.particleIdx )
				partOwner:SetRegistrationPoint( 8, 8 )
				local img = partOwner:CreateInstance( "Particles_StarSparkle.png", "particle" .. self.particleIdx )
				self.particleIdx = self.particleIdx + 1
				local randAngle = math.random( 0.0, 100 ) * math.pi * 0.02
				local delta = lerp( 1.0, 0.6, (1.0 - self.life/4) )
				--log( "randangle: " .. randAngle )
				partOwner:SetX( math.cos( randAngle ) * twinkMgr	.radius * delta + 400 )
				partOwner:SetY( math.sin( randAngle ) * twinkMgr.radius * delta + 300 )
				
				partOwner.time = 0.0
				function partOwner:OnUpdate()
					self.time = self.time + 1/60
					--self:SetOpacity( math.sin( self.time ) )
					self:SetScale( lerp( 1.0, 5.0, self.time/4 ), lerp( 1.0, 5.0, self.time/4 ) )
				end
			end
		end
	end
end

function DoFade()
	fadeTransitionOut = false
	local fadePlane = root:CreateEmptyInstance( "fadePlane" )
	fadePlane:CreateInstance( "whitePlane", "plane" )
	fadePlane.fadeInTime = 0.0
	fadePlane.fadeOutTime = 0.0
	fadePlane:SetOpacity( 0.0 )
	function fadePlane:OnUpdate()
		
		if ( fadeTransitionOut ) then
			-- fadeout
			self.fadeOutTime = self.fadeOutTime + 1/60
			if self.fadeOutTime >= 4 then
				self:DeleteSelf()
			else
				self:SetOpacity( math.min( (4-self.fadeOutTime)/8, 1 ) )
			end
		else
			-- fadein
			self.fadeInTime = self.fadeInTime + 1/60
			self:SetOpacity( math.min( self.fadeInTime/3, 1 ) )
		end
	end
end

function DoHearts()
	-- positions for heart particles
	local heartSections = 10
	local hearts = {}
	local heardSpeed = 0.75

	-- for each corner of heart area, trace a line of hearts
	local heardIdx = 0
	for hC in heartCorners do
		-- ignore last line
		if ( hC == table.getn( heartCorners ) ) then
			return
		end
		
		local lineStart = heartCorners[hC]
		local lineEnd = heartCorners[hC+1]
		
		for i=0,1,1/heartSections do
			-- get position f
			local x = lerp( lineStart[1], lineEnd[1], i )
			local y = lerp( lineStart[2], lineEnd[2], i )
			
			-- create heart
			local heart = root:CreateEmptyInstance( "heart" .. heardIdx )
			heart:CreateInstance( "small_heart.png", "heart" .. heardIdx )
			heardIdx = heardIdx + 1
			heart:SetX( x )
			heart:SetY( y )
			heart.life = 8.0
			function heart:OnUpdate()
				self.life = self.life - 1/60
				if self.life <= 0 then
					self:DeleteSelf()
				else
					-- fly out from center
					local x, y = self:GetX(), self:GetY()
					local dirX, dirY = x - heartCenter[1], y - heartCenter[2]
					dirX, dirY = normalize( dirX, dirY )
					--log( "dir: " .. dirX .. ", " .. dirY )
					self:SetX( x + dirX * heardSpeed )
					self:SetY( y + dirY * heardSpeed )
					self:SetOpacity( heart.life/8 )
				end
			end 
		end
	end
end

function LoadLevel()
	log("calling transition done" )
	TransitionDone()
end

function StartTransition()
	log( "start" )
	-- create transition object
	local transitionMgr = root:CreateEmptyInstance( "transitionMgr" )
	transitionMgr.time = 0
	transitionMgr.life = 8.5
	transitionMgr.states = 
	{
		{ 0.0, DoHearts },
		{ 0.25, DoTwinkles },
		{ 1.5, DoFade },
		{ 6.0, LoadLevel },
	}
	function transitionMgr:OnUpdate()
		local oldTime = self.time
		self.time = self.time + 1/60
		if self.time > self.life then
			self:DeleteSelf()
		else
			for s in self.states do
				local state = self.states[s]
				if oldTime <= state[1] and self.time > state[1] then
					state[2]()
				end
			end
		end
	end
end

StartTransition()