---------------------------------------------------------------------------------
-- Helpers effect - functions generating tables with keys for custom animations
---------------------------------------------------------------------------------

HelpersEffect = {
	createSplineBezier = function(start_point, start_handle, end_point, end_handle, num_points)
        num_points = num_points-1
        local result = {}
        
        local dT = 1.0 / num_points
        local x0 = start_point.x
        local y0 = start_point.y
        local xH0 = start_handle.x
        local yH0 = start_handle.y
        local x1 = end_point.x
        local y1 = end_point.y
        local xH1 = end_handle.x
        local yH1 = end_handle.y

        local t = 0.0
        for i = 0, num_points do
            local oT = 1.0 - t
            local a0 = math.pow(oT, 3.0)
            local a1 = 3.0 * t * oT * oT
            local a2 = 3.0 * t * t * oT
            local a3 = math.pow(t, 3.0)

            local x = a0 * x0 + a1 * xH0 + a2 * xH1 + a3 * x1
            local y = a0 * y0 + a1 * yH0 + a2 * yH1 + a3 * y1
            
            t = t + dT

            table.insert(result, {x = x, y = y})
        end
        
        return result
    end,
    -------------------------------------------------------------------------------

    createSplineBezierEffector = function(start_point, start_handle, end_point, end_handle, num_points, move_time, move_delay)
        local effectorKeys = HelpersEffect.createSplineBezier(start_point, start_handle, end_point, end_handle, num_points)
        local effector = CreateAnimationEffector()
        local t = 0
        local dT = 1 / num_points
        move_delay = move_delay or 0

        for _, keys in ipairs(effectorKeys) do
            effector:setKey(_TRACK_Y, move_delay + t * move_time, keys.y)
            effector:setKey(_TRACK_X, move_delay + t * move_time, keys.x)

            t = t + dT
        end

        return effector
    end,
    -------------------------------------------------------------------------------

    createShakeEffector = function( start_pos, amplitude_x, amplitude_y, time_step, cycled, delay, double_amplitude ) 
        amplitude_x = amplitude_x or 0
        amplitude_y = amplitude_y or 0
        local mode = cycled and ( _ANIM_FWD + _ANIM_LOOP ) or _ANIM_FWD
        delay = delay or 0
        time_step = time_step or 0.1
        
        if double_amplitude then
            start_pos.x = start_pos.x - amplitude_x
            start_pos.y = start_pos.y - amplitude_y 
            amplitude_x = amplitude_x * 2
            amplitude_y = amplitude_y * 2
        end 
        
        local effector = CreateAnimationEffector()
        effector:setDestroysOnEnd( true )
        effector:setMode( mode )
        
        effector:setKey( _TRACK_X, delay, start_pos.x )
        effector:setKey( _TRACK_Y, delay, start_pos.y )
        effector:setKey( _TRACK_X, delay + time_step, start_pos.x + amplitude_x )
        effector:setKey( _TRACK_Y, delay + time_step, start_pos.y + amplitude_y )
        effector:setKey( _TRACK_X, delay + ( time_step * 2 ), start_pos.x )
        effector:setKey( _TRACK_Y, delay + ( time_step * 2 ), start_pos.y )
        
        return effector
    end,
    -------------------------------------------------------------------------------

    createCyclicRotateEffector = function( start_angle, cycle_time, is_clockwise )
        start_angle = start_angle or 0  
        cycle_time = cycle_time or 1
        delay = delay or 0
        local dest_angle = is_clockwise
            and start_angle + M_TWO_PI
            or start_angle + ( -M_TWO_PI ) 

        local effector = CreateAnimationEffector()
        effector:setMode( _ANIM_FWD + _ANIM_LOOP )

        effector:setKey( _TRACK_A, 0, start_angle )
        effector:setKey( _TRACK_A, cycle_time, dest_angle )

        return effector
    end
}
