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

function OnSceneLoad()
    play_field = miniGamePlayField;
    LoadData();
	play_field = nil;
	
	pf = miniGamePlayField;
	g_timer = pf:GetTimer();
	
	miniGameState = {};
   	miniGameState.delayPeriod = 90.0;
   	miniGameState.timeElapsed = 0.0;
   	miniGameState.delayPeriodPassed = false;
   	miniGameState.completed = false;
	CreateObjects()
	RotateToStartPositions()
	
	TimerDoString('OnShowHelp()', 0.5, miniGamePlayField:GetTimer());
end

function OnSceneFree()
    FreeData()
end

--// auxiliary functions -----------------------------------------------------
--// ...
function CreateObjects()
    local RightAngles = {math.rad(147), math.rad(354), math.rad(98), math.rad(14), math.rad(250), math.rad(216), math.rad(170), math.rad(157)}
    OBJECTS_AMOUNT = 8;
    Objects = {}
    for i = 1, OBJECTS_AMOUNT do
        Objects[i] = {}
        Objects[i].Entity = pf:GetObject('bulb_' .. i);
        Objects[i].RightAngle = RightAngles[i]
        Objects[i].Inplace = false
        Objects[i].Group = 0
        Objects[i].Index = i;
        Objects[i].Beam = pf:GetObject('Lazer_' .. i);
        Objects[i].Anim = InplaceAnimation(i);
        AttachInPlace(Objects[i].Beam, Objects[i].Entity)
        Objects[i].Beam:SetOpacity(0)
        pf:IgnoreOnTestPoint('Lazer_' .. i)
    end
    -- for chaining implementation
    Objects[1].Group = 2
    Objects[3].Group = 4
    Objects[4].Group = 5
    Objects[6].Group = 7
end

function RotateToStartPositions()
    math.randomseed(os.clock());
    math.random();
    for i = 1, OBJECTS_AMOUNT do
        -- rotate to opposite direction plus some random angle
        Objects[i].Entity:SetAngle((Objects[i].RightAngle + M_PI + (math.random() * 2.5 - 1.25)) % M_TWO_PI);
    end
end

function AttachInPlace(object, parentObject)
	local dx = object:GetX() - parentObject:GetX()
	local dy = object:GetY() - parentObject:GetY()
	local z = object:GetZ() - parentObject:GetZ()
	object:SetZ(z)
	object:SetXY(dx, dy);
	object:AttachTo(parentObject);
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 InplaceAnimation(index)
    local af = CreateAnimationEffector();
    af:AttachTo(Objects[index].Beam);
    af:SetMode(_ANIM_PINGPONG + _ANIM_LOOP);
    
    af:SetKey(_TRACK_O, 0, 1);
    af:SetKey(_TRACK_O, 0.2, 0.3);
    
    return af;
end

-- returns angle in rads to or from right position
function GetDeltaAngle(index)
    local delta = math.abs(Objects[index].Entity:GetAngle() - Objects[index].RightAngle)
    if delta > math.rad(30) then
        local ang1 = math.min(Objects[index].Entity:GetAngle(), Objects[index].RightAngle) + M_TWO_PI
        local ang2 = math.max(Objects[index].Entity:GetAngle(), Objects[index].RightAngle)
        delta = math.abs(ang1 - ang2)
    end
    return delta;
end

function CheckPosition(index)
    local delta = GetDeltaAngle(index);
    if delta < math.rad(5) then
        Objects[index].Inplace = true;
        Objects[index].Anim:Play();
    end
    if Objects[index].Group ~= 0 then
        CheckPosition(Objects[index].Group)
    end
end

function FinishMiniGameAnimation()  
    for i = 1, OBJECTS_AMOUNT do
        Objects[i].Anim:Stop();
        local af = CreateAnimationEffector();
        af:AttachTo(Objects[i].Entity);
        af:SetMode(_ANIM_PINGPONG + _ANIM_LOOP);
        
        af:SetKey(_TRACK_O, 0, 1);
        af:SetKey(_TRACK_O, 0.1, 0.7);
        af:Play();
    end
end

function FinishMiniGame()
    auxShowButton(true);
end

function CheckComplete()
    for i = 1, OBJECTS_AMOUNT do
        if not Objects[i].Inplace then
            return false;
        end
    end
    miniGameState.completed  = true;
--    FinishMiniGameAnimation();
    FinishMiniGame()
end

function FireBeam(index)
    local delta = GetDeltaAngle(index);
    Objects[index].Beam:SetOpacity((math.rad(30)-delta) / math.rad(150));
end

function StopAnimation(index)
    Objects[index].Anim:Stop();
    Objects[index].Inplace = false;
    if Objects[index].Group ~= 0 then
        StopAnimation(Objects[index].Group)
    end
end

function StartRotation(obj)
    RotatedObject = obj;
    RotatedObject.Entity:GetAnimation():SetBlendMode(0);
    StopAnimation(RotatedObject.Index);
    PlaySound('L18S00', true)
end

-- Recursive func to implemet chain rotation
function Rotate(index, dt)
    Objects[index].Entity:SetAngle(((Objects[index].Entity:GetAngle() + M_PI_OVER_4 * dt) + M_TWO_PI) % M_TWO_PI)   -- to keep angles at 0 - TWO_PI range
    if Objects[index].Group ~= 0 then
        Rotate(Objects[index].Group, dt);
    end
    FireBeam(index)
end

function UpdateRotation(dt)
    if RotatedObject then
        Rotate(RotatedObject.Index, dt);
    end
end

function StopRotation()
    if RotatedObject then
        CheckPosition(RotatedObject.Index);
        RotatedObject.Entity:GetAnimation():SetBlendMode(2);
        RotatedObject = nil
        StopSound('L18S00')
        CheckComplete()
    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.completed == false and
        miniGameState.delayPeriodPassed == false and miniGameState.timeElapsed > miniGameState.delayPeriod) then
        miniGameState.delayPeriodPassed = true;
        auxShowButton(false);
    end
		
    if not miniGameState.completed then
        UpdateRotation(dt);
    end
end

function OnShowHelp()
    miniGamePlayField:GetLevelScreen():ShowDialog(500, 300, GetTextString('MINIGAME_TELEPORT_HELP'), GetTextString('MINIGAME_HELP_DIALOG_TITLE'));
end

function OnObjectMouseDown(object)
    obj = GetObjectByName(object:GetName());
    
    if obj and not miniGameState.completed then
        StartRotation(obj);
    end
end

function OnObjectMouseUp(object)
    if not miniGameState.completed then
        StopRotation();
    end
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/Teleport/018zoom_back.jpg',0,0,1024,768,1,0)
	anim:SetHotSpot(512,384)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('background',anim,512,384,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/1.png',0,0,96,96,1,0)
	anim:SetHotSpot(48,48)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('bulb_1',anim,592,208,105,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/2.png',0,0,160,160,1,0)
	anim:SetHotSpot(80,80)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('bulb_2',anim,592,208,104,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/3.png',0,0,96,96,1,0)
	anim:SetHotSpot(48,48)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('bulb_3',anim,420,293,105,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/4.png',0,0,170,170,1,0)
	anim:SetHotSpot(85,85)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('bulb_4',anim,420,293,104,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/5.png',0,0,240,240,1,0)
	anim:SetHotSpot(120,120)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('bulb_5',anim,420,293,103,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/6.png',0,0,128,128,1,0)
	anim:SetHotSpot(64,64)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('bulb_6',anim,398,471,105,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/7.png',0,0,160,160,1,0)
	anim:SetHotSpot(80,80)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('bulb_7',anim,398,471,104,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/8.png',0,0,70,70,1,0)
	anim:SetHotSpot(35,35)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('bulb_8',anim,479,579,105,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/Lazer_1.jpg',0,0,54,258,1,0)
	anim:SetHotSpot(25,8)
	anim:SetBlendMode(0)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('Lazer_1',anim,597,206,110,-147,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/Lazer_2.jpg',0,0,91,266,1,0)
	anim:SetHotSpot(24,11)
	anim:SetBlendMode(0)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('Lazer_2',anim,544,211,109,-354,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/Lazer_3.jpg',0,0,213,216,1,0)
	anim:SetHotSpot(20,19)
	anim:SetBlendMode(0)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('Lazer_3',anim,421,295,110,-98,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/Lazer_4.jpg',0,0,178,242,1,0)
	anim:SetHotSpot(21,17)
	anim:SetBlendMode(0)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('Lazer_4',anim,455,261,109,-14,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/Lazer_5.jpg',0,0,150,254,1,0)
	anim:SetHotSpot(22,15)
	anim:SetBlendMode(0)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('Lazer_5',anim,419,378,108,-250,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/Lazer_6.jpg',0,0,221,81,1,0)
	anim:SetHotSpot(10,24)
	anim:SetBlendMode(0)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('Lazer_6',anim,409,508,110,-216,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/Lazer_7.jpg',0,0,221,92,1,0)
	anim:SetHotSpot(11,68)
	anim:SetBlendMode(0)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('Lazer_7',anim,398,429,109,-170,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Teleport/Lazer_8.jpg',0,0,152,153,1,0)
	anim:SetHotSpot(16,134)
	anim:SetBlendMode(0)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('Lazer_8',anim,480,578,110,-157,1,1)
end

function FreeData()
end
-- CLEAR_ON_SAVE_END
