------------------------------------------------------------------------------
-- 
function auxBlendShowTransparent(gameObject, duration)
	gameObject:SetOpacity(0.0);
	gameObject:SetVisible(true);
	gameObject:GetAnimation():SetColor('0xFFFFFFFF');
	gameObject:ChangeOpacity(0.0, 1.0, duration);
end

------------------------------------------------------------------------------
-- 
function auxAttachInPlace(object, parentObject, diableChildAboveTest)
	local x,y,z = object:GetScrX(), object:GetScrY(), object:GetScrZ();
	local parentZ = parentObject:GetScrZ();

	object:AttachTo(parentObject);
    object:SetScrXY(x,y);

    if (diableChildAboveTest ~= false) then
        assert(z > parentZ and "Child objects must be placed above their parent one in common");
    end
	object:SetZ(z - parentZ);
end

------------------------------------------------------------------------------
-- 
function GameObject:Move(dx, dy, time)
    local af = CreateAnimationEffector()--AnimationEffector()
    af:AttachTo(self)
    af:SetKey(_TRACK_X, 0.0, self:GetX())
    af:SetKey(_TRACK_Y, 0.0, self:GetY())
    af:SetKey(_TRACK_X, time, self:GetX() + dx)
    af:SetKey(_TRACK_Y, time, self:GetY() + dy)
    af:Play()
end

function GameObject:Rotate(dangle, time)
    local af = CreateAnimationEffector()--AnimationEffector()
    af:AttachTo(self)
    af:SetKey(_TRACK_A, 0.0, self:GetAngle())
    af:SetKey(_TRACK_A, time, self:GetAngle() + dangle)
    af:Play()
end

function GameObject:Scale(dscale, time)
    local af = CreateAnimationEffector()--AnimationEffector()
    af:AttachTo(self)
    af:SetKey(_TRACK_S, 0.0, self:GetAngle())
    af:SetKey(_TRACK_S, time, self:GetAngle() + dscale)
    af:Play()
end

function GameObject:ChangeOpacity(start, finish, time)
    local af = CreateAnimationEffector()--AnimationEffector()
    af:AttachTo(self)
    af:SetKey(_TRACK_O, 0.0, start)
    af:SetKey(_TRACK_O, time, finish)
    af:Play()
end

function GameObject:ChangeOpacityWithDelay(start, finish, time, delay)
    local af = CreateAnimationEffector()--AnimationEffector()
    af:AttachTo(self)
    af:SetKey(_TRACK_O, 0.0, start)
    af:SetKey(_TRACK_O, delay, start)
    af:SetKey(_TRACK_O, delay + time, finish)
    af:Play()
end

------------------------------------------------------------------------------
-- 
function auxStopAnimation(animationName, mode)
	assert(playField:HasObject(animationName) == true);

	local obj = playField:GetObject(animationName);
	if (mode ~= nil ) then
		obj:GetAnimation():SetMode(mode);
	end
	obj:GetAnimation():Stop();
end

------------------------------------------------------------------------------
-- 
function auxSetFibrillationEffector(gameObject, fadeAmount, duration)
	fadeAmount = (fadeAmount == nil and 0.04 or fadeAmount);
	duration = (duration == nil and 0.5 or duration);

	assert(fadeAmount < 1.0);

	local eff= CreateAnimationEffector();
	eff:AttachTo(gameObject);
	eff:SetMode(_ANIM_FWD + _ANIM_LOOP);

	eff:SetKey(_TRACK_O, 0.0, 1.0);
	eff:SetKey(_TRACK_O, duration *1.0/4.0, 1.0 - fadeAmount/2.0);
	eff:SetKey(_TRACK_O, duration *2.0/4.0, 1.0);
	eff:SetKey(_TRACK_O, duration *3.0/4.0, 1.0 - fadeAmount);
	eff:SetKey(_TRACK_O, duration *4.0/4.0, 1.0);
	eff:Play();
	return eff;
end

------------------------------------------------------------------------------
-- 
function auxSetLevitationEffector(gameObject, amplitudes, periods)
	assert(gameObject ~= nil and 
		   table.getn(amplitudes) == 2 and table.getn(periods) == 2);
	local eff = CreateAnimationEffector();
	eff:AttachTo(gameObject);
	eff:SetMode(_ANIM_FWD + _ANIM_PINGPONG);

	for i = 1,2 do
		local track = (i == 1 and _TRACK_X or _TRACK_Y);
		local pos = (i == 1 and gameObject:GetX() or gameObject:GetY());
		local amplitude, period = amplitudes[i], periods[i];
		if (amplitude ~= 0 and period ~= 0) then
			local step, stepCount = 0, 10;
			for t = M_PI/2.0, 3.0/2.0*M_PI, M_PI/stepCount do
				eff:SetKey(track, period * step/stepCount,	pos + amplitude * math.sin(t));
				step = step + 1;
			end
		end
	end
	eff:Play();
	return eff;
end

------------------------------------------------------------------------------
-- 
function auxZoomPlayField(scaleTo, zoomPoint, duration)
	assert(playField ~= nil and scaleTo ~= nil);
	zoomPoint = (zoomPoint ~= nil and zoomPoint or {SCREEN_WIDTH/2.0, SCREEN_HEIGHT/2.0});
	duration = (duration ~=nil and duration or 1.0);

	local scale = playField:GetScale();
	local pos = {playField:GetX(), playField:GetY()};
	local delta = {zoomPoint[1] - (zoomPoint[1] - pos[1]) * scaleTo/scale,
				   zoomPoint[2] - (zoomPoint[2] - pos[2]) * scaleTo/scale};

	eff = CreateAnimationEffector();
	eff:AttachTo(playField);
	eff:SetMode(_ANIM_FWD + _ANIM_NOLOOP);

	eff:SetKey(_TRACK_S, 0.0, 		scale);
	eff:SetKey(_TRACK_S, duration, 	scaleTo);

	eff:SetKey(_TRACK_X, 0.0, 		pos[1]);
	eff:SetKey(_TRACK_Y, 0.0, 		pos[2]);
	eff:SetKey(_TRACK_X, duration, 	delta[1]);
	eff:SetKey(_TRACK_Y, duration, 	delta[2]);

	eff:Play();
end
function auxZoomPlayFieldIn(scaleTo, zoomPoint, duration)
	assert(playField:GetScale() == 1.0);

	auxZoomPlayField(scaleTo, zoomPoint, duration);
end
function auxZoomPlayFieldOut(duration)
	local pScale = playField:GetScale();
	auxZoomPlayField(1.0, {playField:GetX()/(1.0 - pScale), playField:GetY()/(1.0 - pScale)}, duration);
end

------------------------------------------------------------------------------
-- 
function auxGetAnimationDuration(animation)
	assert(animation ~= nil);
	local frameCount, fps = animation:GetFrames(), animation:GetSpeed();
	return (fps > 0 and frameCount/fps or 0.0);
end
