-- Items to use
-- 15_wolf

function OnSceneLoad(screen)
    LoadData(screen)
    DefaultOnSceneLoad('data/Scenes/Minigames/14_puzzle.lua', 'quest', 'data/Scenes/14_Corridor_Main.lua')

    OBJECTS_AMOUNT = 9
    Objects = {}
    for i = 1, OBJECTS_AMOUNT do
        CreateObjectInArray(i)
        if i == 5 then
            Objects[i].Entity:SetOpacity(0)
        end
    end 
    
    first_time = true
    
    RegisterToolApplyInfo('15_wolf', 'target_area', nil, nil,   function(tool_name)
                                                                    play_field:GetObject('target_area'):SetVisible(false);
                                                                    Objects[5].Entity:ChangeOpacity(0, 1, 1)
                                                                    TimerDoString('StartPuzzleMiniGame()', 2, play_field:GetTimer())
                                                                    
                                                                    PlaySound('14_PlacePict');
                                                                    
                                                                    game_state.level_mode = 'mini_game';
                                                                    play_field:GetLevelScreen():GetPanel():SetMode(PM_MINIGAME)
                                                                    ShowMonolog('C_14_WOLF_WAS_APPLY_HINT', 'C_14_WOLF_WAS_APPLY_HINT')
                                                                end,
                                                                function(tool_name)
                                                                    play_field:GetObject('target_area'):SetVisible(false)
                                                                    Objects[5].Entity:SetOpacity(1)
                                                                    
                                                                    for i = 1, OBJECTS_AMOUNT do
                                                                        if HasGameState(game_state.scene_path .. i) then
                                                                            local idx = tonumber(GetGameState(game_state.scene_path .. i):Get(0))
                                                                            RemoveGameState(game_state.scene_path .. i)
                                                                            local delta = idx - Objects[i].CurrentIndex
                                                                            if delta <= 0 then
                                                                                delta = delta + OBJECTS_AMOUNT
                                                                            end
                                                                            RotateCard(i, Objects[i].CurrentIndex, delta)
                                                                            first_time = false
                                                                        end
                                                                    end
                                                                    TimerDoString('StartPuzzleMiniGame()', 1, play_field:GetTimer())
                                                                    game_state.level_mode = 'mini_game';
                                                                    play_field:GetLevelScreen():GetPanel():SetMode(PM_MINIGAME)
                                                                    ShowMonolog('C_14_WOLF_WAS_APPLY_HINT', 'C_14_WOLF_WAS_APPLY_HINT')
                                                                end,
                                                                function()
                                                                    ShowMonolog('C_14_WOLF_BUTTON_APPLY_HINT', 'C_14_WOLF_BUTTON_APPLY_HINT');
                                                                end);
                                                                
    if game_state.level_mode ~= 'mini_game' then
        ShowMonolog('C_14_WOLF_BUTTON_APPLY_HINT', 'C_14_WOLF_BUTTON_APPLY_HINT');                                                                
    end

    lock_cards = true    
end

function CreateObjectInArray(index)
    Objects[index] = {}
    Objects[index].Index = index            -- index in object array
    Objects[index].RightIndex = index       -- index to win
    Objects[index].CurrentIndex = index     -- current image index
    local anim = CreateAnimation('data/Texture/Minigames/14_puzzle/'..index..'.jpg',0,0,148,148,1,0)
    anim:SetHotSpot(74,74)
    anim:SetBlendMode(2)
    anim:SetColor('0xFFFFFFFF')
    local posx = index % 3
    if posx == 0 then
        posx = 3
    end
    local posy = math.ceil(index / 3)
    play_field:CreateObject('cards_'..index,anim,133 + posx*148, 92 + posy*148,110,0,1,1)
    Objects[index].Entity = play_field:GetObject('cards_'..index)
end

function StartPuzzleMiniGame()
    if first_time then
        ShuffleCards()
    end
    LockCards(false)
    DeleteProtectArea()
end

function DeleteProtectArea()
    play_field:GetObject('area'):SetVisible(false)
end

function IsCompleted()
    for i = 1, OBJECTS_AMOUNT do
        if Objects[i].RightIndex ~= Objects[i].CurrentIndex then
            return false
        end
    end
    
    FinishGame()
    return true
end

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

function CreateNewCard(iCard, new_index)
    local anim = CreateAnimation('data/Texture/Minigames/14_puzzle/'..new_index..'.jpg',0,0,148,148,1,0)
    anim:SetHotSpot(74,74)
    anim:SetBlendMode(2)
    anim:SetColor('0xFFFFFFFF')
    local posx = iCard % 3
    if posx == 0 then
        posx = 3
    end
    local posy = math.ceil(iCard / 3)
    play_field:CreateObject('cards_'..iCard,anim,133 + posx*148, 92 + posy*148,110,0,1,1)
    Objects[iCard].Entity = play_field:GetObject('cards_'..iCard)
    Objects[iCard].CurrentIndex = new_index
    
    local af = CreateAnimationEffector()
    af:AttachTo(Objects[iCard].Entity)
    af:SetMode(_ANIM_FWD)
    af:SetKey(_TRACK_SX, 0, 0.1)
    af:SetKey(_TRACK_SX, 0.1, 1)
    af:Play()
    TimerDoString('LockCards(false)', 0.1, play_field:GetTimer())
end

function RotateCard(iCard, current_index, delta)
    if not delta then
        delta = 1
    end
    if delta == 0 then
        return
    end
    local new_index = (current_index + delta) % OBJECTS_AMOUNT
    if new_index == 0 then
        new_index = OBJECTS_AMOUNT
    end
    local af = CreateAnimationEffector()
    af:AttachTo(Objects[iCard].Entity)
    af:SetMode(_ANIM_FWD)
    af:SetKey(_TRACK_SX, 0, 1)
    af:SetKey(_TRACK_SX, 0.1, 0.1)
    af:Play()
    TimerDoString('play_field:DeleteObject("'..Objects[iCard].Entity:GetName()..'")', 0.1, play_field:GetTimer())
    
    TimerDoString('CreateNewCard('..iCard..', '..new_index..')', 0.1, play_field:GetTimer())
end

function SkipMiniGame()
    if game_state.minigame_completed == true then
        return
    end

    LockCards(true)
    for i = 1, OBJECTS_AMOUNT do
        if Objects[i].RightIndex ~= Objects[i].CurrentIndex then
            local delta = Objects[i].RightIndex - Objects[i].CurrentIndex
            if delta <= 0 then
                delta = delta + OBJECTS_AMOUNT
            end
            RotateCard(i, Objects[i].CurrentIndex, delta)
        end
    end
    game_state.minigame_completed = true
    --TimerDoString('IsCompleted()', 0.5, play_field:GetTimer())
    TimerDoString('FinishGame();', 0.5, play_field:GetTimer())
end

function ShuffleCards()
    math.randomseed(os.clock())
    
    for i = 1, OBJECTS_AMOUNT do
        local num_rot = math.random(OBJECTS_AMOUNT)
        RotateCard(i, Objects[i].CurrentIndex, num_rot)
    end
end

function LockCards(lock)
    lock_cards = lock
end

function OnSceneFree(screen)
    DefaultOnSceneFree()
    FreeData(screen)
end

function OnUpdate(dt)
    DefaultOnUpdate(dt)
end

function OnAllItemsFound()
    DefaultOnAllItemsFound()
end

function OnLose()
    DefaultOnLose()
end

function OnExit()
    DefaultOnExit()
end

function OnClose()
    DefaultOnClose()
end

function OnObjectMouseEnter(object)
    DefaultOnObjectMouseEnter(object)
        
    local obj_name = object:GetName()
    obj = GetObjectByName(obj_name)
    if obj and not game_state.minigame_completed and not lock_cards then
        LockCards(true)
        RotateCard(obj.Index, obj.CurrentIndex)
        
        PlaySound('14_ChangePict');
        
        TimerDoString('IsCompleted()', 0.2, play_field:GetTimer())
    end
end

function OnObjectMouseLeave(object)
    DefaultOnObjectMouseLeave(object)
end

function OnObjectMouseDown(object)
    local is_wrong_click = not DefaultOnObjectMouseDown(object)
    local obj_name = object:GetName()
    local pf = play_field
    
    DefaultOnObjectMouseDownProcessed(is_wrong_click);
end

function FinishGame()
    LockCards(true)
    game_state.minigame_completed = true
    for i = 1, OBJECTS_AMOUNT do
        Objects[i].Entity:ChangeOpacity(1, 0, 1)
    end
    if not HasGameState('MiniGameCompleted', '14_puzzle') then
        AddGameState('MiniGameCompleted', '14_puzzle');
    end
    if not HasGameState('ClosedScene', game_state.scene_path) then
        AddGameState('ClosedScene', game_state.scene_path);
    end
    
    play_field:GetObject('zasov'):Move(-150, 0, 2)
    play_field:GetObject('shesterenka_1'):Rotate(M_PI + 0.5, 2)
    PlaySound('14_LockOpening');
    
    TimerDoString('StartLevel("'..game_state.parent_scene..'")', 3, play_field:GetTimer())
end

function OnObjectMouseUp(object)
    DefaultOnObjectMouseUp(object)
end

function OnObjectFound(object)
    DefaultOnObjectFound(object)
end

function OnToolFound(tool)
    DefaultOnToolFound(tool)
end

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

function OnObjectReachPanel(object)
    DefaultOnObjectReachPanel(object)
end

function OnButtonPress(title)
    DefaultOnButtonPress(title)
end

function OnMouseMove(previous_pos, current_pos)
    DefaultOnMouseMove(previous_pos, current_pos)
end

function OnSetTool(tool)
    DefaultOnSetTool(tool)
end

function LevelLoaded(level)
end

function OnSceneDestroy(playfield)
    DefaultOnSceneDestroy(playfield)
    for i = 1, OBJECTS_AMOUNT do
        if HasGameState(game_state.scene_path .. i) then
            RemoveGameState(game_state.scene_path .. i)
        end
        AddGameState(game_state.scene_path .. i, tostring(Objects[i].CurrentIndex))
    end
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/14_puzzle/background.jpg',0,0,1024,768,1,0)
	anim:SetHotSpot(512,384)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('BG',anim,512,384,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Scenes/Common/area.png',0,0,8,8,1,0)
	anim:SetHotSpot(4,4)
	anim:SetBlendMode(2)
	anim:SetColor('0x01FFFFFF')
	screen:CreateObject('area',anim,512,384,120,0,85,85)
	local anim = CreateAnimation('data/Texture/Scenes/Common/area.png',0,0,8,8,1,0)
	anim:SetHotSpot(4,4)
	anim:SetBlendMode(2)
	anim:SetColor('0x01FFFFFF')
	screen:CreateObject('target_area',anim,430,385,130,0,18,18)
	local anim = CreateAnimation('data/Texture/Minigames/14_puzzle/zasov.png',0,0,551,210,1,0)
	anim:SetHotSpot(275,105)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('zasov',anim,701,402,103,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/14_puzzle/skoba.png',0,0,214,373,1,0)
	anim:SetHotSpot(107,186)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('skoba',anim,920,384,105,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/14_puzzle/shesterenka_1.png',0,0,81,81,1,0)
	anim:SetHotSpot(40,40)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('shesterenka_1',anim,725,262,107,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/14_puzzle/frontset.png',0,0,666,587,1,0)
	anim:SetHotSpot(333,293)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('frontset',anim,583,387,108,0,1,1)
end

function FreeData(screen)
end
-- CLEAR_ON_SAVE_END
