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

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

function OnSceneLoad()
	play_field = miniGamePlayField;
    LoadData();
	play_field = nil;

    auxLoadStones()
    miniGamePlayField:IgnoreOnTestPoint('Bg');
    miniGamePlayField:IgnoreOnTestPoint('krepej2');
    miniGamePlayField:IgnoreOnTestPoint('pila');
    miniGamePlayField:IgnoreOnTestPoint('rithag');
    miniGamePlayField:IgnoreOnTestPoint('rithag sh');
    miniGamePlayField:IgnoreOnTestPoint('spr');
    miniGamePlayField:IgnoreOnTestPoint('spr2');
    miniGamePlayField:IgnoreOnTestPoint('spr3');
    
	miniGamePlayField:GetObject('Stone01'):GetAnimation():Play();
	miniGamePlayField:GetObject('Stone02'):GetAnimation():Play();
	miniGamePlayField:GetObject('Stone03'):GetAnimation():Play();
	
	for i = 1,MAX_STONE do
		local Dust = CreateParticleSystemEntity('data/ParticleSystem/Dust.psi', 'SmokeParticle');
		Dust:AttachTo(miniGamePlayField:GetObject("Stone0"..i));
		Dust:SetZ(151.0);
		Dust:SetGeneration(true);
	end

    miniGameState = {};
   	miniGameState.delayPeriod = 90.0;
   	miniGameState.timeElapsed = 0.0;
   	miniGameState.delayPeriodPassed = false;
   	miniGameState.completed = false;
   	
   	StoneTimer = 0.0;
   	NeededStoneTime = math.random(10) + 5;
   	
   	auxInitGame();
   	
   	TimerDoString('OnShowHelp()', 0.5, miniGamePlayField:GetTimer());

	PlaySound('L04S01', true);
end

function OnSceneFree()
    FreeData()
	StopSound('L04S01');
	StopSound('L04S02');
	StopSound('L04S03');
end

------------------------------------------------------------------------------
-- номер начального елемета 
NO_ACTIVE_ELEM = 1

-- скорость вращения
ROTATE_SPEED = 100

-- максимальное количество падающих камней
MAX_STONE = 10;

-- 1 - начальный елемент крутиться вправо
-- 2 - начальный елемент крутиться влево
DIRECTION = 1

-- колчество шестеренок
PINIONS_AMOUNT = 6

--начальная инициализация игровых объектов
function auxInitGame()
    Pinions = {miniGamePlayField:GetObject("sh_1"), miniGamePlayField:GetObject("sh_2"), miniGamePlayField:GetObject("sh_3"),
                miniGamePlayField:GetObject("sh_4"), miniGamePlayField:GetObject("sh_5"), miniGamePlayField:GetObject("sh_6")};
    
    RichagFlag = false;
    
    PinionsPos = {};
    PinionsStartPos = {};
    IsActive = {};
    IsRotated = {};
    
    local FlagsArray = {}

    for i = 1,PINIONS_AMOUNT do
		FlagsArray[i] = false;
    end
    
    for i = 1,PINIONS_AMOUNT do
        if (i == NO_ACTIVE_ELEM) then
            IsActive[i] = false;
            IsRotated[i] = DIRECTION;
            miniGamePlayField:IgnoreOnTestPoint(Pinions[i]:GetName());
            DefaultDiameter = Pinions[i]:GetAnimation():GetWidth();
        else
            IsActive[i] = true;
            IsRotated[i] = -1;
            PinionsPos[i] = Pinions[i]:GetPosition();
        end
    end
    
	for i = 1,PINIONS_AMOUNT - 1 do
		local rand = 0;
		
		repeat
			rand = math.random(PINIONS_AMOUNT);
		until FlagsArray[rand] == false and rand ~= NO_ACTIVE_ELEM
		
		PinionsStartPos[rand] = {};
		
		Floor = math.floor((i - 1)/ 3);
		PinionsStartPos[rand][0] = 150 + 700 * Floor;
		PinionsStartPos[rand][1] = math.random(50) + 200 * (i - Floor * 3) + 200 * Floor * (i - Floor * 3 - 1);

		Pinions[rand]:SetXY(PinionsStartPos[rand][0], PinionsStartPos[rand][1]);
		FlagsArray[rand] = true;
    end
end

function auxLoadStones()
	for i = 1,MAX_STONE do
		local anim = CreateAnimation('data/Texture/Minigames/Pinions/Stone01.png',0,0,32,32,30,40)
		anim:SetHotSpot(16,16)
		anim:SetBlendMode(2)
		anim:SetColor('0xFFFFFFFF')
		miniGamePlayField:CreateObject('Stone0'..i,anim,-100,-100,160,0,1,1)
	end
end

function auxStartDtag(object)
    Index = auxGetObjectIndex(object:GetName());
    
    if(IsActive[Index] == true) then
        DragObject = object;
        DragObject:SetZ(300.0);
        MousePos = GetMousePos();
        dx = MousePos.x - DragObject:GetX();
        dy = MousePos.y - DragObject:GetY();
    end
end

function auxStopDrag()
    if(DragObject ~= nil) then
        
        
        Index = auxGetObjectIndex(DragObject:GetName());
	
        if (Index ~= nil) then   
            if (math.abs(DragObject:GetX() - PinionsPos[Index].x) < 30 and math.abs(DragObject:GetY() - PinionsPos[Index].y) < 30) then --если мы над нашим местом
                DragObject:Move(PinionsPos[Index].x - DragObject:GetX(), PinionsPos[Index].y - DragObject:GetY(), 0.2);
                miniGamePlayField:IgnoreOnTestPoint(DragObject:GetName());
                IsActive[Index] = false;
				PlaySound('L04S02');
                auxUpdateRotObject();
                DragObject:SetZ(100.0 + Index);
                if (OnLevelComplite()) then
					auxStartFinishAnim();
                end
			else
				DragObject:SetZ(200.0 + Index);
				DragObject:Move(PinionsStartPos[Index][0] - DragObject:GetX(), PinionsStartPos[Index][1] - DragObject:GetY(), 0.3);
            end
        end
        
        DragObject = nil;
        dx = nil;
        dy = nil;
    end
end

function auxDrag(MouseX, MouseY)
    if(DragObject ~= nil) then
        local X = MouseX - DragObject:GetX() - dx;
        local Y = MouseY - DragObject:GetY() - dy;
        DragObject:Move(X, Y, 0.0);
    end
end


--При установке нового елемента проверяет не должны ли мы крутить еще что то
--(сделана максимально универсальной, на случай того что начальная шестеренка будет в середине)
function auxUpdateRotObject()
    repeat
        local Count = 0;
        for i = 1,PINIONS_AMOUNT do
            if (IsActive[i] == false and  IsRotated[i] < 0) then
                if(i > 1  and IsRotated[i - 1] >= 0) then
                    IsRotated[i] = 1 - IsRotated[i - 1];
					Count = Count + 1;
                end
                if(i < PINIONS_AMOUNT - 1  and IsRotated[i + 1] >= 0) then
                    IsRotated[i] = 1 - IsRotated[i + 1];
					Count = Count + 1;
                end 
            end
        end
    until Count == 0
end

-- получение индекса объекта в массиве по его имени
function auxGetObjectIndex(name)
    for i = 1,PINIONS_AMOUNT do
        if (Pinions[i]:GetName() == name) then
            return i;
        end
    end
    return nil;
end 

function OnLevelComplite()
    for i = 1,PINIONS_AMOUNT do
        if (IsActive[i]) then
            return false;
        end;
    end 
    
    return true;
end

-- вращение шестеренок
function auxPinionsRotating(dt)
	
	local rotate_koef = 10000;
	
    for i = 1,PINIONS_AMOUNT do
		if (IsRotated[i] > -1) then
			if (IsRotated[i] == 1) then
				Angle = Pinions[i]:GetAngle() + ROTATE_SPEED * DefaultDiameter * dt * 80/ (Pinions[i]:GetAnimation():GetWidth() * rotate_koef);
			end
			if (IsRotated[i] == 0) then
				Angle = Pinions[i]:GetAngle() - ROTATE_SPEED * DefaultDiameter * dt * 80/ (Pinions[i]:GetAnimation():GetWidth() * rotate_koef);
			end
			
			Pinions[i]:SetAngle(Angle);
			Pinions[i]:SetAngle(auxFixedAngle(Pinions[i]:GetAngle()));
        end
    end
end

function auxFixedAngle(Angle)
    if(Angle > 360) then
        Angle = Angle - 360;
    end
	if(Angle < 0) then
        Angle = 360 - Angle;
    end
    
    return Angle;
end

function auxStonesUpdate(dt)
	if (StoneTimer  >= NeededStoneTime) then
		NeededStoneTime = math.random(10) + 5;
		StoneTimer = 0;
		rand = math.random(MAX_STONE);
		for i = 1,rand do
			miniGamePlayField:GetObject("Stone0"..i):SetXY(math.random(200), -100.0 * math.random(5));
			miniGamePlayField:GetObject("Stone0"..i):Move(0.0, SCREEN_HEIGHT + math.random(1000.0) + 600.0, math.random(100.0) / 100.0 + 1.0);
			miniGamePlayField:GetObject("Stone0"..i):SetScale(math.random(100) / 100 + 0.5);
		end
		PlaySound('L04S03');
	end
	
	StoneTimer = StoneTimer +dt;
end

function auxStartFinishAnim()
	local rotate_koef = 10000;
	miniGamePlayField:GetObject("pila"):Move(0.0, -390.0, 100.0 * ROTATE_SPEED / rotate_koef);
	StartAngle = miniGamePlayField:GetObject("rithag"):GetAngle();
	PlaySound('L04S04')
	RichagFlag = true;
end

function auxFinishAnim(dt)
	if (RichagFlag == true) then
		local rotate_koef = 10000;
		local Rithag = miniGamePlayField:GetObject("rithag");
		local Angle = Rithag:GetAngle();
		Rithag:SetAngle(Angle - 0.3 * ROTATE_SPEED / 10000);
		
		local RithagPinion = miniGamePlayField:GetObject("rithag sh");
		RithagPinion:SetAngle(RithagPinion:GetAngle() + ROTATE_SPEED * DefaultDiameter * dt * 80 / (RithagPinion:GetAnimation():GetWidth() * rotate_koef));
		
		Angle = Rithag:GetAngle();
		
		if(math.abs(StartAngle - Angle) > M_PI / 6.0) then
			RichagFlag = false;
			miniGameState.completed = true;
			auxShowButton(true);
			for i = 1,PINIONS_AMOUNT do
				IsRotated[i] = -1;
			end 
		end
    end
end

------------------------------------------------------------------------------
function OnUpdate(dt)
    auxPinionsRotating(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.timeElapsed > miniGameState.delayPeriod and  miniGameState.delayPeriodPassed == false)  then
        miniGameState.delayPeriodPassed = true;
        auxShowButton(false);
    end
    
    auxStonesUpdate(dt);
	auxFinishAnim(dt);
end

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

function OnObjectMouseDown(object)
    auxStartDtag(object);
end
function OnObjectMouseUp(object)
    auxStopDrag();
end

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

function OnMouseMove(previous_pos, current_pos)
    auxDrag(current_pos.x, current_pos.y);
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/Pinions/sh_1.png',0,0,185,186,1,0)
	anim:SetHotSpot(92,93)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('sh_1',anim,508,665,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/sh_2.png',0,0,185,185,1,0)
	anim:SetHotSpot(92,92)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('sh_2',anim,429,526,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/sh_3.png',0,0,96,97,1,0)
	anim:SetHotSpot(48,48)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('sh_3',anim,480,415,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/sh_4.png',0,0,127,127,1,0)
	anim:SetHotSpot(63,63)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('sh_4',anim,439,328,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/sh_5.png',0,0,79,78,1,0)
	anim:SetHotSpot(39,39)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('sh_5',anim,525,339,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/sh_6.png',0,0,187,187,1,0)
	anim:SetHotSpot(93,93)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('sh_6',anim,616,270,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/fonn.png',0,0,1024,768,1,0)
	anim:SetHotSpot(512,384)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('fonn',anim,512,384,98,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/krepej2.png',0,0,71,114,1,0)
	anim:SetHotSpot(33,55)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('krepej2',anim,686,626,150,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/pila.png',0,0,42,518,1,0)
	anim:SetHotSpot(21,259)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('pila',anim,706,402,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/rithag.png',0,0,374,337,1,0)
	anim:SetHotSpot(300,265)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('rithag',anim,507,211,99,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/rithag sh.png',0,0,70,69,1,0)
	anim:SetHotSpot(35,34)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('rithag sh',anim,507,210,101,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/spr.png',0,0,63,233,1,0)
	anim:SetHotSpot(29,114)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('spr',anim,708,114,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/spr2.png',0,0,83,166,1,0)
	anim:SetHotSpot(39,81)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('spr2',anim,432,154,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Pinions/spr3.png',0,0,107,27,1,0)
	anim:SetHotSpot(51,11)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	play_field:CreateObject('spr3',anim,510,753,100,0,1,1)
end

function FreeData()
end
-- CLEAR_ON_SAVE_END
