function OnSceneLoad(screen)
    LoadData(screen)

    OBJECTS_AMOUNT = 16
    Objects = {}    -- class for drag objects  

    delta = 15  -- +/- area to match slot
    top_z = 120 -- max object's z-order  
    margin = 40
    
    -------------------------------------------------------------------------------------------------------------------------
    function Objects:UnlockObject()
        self.Lock = false
    end
    -------------------------------------------------------------------------------------------------------------------------
    function Objects:StartDrag()
        DragObject = self
        top_z = top_z + 1
        DragObject.Entity:SetZ(top_z)
        DragDeltaX = GetMousePos().x - DragObject.Entity:GetX()
        DragDeltaY = GetMousePos().y - DragObject.Entity:GetY()
    end
    -------------------------------------------------------------------------------------------------------------------------
    function Objects:IsInplace()
        local delta_x = self.RightPos.x - self.Entity:GetX()
        local delta_y = self.RightPos.y - self.Entity:GetY()
        if math.abs(delta_x) < delta and math.abs(delta_y) < delta then
            return true
        end
        
        return false
    end
    --------------------------------------------------------------------------------------------------------------------------

    g_screen = screen
    g_timer = screen:GetTimer()

    Objects.__index = Objects;
    for i = 1, OBJECTS_AMOUNT do
        CreateObjectInArray(i)
    end 
    
    ShuffleNotes()
end

function ShuffleNotes()
    local radius = 320
    local angle = M_TWO_PI/OBJECTS_AMOUNT
    for i = 1, OBJECTS_AMOUNT do
        local x = 524 + radius * math.cos(angle*i)
        local y = 384 + radius * math.sin(angle*i)
        Objects[i].Entity:SetXY(x, y)
        Objects[i].StartX = x
        Objects[i].StartY = y
    end
end

function CreateObjectInArray(index)
    Objects[index] = {}
    setmetatable(Objects[index], Objects);
    Objects[index].RightIndex = index
    Objects[index].Entity = g_screen:GetObject('Piece_'..index)
    Objects[index].RightPos = Vector(Objects[index].Entity:GetX(), Objects[index].Entity:GetY());
    Objects[index].Inplace = false
    Objects[index].Lock = false
end

function GetObjectByName(obj_name)
    for i = 1, OBJECTS_AMOUNT do
        if obj_name == Objects[i].Entity:GetName() then
            return Objects[i]
        end
    end
    
    return nil
end

function OnSceneFree()
    FreeData()
end

function OnScreenShown()
end

function ShowMiniGameHelp()
    CreateDialogMiniGameHelp('MINI_GAME_HELP_CIRCLE_PUZZLE')
end

function OnHiddenComics()
end

function OnUpdate(dt)
    UpdateDrag()
    DefaultOnUpdate(dt)
end

function OnLose()
end

function OnExit()
end

function OnObjectMouseEnter(object)
    DefaultOnObjectMouseEnter(object)
end

function OnObjectMouseLeave(object)
    DefaultOnObjectMouseLeave(object)
end

function UpdateDrag()
    if DragObject and not DragObject.Lock then
        local mouse_x = GetMousePos().x - DragDeltaX
        local mouse_y = GetMousePos().y - DragDeltaY
        if mouse_x < margin then
            mouse_x = margin
        elseif mouse_x > 1024 - margin then
            mouse_x = 1024 - margin
        end
        if mouse_y < margin then
            mouse_y = margin
        elseif mouse_y > 768 - margin then
            mouse_y = 768 - margin
        end
        DragObject.Entity:SetXY(mouse_x, mouse_y)
    end
end

function StopDrag()
    if DragObject then
        local obj = GetObjectByName(DragObject.Entity:GetName())
        if DragObject:IsInplace() and obj then
            obj.Entity:MoveTo(obj.RightPos.x, obj.RightPos.y, 0.2)
            obj.Inplace = true
            obj.Entity:SetZ(100)
            obj.Entity:GetAnimation():SetColor('0xFFFFFFFF')
            TimerDoString('IsCompleted()', 0.2, g_timer)
            
            local sound_mg_take_part = CreateSoundEntity('34_mg_insert_part')
            sound_mg_take_part:AttachTo(game_state.screen_mini_game)
            sound_mg_take_part:Play(false)
        else
            obj.Entity:MoveTo(obj.StartX, obj.StartY, 0.25)
            obj.Inplace = false
            obj.Lock = true
            TimerDo(g_timer, 0.2, Objects.UnlockObject, obj)
        end
        DragObject = nil
        DragDeltaX = nil
        DragDeltaY = nil
    end
end

function IsCompleted()
    for i = 1, OBJECTS_AMOUNT do
        if not Objects[i].Inplace then
            return false
        end
    end
    
    MiniGameCompleted(1.0)
        
    return true
end

function OnSkipMiniGame()
    if game_state.minigame_complete then
        return
    end
    
    for i = 1, OBJECTS_AMOUNT do
        Objects[i].Lock = true
        local delta_x = Objects[i].RightPos.x - Objects[i].Entity:GetX()
        local delta_y = Objects[i].RightPos.y - Objects[i].Entity:GetY()
        Objects[i].Entity:Move(delta_x, delta_y, 1)
        Objects[i].Entity:SetZ(100)
        TimerDoString('Objects[' .. i .. '].Entity:GetAnimation():SetColor("0xFFFFFFFF")', 1, g_timer)
        Objects[i].Inplace = true
    end
    
    MiniGameCompleted(1.5)
end

function OnObjectMouseDown(object)
    obj_name = object:GetName()
    local pf = play_field
    local is_wrong_click = true

    --is_wrong_click = DefaultOnObjectMouseDown(object);

    obj = GetObjectByName(obj_name)
    if obj and obj_name ~= 'Background' and not obj.Inplace and not obj.Lock then
        obj:StartDrag()
        local sound_mg_take_part = CreateSoundEntity('34_mg_take_part')
        sound_mg_take_part:AttachTo(game_state.screen_mini_game)
        sound_mg_take_part:Play(false)
    end
    
    return is_wrong_click;
end

function OnObjectMouseUp(object)
    StopDrag()
end

function OnObjectRightMouseDown(object)
end

function OnObjectRightMouseUp(object)
end

function OnObjectFound(object)
    DefaultOnObjectFound();
end

function OnToolFound(tool)
end

function OnToolApply(tool, object)
    DefaultOnToolApply(tool, object)
end

function OnButtonPress(title)
    DefaultMinigameOnButtonPress(title)
end

function OnMouseMove(previous_pos, current_pos)
end

function OnSetTool(tool)
end

function OnMinigameCompleted()
end

function OnLostFocus()
    DefaultMinigameOnLostFocus()
end

function OnGainFocus()
    DefaultMinigameOnGainFocus()
end

-- CLEAR_ON_SAVE_BEGIN
-- Do not edit code listed below (generated by the editor on each save)
function LoadData(screen)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Background.jpg',0,0,1024,768,1,0)
	anim:SetHotSpot(512,384)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Background',anim,512,384,95,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_1.jpg',0,0,44,74,1,0)
	anim:SetHotSpot(22,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_1',anim,434,541,101,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_2.jpg',0,0,74,44,1,0)
	anim:SetHotSpot(37,22)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_2',anim,493,556,102,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_3.jpg',0,0,74,44,1,0)
	anim:SetHotSpot(37,22)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_3',anim,567,556,103,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_4.jpg',0,0,44,74,1,0)
	anim:SetHotSpot(22,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_4',anim,523,497,104,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_5.jpg',0,0,44,74,1,0)
	anim:SetHotSpot(22,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_5',anim,523,423,105,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_6.jpg',0,0,44,74,1,0)
	anim:SetHotSpot(22,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_6',anim,524,349,106,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_7.jpg',0,0,44,74,1,0)
	anim:SetHotSpot(22,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_7',anim,523,275,107,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_8.jpg',0,0,74,44,1,0)
	anim:SetHotSpot(37,22)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_8',anim,464,289,108,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_9.jpg',0,0,74,44,1,0)
	anim:SetHotSpot(37,22)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_9',anim,582,289,109,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_10.jpg',0,0,44,74,1,0)
	anim:SetHotSpot(22,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_10',anim,641,274,110,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_11.jpg',0,0,44,74,1,0)
	anim:SetHotSpot(22,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_11',anim,685,305,111,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_12.jpg',0,0,44,74,1,0)
	anim:SetHotSpot(22,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_12',anim,448,230,112,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_13.jpg',0,0,74,44,1,0)
	anim:SetHotSpot(37,22)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_13',anim,582,408,113,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_14.jpg',0,0,74,44,1,0)
	anim:SetHotSpot(37,22)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_14',anim,464,363,114,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_15.jpg',0,0,74,44,1,0)
	anim:SetHotSpot(37,22)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_15',anim,390,363,115,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/34_circle_puzzle/Piece_16.jpg',0,0,44,74,1,0)
	anim:SetHotSpot(22,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Piece_16',anim,641,422,116,0,1,1)
end

function FreeData(screen)
end
-- CLEAR_ON_SAVE_END
