
function OnSceneLoad(screen)
    LoadData(screen)
    DefaultOnSceneLoad('data/Scenes/18_Balkon_MG.lua', 'quest', 'data/Scenes/18_Theatre_Hall_Main.lua')

	LinkScene('area_back', 'CursorDoorDown', 'data/Scenes/18_Theatre_Hall_Main.lua', false)
	
    game_state.cargoArray = {};
    game_state.discArray  = {};
    game_state.size       = 5;
    game_state.stage      = 'wait';
    game_state.unvisibleButton = nil;
   
    local deltaWidth = (play_field:GetObject('Button'..game_state.size):GetX() - play_field:GetObject('Button1'):GetX()) / (game_state.size-1);
    local indexes = {6,5,4,3,2,1}
    
    game_state.discRadius = deltaWidth / 2;
    
    for i=1, game_state.size+1 do
        CreateCargo(i, 'Pimpa'..i, 'Pinion'..i, 'Number'..i);
    end
    
    for i=1, game_state.size do
        CreateDisc(i);
        
        GetDisc(i).x = play_field:GetObject('Button1'):GetX() + deltaWidth * (i-1);
        GetDisc(i).y = play_field:GetObject('Button'..i):GetY();
        
        GetDisc(i).setLeftCargo ( GetCargo(indexes[i])  );
        GetDisc(i).setRightCargo( GetCargo(indexes[i+1]) );
    end
    
    RegisterToolApplyInfo('24_pimpa', 'area_tool_apply',    nil,
                                                            nil,
                                                            function(tool_name)
                                                                play_field:GetObject('area_tool_apply'):SetVisible(false);
                                                                play_field:GetObject('area_cover'     ):SetVisible(false);
                                                                
                                                                GetCargo(1).pimpa:Show()
                                                                GetCargo(1).pinion:Show()
                                                                GetCargo(1).number:Show()
                                                                
                                                                game_state.level_mode = 'mini_game';
														        play_field:GetLevelScreen():GetPanel():SetMode(PM_MINIGAME)
														        ShowMonolog('C_18_PRE_MINIGAME_2', 'C_18_PRE_MINIGAME_2')
                                                            end,
                                                            
                                                            function(tool_name)
                                                                play_field:GetObject('area_tool_apply'):SetVisible(false);
                                                                play_field:GetObject('area_cover'     ):SetVisible(false);
                                                                
                                                                game_state.level_mode = 'mini_game';
														        play_field:GetLevelScreen():GetPanel():SetMode(PM_MINIGAME)
														        ShowMonolog('C_18_PRE_MINIGAME_2', 'C_18_PRE_MINIGAME_2')
                                                            end);

	if not HasGameState('ToolApplied', '24_pimpa') then
		ShowMonolog('C_18_PRE_MINIGAME', 'C_18_PRE_MINIGAME')
		GetCargo(1).pimpa:Hide()
		--GetCargo(1).pinion:Hide()
        GetCargo(1).number:Hide()   
        
        play_field:GetObject('area_tool_apply'):SetXY(GetCargo(1).pimpa:GetX(), GetCargo(1).pimpa:GetY());
	else
		--ShowMonolog('C_18_PRE_MINIGAME_2', 'C_18_PRE_MINIGAME_2')
	end
	
	LoadSound("CircleRoll", "data/Sound/18_Balkon_MG/Circle_roll.ogg");
	play_field.circleRollSound = MakeSoundEntity("CircleRoll");
end

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

----------------------------------------------------
-- minigame functions
----------------------------------------------------
function CreateCargo(id, pimpaName, pinionName, numberName)
    local cargo = {};
    
    cargo.id     = id;
    cargo.pimpa  = play_field:GetObject(pimpaName);
    cargo.pinion = play_field:GetObject(pinionName);
    cargo.number = play_field:GetObject(numberName);
    
    cargo.effector = CreateAnimationEffector();
    cargo.effector:AttachTo(cargo.pinion);
    cargo.effector:SetMode(HGEANIM_FWD + HGEANIM_LOOP);
    cargo.effector:SetKey(_TRACK_A, 0, 0);
    cargo.effector:SetKey(_TRACK_A, 1, M_TWO_PI);
    
    cargo.SetX = function(x)
        cargo.pimpa:SetX(x);
        cargo.pinion:SetX(x);
        cargo.number:SetX(x);
    end
    
    cargo.SetY = function(y)
        cargo.pimpa:SetY(y);
        cargo.pinion:SetY(y);
        cargo.number:SetY(y);
    end
    
    cargo.StartAnim = function()
        cargo.effector:Play();
    end
    
    cargo.StopAnim = function()
       cargo.effector:Stop();
    end
    
    game_state.cargoArray[id] = cargo;
    return cargo;
end
----------------------------------------------------
function GetCargo(id)
    return game_state.cargoArray[id];
end
----------------------------------------------------
function CreateDisc(id)
    local disc = {};
    
    disc.id         = id;
    disc.leftCargo  = nil;
    disc.rightCargo = nil;
    
    disc.leftAngle  = math.pi;
    disc.rightAngle = 0;
    
    disc.rotating   = false;
    
    disc.x          = 0;
    disc.y          = 0;
    disc.angle      = 0;
    disc.startAngle	= 0;
	disc.rotateCoef = 0;
	disc.time       = 0;
	
	disc.setLeftCargo = function(cargo)
		disc.leftCargo = cargo;
		
		if cargo ~= nil then
		    local angle = disc.angle + disc.leftAngle;
            disc.leftCargo.SetX( disc.x + game_state.discRadius * math.cos( angle ) );
			disc.leftCargo.SetY( disc.y + game_state.discRadius * math.sin( angle ) );
		end
	end
	
	disc.setRightCargo = function(cargo)
		disc.rightCargo = cargo;
		
		if cargo ~= nil then
		    local angle = disc.angle + disc.rightAngle;
            disc.rightCargo.SetX( disc.x + game_state.discRadius * math.cos( angle ) );
			disc.rightCargo.SetY( disc.y + game_state.discRadius * math.sin( angle ) );
		end
	end
	
    disc.Rotate = function(time)
		disc.time       = 0;
		disc.rotateCoef = math.pi / time;
		disc.startAngle = disc.angle;
		disc.rotating   = true;
		
		if disc.leftCargo ~= nil then
		    disc.leftCargo.StartAnim();
		end
		
		if disc.rightCargo ~= nil then
		    disc.rightCargo.StartAnim();
		end
	end
	
	disc.Update = function(dt)
	    if disc.rotating == true then
			disc.time = disc.time + dt;
			
			local dAngle = math.min(disc.rotateCoef * disc.time, math.pi);
			
			disc.angle = disc.startAngle + dAngle;
			
			if disc.rightCargo ~= nil then
				local angle = disc.angle + disc.rightAngle;
				disc.rightCargo.SetX( disc.x + game_state.discRadius * math.cos( angle ) );
				disc.rightCargo.SetY( disc.y + game_state.discRadius * math.sin( angle ) );
			end
			
			if disc.leftCargo ~= nil then
				local angle = disc.angle + disc.leftAngle;
				disc.leftCargo.SetX( disc.x + game_state.discRadius * math.cos( angle ) );
				disc.leftCargo.SetY( disc.y + game_state.discRadius * math.sin( angle ) );
			end
			
			if dAngle == math.pi then
			    disc.leftAngle, disc.rightAngle = disc.rightAngle, disc.leftAngle;
				disc.leftCargo, disc.rightCargo = disc.rightCargo, disc.leftCargo;
				disc.rotating = false;
				
				onDiscRotated(disc.id)
			end
		end
	end
	
	game_state.discArray[id] = disc;
	return disc;
end
----------------------------------------------------
function GetDisc(id)
    return game_state.discArray[id];
end
----------------------------------------------------
function onDiscRotated(id)
    local disc = GetDisc(id);
    
    if id > 1 then
        GetDisc(id-1).setRightCargo( disc.leftCargo );
    end
    
    if id < game_state.size then
        GetDisc(id+1).setLeftCargo( disc.rightCargo );
    end
    
    if disc.leftCargo ~= nil then
        disc.leftCargo.StopAnim();
    end
    
    if disc.rightCargo ~= nil then
        disc.rightCargo.StopAnim();
    end
    
    game_state.stage = 'wait';
    
    if IsCompleted() == true then
        OnWinMiniGame();
    end
end
----------------------------------------------------
function IsCompleted()
    local disc = nil;
    local index = 1;
    
    for i=1, game_state.size do
        disc = GetDisc(i);
        
        if disc.leftCargo.id ~= index then
            return false;
        end
        
        index = index + 1;
        
        if i == game_state.size and disc.rightCargo.id ~= index then
            return false;
        end
    end
    
    return true;
end
----------------------------------------------------
function OnWinMiniGame()
    game_state.stage = 'win';
	AddGameState('MiniGameCompleted', '18_numbers')
	StartLevel('data/Scenes/18_Theatre_Hall_Main.lua')
end
----------------------------------------------------
function OnUpdate(dt)
    for i, disc in ipairs(game_state.discArray) do
        disc.Update(dt);
    end
    
    DefaultOnUpdate(dt)
end

function OnAllItemsFound()
    DefaultOnAllItemsFound()
end

function OnLose()
    DefaultOnLose()
end

function OnExit()
    DefaultOnExit()
end

function OnClose()
    DefaultOnClose()
end

function OnObjectMouseEnter(object)
    DefaultOnObjectMouseEnter(object)
end

function OnObjectMouseLeave(object)
    if game_state.unvisibleButton ~= nil and object:GetName() == 'ButtonOn' then
        play_field:GetObject('ButtonOn'):SetVisible(false);
        game_state.unvisibleButton:SetVisible(true);
        game_state.unvisibleButton = nil
    end
    
    DefaultOnObjectMouseLeave(object)
end

function OnObjectMouseDown(object)
    local is_wrong_click = not DefaultOnObjectMouseDown(object)
    local obj_name = object:GetName()
    local pf = play_field
    
    if obj_name == 'area_cover'
    or obj_name == 'area_tool_apply'
    then
        ShowMonolog('C_18_PRE_MINIGAME', 'C_18_PRE_MINIGAME');
    end
    
    if game_state.stage == 'wait' then
        for i=1, 5 do
            if obj_name == 'Button'..i then
                GetDisc(i).Rotate(1);
                game_state.stage = 'rotate';
                
                play_field.circleRollSound:StopSound();
                play_field.circleRollSound:Play(false);
                
                play_field:GetObject('ButtonOn'):SetXY(object:GetX(), object:GetY() + 4);
                play_field:GetObject('ButtonOn'):SetVisible(true);
                object:SetVisible(false);
                
                game_state.unvisibleButton = object;
                break;
            end
        end
    end
    
    DefaultOnObjectMouseDownProcessed(is_wrong_click);
end

function OnObjectMouseUp(object)
    if game_state.unvisibleButton ~= nil then
        play_field:GetObject('ButtonOn'):SetVisible(false);
        game_state.unvisibleButton:SetVisible(true);
        game_state.unvisibleButton = nil
    end
    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)
end

function SkipMiniGame()
	OnWinMiniGame()
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/Balcony/fon.JPG',0,0,1024,768,1,0)
	anim:SetHotSpot(512,384)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('fon',anim,512,384,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Button_On.png',0,0,140,142,1,0)
	anim:SetHotSpot(70,71)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('ButtonOn',anim,92,684,101,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Button_Off.png',0,0,141,133,1,0)
	anim:SetHotSpot(70,66)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Button1',anim,207,383,102,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Button_Off.png',0,0,141,133,1,0)
	anim:SetHotSpot(70,66)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Button2',anim,365,383,102,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Button_Off.png',0,0,141,133,1,0)
	anim:SetHotSpot(70,66)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Button3',anim,523,383,102,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Button_Off.png',0,0,141,133,1,0)
	anim:SetHotSpot(70,66)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Button4',anim,678,383,102,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Button_Off.png',0,0,141,133,1,0)
	anim:SetHotSpot(70,66)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Button5',anim,835,383,102,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Shester.png',0,0,75,74,1,0)
	anim:SetHotSpot(37,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Pinion1',anim,129,235,103,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Shester.png',0,0,75,74,1,0)
	anim:SetHotSpot(37,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Pinion2',anim,287,293,103,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Shester.png',0,0,75,74,1,0)
	anim:SetHotSpot(37,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Pinion3',anim,441,479,103,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Shester.png',0,0,75,74,1,0)
	anim:SetHotSpot(37,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Pinion4',anim,608,537,103,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Shester.png',0,0,75,74,1,0)
	anim:SetHotSpot(37,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Pinion5',anim,760,261,103,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Shester.png',0,0,75,74,1,0)
	anim:SetHotSpot(37,37)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Pinion6',anim,900,107,103,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Pimpa.PNG',0,0,75,89,1,0)
	anim:SetHotSpot(37,44)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Pimpa1',anim,130,231,104,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Pimpa.PNG',0,0,75,89,1,0)
	anim:SetHotSpot(37,44)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Pimpa2',anim,286,291,104,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Pimpa.PNG',0,0,75,89,1,0)
	anim:SetHotSpot(37,44)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Pimpa3',anim,447,479,104,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Pimpa.PNG',0,0,75,89,1,0)
	anim:SetHotSpot(37,44)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Pimpa4',anim,608,541,104,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Pimpa.PNG',0,0,75,89,1,0)
	anim:SetHotSpot(37,44)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Pimpa5',anim,756,252,104,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Pimpa.PNG',0,0,75,89,1,0)
	anim:SetHotSpot(37,44)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Pimpa6',anim,901,106,104,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Number1.PNG',0,0,17,34,1,0)
	anim:SetHotSpot(8,17)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Number1',anim,195,73,105,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Number2.PNG',0,0,26,37,1,0)
	anim:SetHotSpot(13,18)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Number2',anim,215,69,105,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Number3.PNG',0,0,26,36,1,0)
	anim:SetHotSpot(13,18)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Number3',anim,238,68,105,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Number4.PNG',0,0,24,36,1,0)
	anim:SetHotSpot(12,18)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Number4',anim,259,68,105,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Number5.PNG',0,0,25,34,1,0)
	anim:SetHotSpot(12,17)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Number5',anim,278,68,105,0,1,1)
	local anim = CreateAnimation('data/Texture/Minigames/Balcony/Number6.PNG',0,0,24,37,1,0)
	anim:SetHotSpot(12,18)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Number6',anim,297,65,105,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_cover',anim,546,380,110,0,110,25)
	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_tool_apply',anim,716,51,111,0,15,15)
	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_back',anim,498,693,101,0,140,20)
end

function FreeData(screen)
end
-- CLEAR_ON_SAVE_END
