--element_fly_animation = { elem_props = {} }

element_fly_animation.timeScale = 0.5
element_fly_animation.timeBeforeScaleMinus = 0.5
element_fly_animation.targetScale = 0.2
element_fly_animation.targetLengthStraigth = 20 -- distance to fly straight to target

element_fly_animation.gamefieldW = 1024
element_fly_animation.gamefieldH = 500
element_fly_animation.moveAccel = 690
element_fly_animation.rotateAccel = 400
element_fly_animation.restrictBorder = 50
element_fly_animation.moveSideMax = 200
element_fly_animation.moveSideFactor = 2

element_fly_animation.moveSideMaxInv = 400
element_fly_animation.moveSideFactorInv = 3

----------------------------------------------------------------------------------------------------
function element_fly_to_main_panel(elem)

	element_fly_animation.start(elem, get_target_pos_main_panel(elem), "set_element_visible(\""..elem:getName().."\", false)		delete_element_from_main_panel(\""..elem:getName().."\")")
	
	--set_parent_to_main_panel(elem, "TextPlace")	
	--set_character_parent(elem:getCharacter(), main_panel.parent:getElement("TextPlace"):getCharacter())
	--element_fly_animation.elem_props[elem:getName()].curPos = elem:getPos()
	
end

----------------------------------------------------------------------------------------------------
function element_fly_animation.init_elem_props(elem)
	if element_fly_animation.elem_props[elem:getName()] == nil then
		element_fly_animation.elem_props[elem:getName()] = {}
		
		local anim_props = element_fly_animation.elem_props[elem:getName()]
		
		anim_props.time = 0
		anim_props.scaleMinus = 0
		anim_props.initScale = elem:getScale()
		
		anim_props.curPos = elem:getPos()
		printVec2(anim_props.curPos)
		anim_props.initPos = elem:getPos()
		anim_props.startFlyEffect = 0
		anim_props.useSideMovement = 1
		
		if math.random() < 0.5 then
			anim_props.sideSignX = 1
		else
			anim_props.sideSignX = -1
		end
		
		if math.random() < 0.5 then
			anim_props.sideSignY = 1
		else
			anim_props.sideSignY = -1
		end
		
--[[ 		if anim_props.curPos.x < element_fly_animation.restrictBorder then
			anim_props.sideSignX = -1
		end
		
		if anim_props.curPos.x > element_fly_animation.gamefieldW  - element_fly_animation.restrictBorder then
			anim_props.sideSignX = 1
		end ]]
		if anim_props.flyToInventory then
			anim_props.sideSignX = 1
		else
			anim_props.sideSignX = -1
		end
		
		if anim_props.curPos.y < element_fly_animation.restrictBorder then
			anim_props.sideSignY = -1
		end
		
		if anim_props.curPos.y > element_fly_animation.gamefieldH  - element_fly_animation.restrictBorder then
			anim_props.sideSignY = 1
		end
		 
		anim_props.speed = 0
		anim_props.scale = 1
		anim_props.accel = element_fly_animation.moveAccel
		anim_props.rotSpeed = 0
		anim_props.curAngle = 0
		anim_props.rotAccel = element_fly_animation.rotateAccel
		anim_props.prevLen = 10000
		
		return anim_props
	else
		return element_fly_animation.elem_props[elem:getName()]		
	end
end

----------------------------------------------------------------------------------------------------
function element_fly_animation.start(elem, targetPos, scriptOnEnd)
	local anim_props = element_fly_animation.init_elem_props(elem)
	
	anim_props.targetPos = targetPos
	anim_props.scriptOnEnd = scriptOnEnd;
	
	start_effect_at(common.hidEffect, elem:getPos())
	console:print("pickup effect: "..common.hidEffect)
	anim_props.curPos = elem:getPos()
	
	elem:setEventHandler(eiUpdate, "element_fly_animation_update")
	
end

----------------------------------------------------------------------------------------------------
function element_fly_animation_update(elem, dt)

	local anim_props = element_fly_animation.elem_props[elem:getName()]
	
	anim_props.time = anim_props.time + dt
	
	local cur_pos = anim_props.curPos
	local dir = anim_props.targetPos - anim_props.curPos
	local lenToTarget  = dir:len()
	dir:norm()
	dir.x = dir.x * anim_props.speed * dt
	dir.y = dir.y * anim_props.speed * dt
	local deltaLen = lenToTarget  - anim_props.prevLen
	
	if lenToTarget < element_fly_animation.targetLengthStraigth then
		anim_props.useSideMovement = 0	
	end

	if lenToTarget < dir:len() then
		elem:setEventHandler(eiUpdate, "")
		--elem:setPos(anim_props.targetPos)
		exec_string(anim_props.scriptOnEnd)
	elseif anim_props.time < element_fly_animation.timeScale then
		element_fly_animation.update_scale(elem, dt, anim_props)
	else
		if anim_props.start_fly_sound == nil then
			anim_props.start_fly_sound = true
			play_sound("object_fly")
		end
		element_fly_animation.update_scale(elem, dt, anim_props)
		element_fly_animation.update_rotate(elem, dt, anim_props)
		element_fly_animation.update_translate(elem, dt, anim_props)
	end
end

----------------------------------------------------------------------------------------------------
function element_fly_animation_update_inv(elem, dt)

	local anim_props = element_fly_animation.elem_props[elem:getName()]
	
	anim_props.time = anim_props.time + dt
	
	local cur_pos = anim_props.curPos
	local dir = anim_props.targetPos - anim_props.curPos
	local lenToTarget  = dir:len()
	dir:norm()
	dir.x = dir.x * anim_props.speed * dt
	dir.y = dir.y * anim_props.speed * dt
	local deltaLen = lenToTarget  - anim_props.prevLen
	
	if lenToTarget < element_fly_animation.targetLengthStraigth then
		anim_props.useSideMovement = 0	
	end

	if lenToTarget < dir:len() then
		elem:setEventHandler(eiUpdate, "")
		elem:rotate(0)
		elem:setPos(anim_props.targetPos)
		exec_string(anim_props.scriptOnEnd)
	elseif anim_props.time < element_fly_animation.timeScale then
		element_fly_animation.update_scale(elem, dt, anim_props)
	else
		
		local needScale = anim_props.initScale - (anim_props.initScale - anim_props.targetScale) *
												 (anim_props.curPos.y - anim_props.initPos.y) / (anim_props.targetPos.y - anim_props.initPos.y)
												 
		if anim_props.start_fly_sound == nil then
			anim_props.start_fly_sound = true
			play_sound("object_fly")
		end
												 
		elem:scale(needScale)
		
		--element_fly_animation.update_rotate(elem, dt, anim_props)
		element_fly_animation.update_translate(elem, dt, anim_props)
	end
end

----------------------------------------------------------------------------------------------------
function element_fly_animation.update_rotate(elem, dt, anim_props)
	anim_props.curAngle = anim_props.curAngle + anim_props.rotSpeed * dt
	anim_props.rotSpeed = anim_props.rotSpeed + anim_props.rotAccel * dt
	elem:rotate(anim_props.curAngle)	
end

----------------------------------------------------------------------------------------------------
function element_fly_animation.update_scale(elem, dt, anim_props)
	local sc = 15
	
	local scale = anim_props.initScale + math.sin(anim_props.time * 8) / sc
	
	if anim_props.scaleMinus == 1 then
		local curLen = (anim_props.targetPos - anim_props.curPos):len()
		anim_props.scale = (anim_props.scaleBeforeShrink - element_fly_animation.targetScale) * curLen / anim_props.lengthInit + element_fly_animation.targetScale 
		scale = anim_props.scale
	end		
	
	anim_props.scale = scale

	if (anim_props.scaleMinus == 0 and anim_props.time > element_fly_animation.timeBeforeScaleMinus) then
		anim_props.scaleBeforeShrink = anim_props.scale
		anim_props.lengthInit = (anim_props.targetPos - anim_props.curPos):len()
		anim_props.scaleMinus = 1
	end
	
	elem:scale(scale)
end

----------------------------------------------------------------------------------------------------
function element_fly_animation.update_translate(elem, dt, anim_props)
	local cur_pos = anim_props.curPos
	
	local dir = anim_props.targetPos - cur_pos
	
	if anim_props.startFlyEffect == 0 then
		anim_props.startFlyEffect = 1
		elem:setEffect(common.hidFlyEffect )
	end
	
	local len = dir:len()
	anim_props.prevLen = len
	dir:norm()
	dir.x = dir.x * anim_props.speed * dt
	dir.y = dir.y * anim_props.speed * dt
	anim_props.speed = anim_props.speed + anim_props.accel * dt
	
	if anim_props.time > element_fly_animation.timeScale + 0.8 then
		anim_props.accel = anim_props.accel + 800 * dt
	end
	
	cur_pos = cur_pos + dir

	anim_props.curPos = cur_pos

	if anim_props.useSideMovement == 1 then
	
		local msf = element_fly_animation.moveSideFactor
		local msm = element_fly_animation.moveSideMax
		
		if anim_props.flyToInventory ~= nil then
			msf = element_fly_animation.moveSideFactorInv
			msm = element_fly_animation.moveSideMaxInv
		end
		
		cur_pos.x = cur_pos.x + math.sin((anim_props.time - element_fly_animation.timeScale) * msf) * msm * anim_props.sideSignX * dt
		cur_pos.y = cur_pos.y + math.cos((anim_props.time - element_fly_animation.timeScale + 1.5707) * msf) * msm * anim_props.sideSignY * dt
--		cur_pos.y = cur_pos.y + math.cos((anim_props.time - element_fly_animation.timeScale) * msf) * msm * anim_props.sideSignY * dt
		
	end		
	
	elem:setPos(cur_pos)
end

----------------------------------------------------------------------------------------------------
function return_back(name)
	local elem = get_current_level():getElementByName(name)
	elem:setEventHandler(4, "")
	elem:setPos(element_fly_animation.elem_props[elem:getName()].initPos)
end

----------------------------------------------------------------------------------------------------
function printVec2(v)
	console:print("Vector: x="..v.x.." y="..v.y)
end


element_alpha_props = {}

----------------------------------------------------------------------------------------------------
function element_appear_from_alpha(elem, time)

	element_alpha_props[elem:getName()] = {}
	local alpha_props = element_alpha_props[elem:getName()]
	set_element_visible(elem:getName(), true)
	set_element_alpha(elem:getName(), 0)
	
	alpha_props.time = 0
	alpha_props.timeEnd = time
	alpha_props.alpha = 0
	alpha_props.alphaDir = 1
	
	
	elem:setEventHandler(eiUpdate, "element_alpha_update")
end

----------------------------------------------------------------------------------------------------
function element_disappear_to_alpha(elem, time)

	element_alpha_props[elem:getName()] = {}
	local alpha_props = element_alpha_props[elem:getName()]
	set_element_visible(elem:getName(), true)
	set_element_alpha(elem:getName(), 1)
	
	alpha_props.time = 0
	alpha_props.timeEnd = time
	alpha_props.alpha = 1
	alpha_props.alphaDir = -1
	
	elem:setEventHandler(eiUpdate, "element_alpha_update")
end

----------------------------------------------------------------------------------------------------
function element_alpha_update(elem, dt)
	local alpha_props = element_alpha_props[elem:getName()]
	
	alpha_props.time = alpha_props.time + dt
	if alpha_props.time > alpha_props.timeEnd then
		
		if alpha_props.alphaDir == 1 then
			set_element_alpha(elem:getName(), 1)
		else
			set_element_alpha(elem:getName(), 0)
			set_element_visible(elem:getName(), false)
		end	
		
		elem:setEventHandler(eiUpdate, "")
	else
		if alpha_props.alphaDir == 1 then
			set_element_alpha(elem:getName(), alpha_props.time / alpha_props.timeEnd)
		else
			set_element_alpha(elem:getName(), 1 - alpha_props.time / alpha_props.timeEnd)
		end		
	end	
end