dofile('data/Scripts/Minigames/minigameScreen.lua');
-- miniGameScreen

------------------------------------------------------------------------------

function OnSceneLoad()
	play_field = miniGamePlayField;
    LoadData();
	play_field = nil;
    
    auxInitCubes();
    auxShufflePlayField(20);

	miniGamePlayField:IgnoreOnTestPoint('Layer_Glow');
	miniGamePlayField:IgnoreOnTestPoint('CenterStone_radial_glow');

   	miniGamePlayField:GetObject('Layer_Glow'):SetVisible(false);
   	miniGamePlayField:GetObject('CenterStone_radial_glow'):SetVisible(false);

   	miniGameState = {};
   	miniGameState.delayPeriod = 90.0;
   	miniGameState.timeElapsed = 0.0;
   	miniGameState.delayPeriodPassed = false;
   	miniGameState.completed = false;
end
function OnSceneFree()
    FreeData()
end

--// auxiliary functions -----------------------------------------------------
function auxInitCubes()
	cubes = {};
	cubes[1] = {miniGamePlayField:GetObject('stone1'), miniGamePlayField:GetObject('stone2'), miniGamePlayField:GetObject('stone3')};
	cubes[2] = {miniGamePlayField:GetObject('stone4'), nil,                            miniGamePlayField:GetObject('stone5')};
	cubes[3] = {miniGamePlayField:GetObject('stone6'), miniGamePlayField:GetObject('stone7'), miniGamePlayField:GetObject('stone8')};

	cubes.positions = {};
	cubes.positions[1] = {miniGamePlayField:GetObject('stone1'):GetPosition(), miniGamePlayField:GetObject('stone2'):GetPosition(), miniGamePlayField:GetObject('stone3'):GetPosition()};
	cubes.positions[2] = {miniGamePlayField:GetObject('stone4'):GetPosition(), miniGamePlayField:GetObject('stone9'):GetPosition(), miniGamePlayField:GetObject('stone5'):GetPosition()};
	cubes.positions[3] = {miniGamePlayField:GetObject('stone6'):GetPosition(), miniGamePlayField:GetObject('stone7'):GetPosition(), miniGamePlayField:GetObject('stone8'):GetPosition()};
	
	cubes.completeNames = {};
    for i = 1,3 do
        cubes.completeNames[i] = {};
        for j = 1,3 do
            if cubes[i][j] ~= nil then
                local name = cubes[i][j]:GetName();
                cubes.completeNames[i][j] = name;
            end
        end
    end

    cubes.locked = false;
end

function auxGetObjectIndeces(objectName)
    for i,v in ipairs(cubes) do
        for j = 1,3 do
            if v[j] ~= nil and v[j]:GetName() == objectName then
                return {i,j};
            end
        end
    end
    assert(false);
end

function auxGetEmptyObjectIndeces()
    for i,v in ipairs(cubes) do
        for j = 1,3 do
            if v[j] == nil then
                return {i,j};
            end
        end
    end
    assert(false);
end

function auxLockCubes(isLocked)
    assert(cubes.locked ~= nil);
    cubes.locked = isLocked;
end

function auxIsMiniGameCompleted()
    for i = 1,3 do
        for j = 1,3 do
            if cubes[i][j] ~= nil then
                local name = cubes[i][j]:GetName();
                if (cubes.completeNames[i][j] ~= name ) then
                    return false;
                end
            end
        end
    end
    return true;
end

function auxMoveObjectToPosition(object, idecesFrom, indecesTo, isShuffleMode)
    if isShuffleMode == nil then
        isShuffleMode = false;
    end
    
    local posFrom = cubes.positions[ idecesFrom[1] ][ idecesFrom[2] ];
    local posTo = cubes.positions[ indecesTo[1] ][ indecesTo[2] ];
    local duration = 0.5;
    
    if (isShuffleMode) then
        object:SetXY(posTo.x, posTo.y);
    else
        auxLockCubes(true);
        object:Move(posTo.x - posFrom.x, posTo.y - posFrom.y, duration);
        TimerDoString('auxLockCubes(false)', duration, miniGamePlayField:GetTimer());
    end
    cubes[ idecesFrom[1] ][ idecesFrom[2] ] = nil;
    cubes[ indecesTo[1] ][ indecesTo[2] ] = object;
end

function auxCreateShakeEffector(object, duration, amplitudeFactor)
    if amplitudeFactor == nil then
        amplitudeFactor = 1.0;
    end
	local objY = object:GetY();
	local objX = object:GetX();

	local amplitude = 5.0 * amplitudeFactor;
	local fadeSpeed = 5.0;
	local offset = amplitude > 0.0 and 0.8 or 0.0;

	eff = CreateAnimationEffector();
	eff:AttachTo(object);
--	eff:SetMode(_ANIM_LOOP);

    local time = 0.0;
    local pointCount = 6;
    local dT = duration / pointCount;
    local xScale = 0.25;
    while time <= duration do
        local value = 1.0/math.exp(fadeSpeed*time);
    	eff:SetKey(_TRACK_Y, time, 	        objY + amplitude * value + offset);
    	eff:SetKey(_TRACK_Y, time + dT/2.0, objY);
    	eff:SetKey(_TRACK_X, time, 	        objX + xScale * amplitude * value + offset);
    	eff:SetKey(_TRACK_X, time + dT/2.0, objX);
    	time = time + dT;
    end

    auxLockCubes(true);
	eff:Play();
    TimerDoString('auxLockCubes(false)', duration, miniGamePlayField:GetTimer());
end

function auxTryToMoveObject(object, isShuffleMode)
    local objectName = object:GetName();
    if isShuffleMode == nil then
        isShuffleMode = false;
    end

    local index = auxGetObjectIndeces(objectName); 
    local emptyIndex = auxGetEmptyObjectIndeces();
    
    if ( (index[1] == emptyIndex[1] and math.abs(index[2] - emptyIndex[2]) == 1) or 
         (index[2] == emptyIndex[2] and math.abs(index[1] - emptyIndex[1]) == 1) ) then
        auxMoveObjectToPosition(object, index, emptyIndex, isShuffleMode);
    else
        if (isShuffleMode == false) then
            auxCreateShakeEffector(object, 0.5); 
        end
        return false;
    end
    return true;
end

function auxShufflePlayField(stepCount)
    assert(stepCount ~= nil and stepCount >= 5);
    
    local prevCubeName = '';
    while (stepCount > 0) do
        local objectName = 'stone'..math.random(1,8);
        if (objectName ~= prevCubeName and auxTryToMoveObject(miniGamePlayField:GetObject(objectName), true) == true) then
            stepCount = stepCount - 1;
            prevCubeName = objectName;
        end
    end
end

-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

function OnUpdate(dt)
    miniGameState.timeElapsed = miniGameState.timeElapsed + dt;
	auxUpdateProgressBar(miniGameState.timeElapsed > miniGameState.delayPeriod and 1.0 or miniGameState.timeElapsed / miniGameState.delayPeriod);
    if (miniGameState.delayPeriodPassed == false and miniGameState.timeElapsed > miniGameState.delayPeriod) then
        miniGameState.delayPeriodPassed = true;
        auxShowButton(false);
    end
end

function OnShowHelp()
end

function OnObjectMouseDown(object)
    local objectName = object:GetName();
    
    if (string.sub(objectName, 1, 5) == 'stone' and objectName ~= 'stone9') then
        if miniGameState.completed == false and cubes.locked == false then
            auxTryToMoveObject(object);
            
            if ( miniGameState.completed == false and auxIsMiniGameCompleted() == true ) then
                miniGameState.completed = true;
                --auxLockCubes(true);
                miniGamePlayField:GetObject('Layer_Glow'):SetVisible(true);
			   	miniGamePlayField:GetObject('CenterStone_radial_glow'):SetVisible(true);
                auxShowButton(true);
            end
        end
    end
end
function OnObjectMouseUp(object)
end

function OnObjectRightMouseDown(object)
end
function OnObjectRightMouseUp(object)
end

function OnMouseMove(previousPos, currentPos)
end

function OnObjectMouseEnter(object)
end
function OnObjectMouseLeave(object)
end

-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

-- CLEAR_ON_SAVE_BEGIN
-- Do not edit code listed below (generated by the editor on each save)
function LoadData()
	local anim = CreateAnimation('data/Texture/Minigames/Tails/back.png',0,0,1024,768,1,0)
	anim:SetHotSpot(512,384)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('back',anim,512,384,98,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Tails/stone1.png',0,0,170,170,1,0)
	anim:SetHotSpot(85,85)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('stone1',anim,344,219,101,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Tails/stone2.png',0,0,170,170,1,0)
	anim:SetHotSpot(85,85)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('stone2',anim,510,220,101,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Tails/stone3.png',0,0,170,170,1,0)
	anim:SetHotSpot(85,85)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('stone3',anim,680,220,101,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Tails/stone4.png',0,0,170,170,1,0)
	anim:SetHotSpot(85,85)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('stone4',anim,344,387,101,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Tails/stone5.png',0,0,170,170,1,0)
	anim:SetHotSpot(85,85)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('stone5',anim,681,388,101,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Tails/stone6.png',0,0,170,170,1,0)
	anim:SetHotSpot(85,85)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('stone6',anim,342,555,101,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Tails/stone7.png',0,0,170,170,1,0)
	anim:SetHotSpot(85,85)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('stone7',anim,512,555,101,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Tails/stone8.png',0,0,170,170,1,0)
	anim:SetHotSpot(85,85)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('stone8',anim,679,555,101,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Tails/stone9.png',0,0,170,170,1,0)
	anim:SetHotSpot(85,85)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('stone9',anim,512,385,99,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Tails/Layer_Glow.png',0,0,158,158,1,0)
	anim:SetHotSpot(79,79)
	anim:SetBlendMode(0)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('Layer_Glow',anim,513,385,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Scenes/Common/radialGlow.png',0,0,97,99,1,0)
	anim:SetHotSpot(48,48)
	anim:SetBlendMode(0)
	anim:SetColor('0xFF0099FF')
	play_field:CreateObject('CenterStone_radial_glow',anim,513,384,102,0,5,5)
end

function FreeData()
end
-- CLEAR_ON_SAVE_END
