NAME_STATE_MINIGAME = 'Minigame___';

function LoadMiniGames(path)
    if IsExistMiniGame() then
        return
    end

--   TimerDo(play_field:GetTimer(), 0.01, function()
                                            SaveStatesPlayField()
                                            DefaultOnMiniGameLoad(path)
                                            
                                            game_state.hide_time_minigame = 1.5
                                            game_state.minigame_complete = false
                                            game_state.continue_mode = 0
                                            
                                            local screen_mini_game = load_screen(path)
                                            game_state.screen_mini_game = screen_mini_game
                                            game_state.path_mini_game = path
                                            screen_mini_game:SetLayer(LAYER_MINIGAME)
                                            play_field:SetEnabled(false)
                                            play_field:GetLevelScreen():GetPanel():Stop()
                                            play_field:GetLevelScreen():GetPhone():Stop()
                                            
                                            game_state.bttn_continue = CreateMiniGameContinueBttn( Vector(920, 738), 'ContinueMiniGame', screen_mini_game)
                                            game_state.bttn_continue:Hide()
                                            game_state.bttn_continue:Stop()
                                                                                        
                                            game_state.bttn_skip = CreateMiniGameSkipBttn( Vector(962, 60), 'SkipMiniGame', screen_mini_game)
                                            game_state.bttn_skip:SetVisible(false)
                                            game_state.bttn_skip:Go()
                                            TimerDo(screen_mini_game:GetTimer(), MINIGAME_SKIP_TIME, SkipMinigameEnable)
                                                                                        
                                            game_state.panel_hint = CreateHintPanel(Vector(100, 100), screen_mini_game)
                                                                                                                                    
                                            AddGameState(NAME_STATE_MINIGAME..path, 'load')
                                            
                                            TimerDo(screen_mini_game:GetTimer(), TIME_START_LEVEL, ShowMiniGameHelp)
--  end)
end

function SetContinueMode(mode)
    -- 1 - continue button, 0 - simple exit, other - need take item
    mode = mode or 0
    game_state.continue_mode = mode
end

function OnCompletedGame()
    if game_state and game_state.screen_mini_game then
        local path_mini_game = game_state.path_mini_game
        game_state.screen_mini_game:ScreenDestroy()
        game_state.screen_mini_game:SetAllowInput(false)
        game_state.screen_mini_game = nil
        ReloadStatesPlayField()
        play_field:SetEnabled(true)
        play_field:GetLevelScreen():GetPanel():Go()
        play_field:GetLevelScreen():GetPhone():Go()
        play_field:GainFocus()
        
        AddGameState(NAME_STATE_MINIGAME..path_mini_game, 'complete')
		OnMinigameCompleted(path_mini_game)

        if play_field:GetLevelScreen():HasPhotoTasksOnly() then
		    play_field:GetLevelScreen():GetPhone():SetVisibleTool()
		end
    end
end

function IsMiniGamePlay(path)
    return HasGameState(NAME_STATE_MINIGAME..path, 'complete')
end

function IsExistMiniGame()
    if game_state and game_state.screen_mini_game then
        return true
    end
    
    return false
end

function SaveStatesPlayField()
    play_field.game_state = nil
    play_field.game_state = game_state
    play_field.custom_cursors = nil
    play_field.custom_cursors = custom_cursors
    custom_cursors = {}
end

function DefaultOnMiniGameLoad(path)
    game_state = {}
    game_state.scene_path = path;
    game_state.locker = ReferenceCounter()
    game_state.active_zone = nil
    game_state.locked_objects = {}
    game_state.active_objects = {}
    game_state.state = GetGameManager():GetCurrPlayer():GetGameState()
    
    SetCursor( GetCursorArrow() )
end

function SkipMinigameEnable()
    if game_state.bttn_skip == nil or game_state.bttn_skip.anim:IsVisible() == false then
        return;
    end

    -- Create particle
    local points = {}
    local particle = CreateAnimation('data/Texture/Effect/particles_2.png',32,64,32,32,1,0)
	particle:SetHotSpot(16,16)
	particle:SetBlendMode(0)
	particle:SetColor('0x01FFFFFF')
	game_state.screen_mini_game:CreateObject('Skip_particles',particle,512,384,1000,0,1,1)
	    
	local radius = 55.0
		    
	for i = 1, 4 do
	    -- Create pixel for attach
        points[i] = CreateAnimation('data/Texture/Scenes/Common/pixel.jpg',0,0,8,8,1,0)
        points[i]:SetHotSpot(4,4);
        points[i]:SetBlendMode(0)
	    points[i]:SetColor('0x01FFFFFF')
	    -- Calculate coord and init variables
        local x = radius * math.cos(M_PI_OVER_2*i)
        local y = radius * math.sin(M_PI_OVER_2*i)
        local keys_num = 60
        local angle = M_TWO_PI/keys_num
        local time = 0.0
        local delay = 0.03
        -- Create object and particles
	    game_state.screen_mini_game:CreateObject('skip_pixel_'..i, points[i], x, y, 550,0,1,1)
	    points[i].obj = game_state.screen_mini_game:GetObject('skip_pixel_'..i)
	    points[i].obj:AttachTo(game_state.bttn_skip)
	    points[i].particle = game_state.screen_mini_game:GetObject('Skip_particles')
        points[i].obj:AddParticleSystem('data/ParticleSystem/Skip.psi', points[i].particle:GetAnimationPtr())
        -- Calculate keys for rotate animation
        local af = CreateAnimationEffector()
        x = points[i].obj:GetX()
        y = points[i].obj:GetY()
        for j = 1, keys_num do
            af:SetKey(_TRACK_X, time, x)
            af:SetKey(_TRACK_X, time + delay, x*math.cos(angle) - y*math.sin(angle))
            af:SetKey(_TRACK_Y, time, y)
            af:SetKey(_TRACK_Y, time + delay, x*math.sin(angle) + y*math.cos(angle))
            x = x*math.cos(angle) - y*math.sin(angle)
            y = x*math.sin(angle) + y*math.cos(angle)
            time = time + delay
        end
        af:AttachTo(points[i].obj)
        af:Play()
        points[i].effector = af
        --
        points[i].obj:AttachTo(game_state.bttn_skip)
        TimerDo(game_state.screen_mini_game:GetTimer(), 1.1*keys_num*delay, StopParticlesAnim)
    end
    
    game_state.bttn_skip.anim:Stop();
    game_state.bttn_skip.anim:SetVisible(false)
    game_state.bttn_skip:SetVisible(true)
end

function StopParticlesAnim()
    for i = 1, 4 do
        if game_state.screen_mini_game then
            game_state.screen_mini_game:GetObject('skip_pixel_'..i):Hide()
        end
    end
end

function ReloadStatesPlayField()
    game_state = {};
    custom_cursors = {};
    custom_cursors = play_field.custom_cursors;
    game_state = play_field.game_state;
end

function MiniGameCompleted(delay)
    delay = delay or 0.01
    -- Button skip -----------------------------------------------------------------------------
    if game_state.bttn_skip then 
        game_state.bttn_skip:SetEnabled(false) 
        game_state.bttn_skip.anim:Stop()
    end
    TimerDo(game_state.screen_mini_game:GetTimer(), delay,  function ()
                                                                if game_state.bttn_skip then
                                                                    game_state.bttn_skip:SetEnabled(false)
                                                                    local af = CreateAnimationEffector()
                                                                    af:AttachTo(game_state.bttn_skip)
                                                                    af:SetKey(_TRACK_O, 0.0, game_state.bttn_skip:GetOpacity())
                                                                    af:SetKey(_TRACK_O, game_state.hide_time_minigame, 0.0)
                                                                    af:Play()
                                                                    TimerDo(game_state.screen_mini_game:GetTimer(), game_state.hide_time_minigame, function ()
                                                                                            if game_state.bttn_skip then
                                                                                                game_state.bttn_skip:Hide()    
                                                                                            end
                                                                                                                                                    end)
                                                                end
                                                            end)
    -- Hint panel -------------------------------------------------------------------------------
    if game_state.panel_hint then 
        game_state.panel_hint.help_bttn:SetEnabled(false)
        game_state.panel_hint.menu_bttn:SetEnabled(false)
    end
    TimerDo(game_state.screen_mini_game:GetTimer(), delay,  function ()
                                                                if game_state.panel_hint then
                                                                    game_state.panel_hint.help_bttn:SetEnabled(false)
                                                                    game_state.panel_hint.menu_bttn:SetEnabled(false)
                                                                    local af = CreateAnimationEffector()
                                                                    af:AttachTo(game_state.panel_hint)
                                                                    af:SetKey(_TRACK_O, 0.0, game_state.panel_hint:GetOpacity())
                                                                    af:SetKey(_TRACK_O, game_state.hide_time_minigame, 0.0)
                                                                    af:Play()
                                                                    TimerDo(game_state.screen_mini_game:GetTimer(), game_state.hide_time_minigame, function ()
                                                                                        if game_state.panel_hint then
                                                                                            game_state.panel_hint:Hide()   
                                                                                        end
                                                                                                                                                    end)
                                                                end
                                                            end)
    -- 1 - continue button, 0 - simple exit, other - need take item ----------------------------
    if game_state.continue_mode == 0 then
        TimerDo(game_state.screen_mini_game:GetTimer(), delay, PlayMinigameFinalAnim)
        TimerDo(game_state.screen_mini_game:GetTimer(), delay + 4.0, OnCompletedGame)
    elseif game_state.continue_mode == 1 then
        TimerDo(game_state.screen_mini_game:GetTimer(), delay,  function ()
                                                                    if game_state.bttn_continue then
                                                                        game_state.bttn_continue:Show()
                                                                        game_state.bttn_continue:Go()        
                                                                    end
                                                                end)
    else
        -- complete minigame after take specific game object on scene
    end
    ---------------------------------------------------------------------------------------------
    game_state.minigame_complete = true
end

function CreateHintPanel(pos, listener)
    -- Hint background
    local back = CreateAnimation('data/Texture/GUI/Panel/panel_mg.png',0,0,218,73,1,0)
    back:SetHotSpot(109,36)
	game_state.screen_mini_game:CreateObject('hint_back', back, 107, 733, 450, 0, 1, 1)
	
	local hint_panel = game_state.screen_mini_game:GetObject('hint_back')
	hint_panel:AttachTo(game_state.screen_mini_game)
	-- Menu button load
	local mb_up = CreateAnimation('data/Texture/GUI/Panel/menu_bttn_panel.png',0,0,88,40,1,0)
	mb_up:SetHotSpot(44,20)
	local mb_over = CreateAnimation('data/Texture/GUI/Panel/menu_bttn_panel.png',0,40,88,40,1,0)
	mb_over:SetHotSpot(44,20)
	local mb_down = CreateAnimation('data/Texture/GUI/Panel/menu_bttn_panel.png',0,80,88,40,1,0)
	mb_down:SetHotSpot(44,20)
	-- Help button load
	local hb_up = CreateAnimation('data/Texture/GUI/Panel/help_bttn_panel.png',0,0,52,47,1,0)
	hb_up:SetHotSpot(26,24)
	local hb_over = CreateAnimation('data/Texture/GUI/Panel/help_bttn_panel.png',0,47,52,47,1,0)
	hb_over:SetHotSpot(26,24)
	local hb_down = CreateAnimation('data/Texture/GUI/Panel/help_bttn_panel.png',0,94,52,47,1,0)
	hb_down:SetHotSpot(26,24)
	-- Create buttons and attach to parent
	local menu_button = CreateButton(mb_up, mb_over, mb_down, 'MenuButtonMinigame', listener)
	menu_button:SetHotKey(HGEK_ESCAPE)
	menu_button:SetXY(-42, 3)
	menu_button:SetZ(5)
	menu_button:AttachTo(hint_panel)
	hint_panel.menu_bttn = menu_button
	local help_button = CreateButton(hb_up, hb_over, hb_down, 'HelpButtonMinigame', listener)
	help_button:SetXY(30, 3)
	help_button:SetZ(5)
	help_button:AttachTo(hint_panel)
	hint_panel.help_bttn = help_button
	
	return hint_panel
end

function CreateMiniGameSkipBttn(pos, message, listener)
    -- Button states
    local up = CreateAnimation('data/Texture/GUI/Button/Skip/button_skip.png',0,0,119,113,1,0)
	up:SetHotSpot(60,57)
    local over = CreateAnimation('data/Texture/GUI/Button/Skip/button_skip.png',0,113,119,113,1,0)
    over:SetHotSpot(60,57)
    local down = CreateAnimation('data/Texture/GUI/Button/Skip/button_skip.png',0,113,119,113,1,0)
    down:SetHotSpot(60,57)
	local button = CreateButton(up, over, down, message, listener)
	-- Background
	local back = CreateAnimation('data/Texture/GUI/Button/Skip/button_skip_back.png',0,0,119,113,1,0)
	back:SetHotSpot(60,57)
	game_state.screen_mini_game:CreateObject('skip_back', back, 0, 0, -1, 0, 1, 1)
	game_state.screen_mini_game:GetObject('skip_back'):AttachTo(button)
	button.background = game_state.screen_mini_game:GetObject('skip_back')
	-- Anim (set fps here!!!)
	local anim = CreateAnimation('data/Texture/GUI/Button/Skip/button_skip_anim.png',0,0,71,71,7,7/MINIGAME_SKIP_TIME)
	anim:SetHotSpot(36,36)
	game_state.screen_mini_game:CreateObject('skip_anim', anim, -1, -3, 2, 0, 1, 1)
	game_state.screen_mini_game:GetObject('skip_anim'):AttachTo(button)
	button.anim = game_state.screen_mini_game:GetObject('skip_anim')
		
	button:AttachTo(listener)
	button:SetX(pos.x)
	button:SetY(pos.y)
    button:SetZ(500)
	return button
end

function CreateMiniGameContinueBttn(pos, message, listener)
    local button = create_button_ex(listener, 'data/Texture/GUI/Button/button_continue.png', message, pos.x, pos.y, 500)
    return button
end

function RegisterMiniGame(path, function_play)
    local minigame = {}
    minigame.path = path
    minigame.function_play = function_play

    table.insert(game_state.register_minigame, minigame)
--[[
    -- Проверка на запуск
    if  HasGameState(NAME_STATE_MINIGAME..path, 'load') and 
        not HasGameState(NAME_STATE_MINIGAME..path, 'complete')
    then
        PlayRegisterMiniGame(path)
    end
]]
end

function CheckRegisterMiniGame()
    if IsExistMiniGame() then
        return
    end
    
    -- Проверка на запуск
    for i, v in ipairs(game_state.register_minigame) do
        local path = v.path
        if  HasGameState(NAME_STATE_MINIGAME..path, 'load') and 
            not HasGameState(NAME_STATE_MINIGAME..path, 'complete')
        then
            PlayRegisterMiniGame(path)
            break
        end
    end -- for i, v in ipairs(game_state.register_minigame) do
end

function PlayRegisterMiniGame(path)
    if IsExistMiniGame() then
        return
    end

    for i, v in ipairs(game_state.register_minigame) do
        if v.path == path then
            v.function_play()
            break
        end
    end
end

function DefaultMinigameOnLostFocus()
    if game_state.screen_mini_game then
        game_state.screen_mini_game:Stop()
    end
end

function DefaultMinigameOnGainFocus()
    if game_state.screen_mini_game then
        game_state.screen_mini_game:Go()
    end
end

function DefaultMinigameOnButtonPress(title)
    PlaySound("button_press")

    if title == 'SkipMiniGame' then
        OnSkipMiniGame()
        return
    end
    
    if title == 'ContinueMiniGame' then
        OnCompletedGame()
        return
    end
    
    if title == 'MenuButtonMinigame' then
        local screen = CreateInGameMenu()
        screen:SetXY(-200, 0)
        return
    end
    
    if title == 'HelpButtonMinigame' then
        ShowMiniGameHelp()
        return
    end    
end