-----------------------------------------------------------------------------------
-- GAME OBJECTS HELPERS -----------------------------------------------------------
-----------------------------------------------------------------------------------

function Object(name)
    assert(play_field and play_field:HasObject(name))
    return play_field:GetObject(name)
end
-----------------------------------------------------------------------------------

function HasObject(name)
    assert(play_field)
    return play_field:HasObject(name)
end
-----------------------------------------------------------------------------------

function ObjectVisible(name, is_visible)
    assert(play_field)
    Object(name):SetVisible(is_visible)
end
-----------------------------------------------------------------------------------

function ObjectsVisible(names, is_visible)
    assert(play_field)
    
    if type(names)=='table' then
        for i,v in pairs(names) do
            ObjectVisible(v, is_visible)
        end
    else
        Object(names):SetVisible(is_visible)
    end
end
-----------------------------------------------------------------------------------

function ObjectOpacity(name, op, time)
    time = time or 0
    
    if type(name)=='table' then
        for i, v in pairs(name) do
            ObjectOpacity(v, op, time)
        end
    else
        if time == 0 then
            Object(name):SetOpacity(op)
        else
            Object(name):ChangeOpacity(Object(name):GetOpacity(), op, time)
        end
    end
end
-----------------------------------------------------------------------------------

function FadeShow(...)
    local objects = {...}
    for _, name in pairs(objects) do
        Object(name):Show()
        Object(name):ChangeOpacity(0, 1, CHANGE_OBJECT_OPACITY)
    end
end
-----------------------------------------------------------------------------------

function FadeHide(...)
    local objects = {...}
    for _, name in pairs(objects) do
        Object(name):ChangeOpacity(1, 0, CHANGE_OBJECT_OPACITY)
    end
end
-----------------------------------------------------------------------------------
function HideObjects(...)
    local objects = {...}
    for _, name in pairs(objects) do
        Object(name):Hide()
    end
end
-----------------------------------------------------------------------------------

function ShowObjects(...)
    local objects = {...}
    for _, name in pairs(objects) do
        Object(name):Show()
    end
end
-----------------------------------------------------------------------------------

function CGameObject:Move(dx, dy, time)
    local af = CreateAnimationEffector()
    af:SetDestroysOnEnd(true)
    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 CGameObject:MoveTo(x, y, time, delay)
    delay = delay or 0

    local af = CreateAnimationEffector()
    af:SetDestroysOnEnd(true)
    af:AttachTo(self)
    af:SetKey(_TRACK_X, delay, self:GetX())
    af:SetKey(_TRACK_Y, delay, self:GetY())
    af:SetKey(_TRACK_X, delay+time, x)
    af:SetKey(_TRACK_Y, delay+time, y)
    af:Play()
    
    return af
end
-----------------------------------------------------------------------------------

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

function CGameObject:RotateTo(angle, time)
    local af = CreateAnimationEffector()
    af:SetDestroysOnEnd(true)
    af:AttachTo(self)
    af:SetKey(_TRACK_A, 0.0, self:GetAngle())
    af:SetKey(_TRACK_A, time, angle)
    af:Play()
end
-----------------------------------------------------------------------------------

function CGameObject:ChangeScale(start, finish, time)
    local af = CreateAnimationEffector()
    af:SetDestroysOnEnd(true)
    af:AttachTo(self)
    af:SetKey(_TRACK_S, 0.0, start)
    af:SetKey(_TRACK_S, time, finish)
    af:Play()
    
    return af
end
-----------------------------------------------------------------------------------

function CGameObject:ChangeScaleX(start, finish, time)
    local af = CreateAnimationEffector()
    af:SetDestroysOnEnd(true)
    af:AttachTo(self)
    af:SetKey(_TRACK_SX, 0.0, start)
    af:SetKey(_TRACK_SX, time, finish)
    af:Play()
    
    return af
end
-----------------------------------------------------------------------------------

function CGameObject:ChangeScaleY(start, finish, time)
    local af = CreateAnimationEffector()
    af:SetDestroysOnEnd(true)
    af:AttachTo(self)
    af:SetKey(_TRACK_SY, 0.0, start)
    af:SetKey(_TRACK_SY, time, finish)
    af:Play()
    
    return af
end
-----------------------------------------------------------------------------------

function CGameObject:ChangeOpacity(start, finish, time, delay)
    delay = delay or 0
    
    local af = CreateAnimationEffector()
    af:SetDestroysOnEnd(true)
    af:AttachTo(self)
    af:SetKey(_TRACK_O, 0.0 + delay, start)
    af:SetKey(_TRACK_O, time + delay, finish)
    af:Play()
    
    return af
end
-------------------------------------------------------------------------------
function CGameObject:SetParam(color, opacity, is_visible, ignore_on_test_point)
    if ignore_on_test_point == nil then
        ignore_on_test_point = false
    end

    self:GetAnimation():SetColor(color)
    self:SetOpacity(opacity)
    self:SetVisible(is_visible)
        
    if ignore_on_test_point and not play_field:IsIgnoredOnTestPoint(obj_name) then
        play_field:IgnoreOnTestPoint(obj_name)
    end
end
-------------------------------------------------------------------------------
function CGameObject:MarkWithPS()
    self:AddParticleSystem('data/ParticleSystem/ObjectHighlight.psi',
                           'SolveLaterObjectParticle')
end
--------------------------------------------------------------------------------
function CGameObject:Highlight()
	local HIGHLIGHT_DURATION  = 5
    local highlight_particles = self:AddParticleSystem('data/ParticleSystem/Glint.psi',
                           'HOActionParticle', true)
    highlight_particles:AffectedByOpacity(true)
                           
	local magic_effect = CreateAnimationEffector()
	magic_effect:AttachTo(highlight_particles)
	magic_effect:SetKey(_TRACK_O, 0, 0)
	magic_effect:SetKey(_TRACK_O, HIGHLIGHT_DURATION/2, 1)
	magic_effect:SetKey(_TRACK_O, HIGHLIGHT_DURATION, 0)
	magic_effect:Play()
	
	GetCurrentLevel().timer:Add(function() self:DeleteParticleSystem(0) end, HIGHLIGHT_DURATION)
end
--------------------------------------------------------------------------------