function OnSceneLoad(screen)
    LoadData(screen)
    DefaultOnSceneLoad('data/Scenes/17_Bedroom_Microscope.lua', 'quest', 'data/Scenes/17_Bedroom_Main.lua')
    pf = play_field
    g_timer = pf:GetTimer()
    
    play_field:IgnoreOnTestPoint('pipette_red')
    
    InitGame()
    
    max_z = 111                     -- used when dragging objects to be in front of other objects
    pieces_to_apply = 4             -- how many objects remain to apply. When not all objects applied dragging is prohibited
    
    -- need register ?
    b_microscope = true
    b_glass = true
    b_seashell = true
    b_pipette = true
    
    RegisterSceneTools()    
                          
    ReadGameState()
    CorrectGameState()
    
    play_field:IgnoreOnTestPoint('area_red')
    
    if game_state.level_mode ~= 'mini_game' then
        ShowMonolog('C_17_NOT_ALL_TOOL_APPLIED', 'C_17_NOT_ALL_TOOL_APPLIED');
    end
end

function RegisterSceneTools()
    if b_microscope then
        RegisterToolApplyInfo('17_microscope', 'area_entire', nil, nil, function(tool_name)
                                                                            pf:GetObject('microscope'):Show()
                                                                            pf:GetObject('microscope'):ChangeOpacity(0, 0, 0)
                                                                            pf:GetObject('microscope'):ChangeOpacity(0, 1, 1)
                                                                            b_microscope = false    -- needn't register microscope
                                                                            RegisterSceneTools()    -- reregister all remain tools to get proper cursor
                                                                            CheckAllToolsApplied()
                                                                        end,
                                                                        
                                                                        function(tool_name)
                                                                            pf:GetObject('microscope'):Show()
                                                                            b_microscope = false
                                                                            CheckAllToolsApplied()
                                                                        end);
    end
    if b_pipette then                                                                    
        RegisterToolApplyInfo('17_pipette', 'area_entire', nil, nil, function(tool_name)
                                                                            pf:GetObject('pipette_01'):Show()
                                                                            pf:GetObject('pipette_01'):ChangeOpacity(0, 0, 0)
                                                                            pf:GetObject('pipette_01'):ChangeOpacity(0, 1, 1)
                                                                            b_pipette = false
                                                                            RegisterSceneTools()
                                                                            CheckAllToolsApplied()
                                                                        end,
                                                                        
                                                                        function(tool_name)
                                                                            pf:GetObject('pipette_01'):Show()
                                                                            b_pipette = false
                                                                            CheckAllToolsApplied()
                                                                        end)
    end
    if b_seashell then                                                                    
        RegisterToolApplyInfo('17_seashell', 'area_entire', nil, nil, function(tool_name)
                                                                            pf:GetObject('seashell'):ChangeOpacity(0, 1, 1)
                                                                            b_seashell = false
                                                                            RegisterSceneTools()
                                                                            CheckAllToolsApplied()
                                                                        end,
                                                                        
                                                                        function(tool_name)
                                                                            pf:GetObject('seashell'):SetOpacity(1)
                                                                            b_seashell = false
                                                                            CheckAllToolsApplied()
                                                                        end)
    end
    if b_glass then                                                                    
        RegisterToolApplyInfo('17_glass', 'area_entire', nil, nil, function(tool_name)
                                                                            pf:GetObject('glass_01'):ChangeOpacity(0, 1, 1)
                                                                            b_glass = false
                                                                            RegisterSceneTools()
                                                                            CheckAllToolsApplied()
                                                                        end,
                                                                        
                                                                        function(tool_name)
                                                                            pf:GetObject('glass_01'):SetOpacity(1)
                                                                            b_glass = false
                                                                            CheckAllToolsApplied()
                                                                        end)
    end
end

function CheckAllToolsApplied()
    pieces_to_apply = pieces_to_apply - 1
    if pieces_to_apply == 0 then
        pf:GetObject('area_entire'):SetVisible(false)
        game_state.level_mode = 'mini_game';
        play_field:GetLevelScreen():GetPanel():SetMode(PM_MINIGAME)
        
        ShowMonolog('C_17_ALL_TOOL_APPLIED', 'C_17_ALL_TOOL_APPLIED');
    end
end

function ReadGameState()
    if HasGameState(game_state.scene_path .. '_pipette_full') then
        pipette_full = true
    else
        pipette_full = false
    end
    if HasGameState(game_state.scene_path .. '_glass_inplace') then
        glass_inplace = true
    else
        glass_inplace = false
    end
    if HasGameState(game_state.scene_path .. '_seashell_inplace') then
        seashell_inplace = true
    else
        seashell_inplace = false
    end
    if HasGameState(game_state.scene_path .. '_drip_inplace') then
        drip_inplace = true
    else
        drip_inplace = false
    end
end

function InitGame()
    AttachInPlace(pf:GetObject('fishki'), pf:GetObject('microscope'))
    AttachInPlace(pf:GetObject('pipette_red'), pf:GetObject('pipette_01'))
    pf:GetObject('microscope'):Hide()
    pf:GetObject('red'):SetOpacity(0.01)
    pf:GetObject('pipette_red'):SetOpacity(0)
    pf:GetObject('pipette_01'):Hide()
    pf:GetObject('drip'):SetOpacity(0)
    pf:GetObject('seashell'):SetOpacity(0)
    pf:GetObject('glass'):SetOpacity(0)
    pf:GetObject('glass_01'):SetOpacity(0)
end

function CorrectGameState()
    if seashell_inplace then
        pf:GetObject('red'):SetOpacity(1)
        pf:GetObject('seashell'):SetOpacity(0)
    end
    if glass_inplace then
        pf:GetObject('glass'):SetOpacity(1)
        pf:GetObject('glass_01'):SetOpacity(0)
    end
    if pipette_full then
        pf:GetObject('pipette_red'):SetOpacity(1)
    end
    if drip_inplace then
        pf:GetObject('drip'):SetOpacity(1)
        pf:GetObject('pipette_01'):SetOpacity(0)
        TimerDoString('FinishMiniGame()', 1, g_timer)
    end
end

function AttachInPlace(object, parentObject)
	local scrX,scrY = object:GetScrX(), object:GetScrY();
	local z = object:GetZ() - parentObject:GetZ()
	object:SetZ(z)
	object:AttachTo(parentObject);
	object:SetScrXY(scrX, scrY);	
end

function OnSceneFree(screen)
    DefaultOnSceneFree()
    FreeData(screen)
end
------------------------------------------------
-- Common drag functions
function StartDrag(obj)
    obj:SetZ(max_z)
    max_z = max_z + 1
    
    DragObject = {}
    DragObject.Entity = obj
    DragObject.InitX = DragObject.Entity:GetX() -- initial coords to return object when missing
    DragObject.InitY = DragObject.Entity:GetY()
    DragObject.DeltaX = GetMousePos().x - DragObject.InitX
    DragObject.DeltaY = GetMousePos().y - DragObject.InitY
    
    game_state.custom_cursors[DragObject.Entity:GetName()] = 'CursorHand';
    game_state.ignore_on_highlight[DragObject.Entity:GetName()] = true;
    
    game_state.disable_default_zoom_exit = true
end

function UpdateDrag()
    if DragObject then
        local mouse_x = GetMousePos().x - DragObject.DeltaX
        local mouse_y = GetMousePos().y - DragObject.DeltaY
        DragObject.Entity:SetXY(mouse_x, mouse_y)
    end
end

function StopDrag()
    game_state.custom_cursors[DragObject.Entity:GetName()] = nil;
    game_state.ignore_on_highlight[DragObject.Entity:GetName()] = nil;
    
    game_state.disable_default_zoom_exit = false
end
------------------------------------------------
-- Seashell Drag
function StartDragSeashell(obj)
    StartDrag(obj)
    DragObject.What = 'Seashell'
end

function UpdateDragSeashell()
    if DragObject and DragObject.What == 'Seashell' then
        UpdateDrag()
    end
end

function StopDragSeashell()
    local x = DragObject.Entity:GetX()
    local y = DragObject.Entity:GetY()
    DragObject.Entity:SetOpacity(0)                         -- DragObject will not overlap testing object
    local target = pf:FindObjectByPos(Vector(x, y))
    DragObject.Entity:SetOpacity(1)
    
    if target and target:GetName() == 'red' then
        pf:GetObject('seashell'):ChangeOpacity(1, 0, 0.2)
        pf:GetObject('red'):ChangeOpacity(0, 1, 0.2)
        seashell_inplace = true
        
        PlaySound('17_AcidShell');
        play_field:GetObject('red'):AddParticleSystem('data/ParticleSystem/Acid.psi', 'SmokeParticle', true);
    else
        local delta_x = DragObject.InitX - DragObject.Entity:GetX()
        local delta_y = DragObject.InitY - DragObject.Entity:GetY()
        DragObject.Entity:Move(delta_x, delta_y, 0.2)
    end
    
    StopDrag();
    DragObject = nil
end

------------------------------------------------
-- Empty Pipette Drag
function StartDragEmptyPipette(obj)
    StartDrag(obj)
    DragObject.What = 'EmptyPipette'
    play_field:DoNotIgnoreOnTestPoint('area_red')
end

function UpdateDragEmptyPipette()
    if DragObject and DragObject.What == 'EmptyPipette' then
        UpdateDrag()
    end
end

function StopDragEmptyPipette()
    local x = DragObject.Entity:GetX()
    local y = DragObject.Entity:GetY()
    DragObject.Entity:SetOpacity(0)
    local target = pf:FindObjectByPos(Vector(x, y))
    DragObject.Entity:SetOpacity(1)
    local time = 0.2
    
    if target and target:GetName() == 'area_red' and seashell_inplace then
        time = 0.5
        pf:GetObject('pipette_red'):ChangeOpacity(0, 1, 0.2)
        pipette_full = true
        
        PlaySound('17_UsePipette');
    end
    local delta_x = DragObject.InitX - DragObject.Entity:GetX()
    local delta_y = DragObject.InitY - DragObject.Entity:GetY()
    DragObject.Entity:Move(delta_x, delta_y, time)
    play_field:IgnoreOnTestPoint('area_red')
    StopDrag();
    DragObject = nil
end
------------------------------------------------
-- Full Pipette Drag
function StartDragFullPipette(obj)
    StartDrag(obj)
    DragObject.What = 'FullPipette'
end

function UpdateDragFullPipette()
    if DragObject and DragObject.What == 'FullPipette' then
        UpdateDrag()
    end
end

function StopDragFullPipette()
    local x = DragObject.Entity:GetX()
    local y = DragObject.Entity:GetY()
    DragObject.Entity:SetOpacity(0)
    local target = pf:FindObjectByPos(Vector(x, y))
    DragObject.Entity:SetOpacity(1)
    
    if target and target:GetName() == 'glass' and glass_inplace and not drip_inplace then
        pf:GetObject('pipette_01'):ChangeOpacity(1, 0, 0.2)
        pf:GetObject('drip'):ChangeOpacity(0, 1, 0.2)
        drip_inplace = true
        
        PlaySound('17_DripOnGlass');
        
        TimerDoString('FinishMiniGame()', 1, g_timer)
    else
        local delta_x = DragObject.InitX - DragObject.Entity:GetX()
        local delta_y = DragObject.InitY - DragObject.Entity:GetY()
        DragObject.Entity:Move(delta_x, delta_y, 0.2)
    end
    StopDrag();
    DragObject = nil
end
------------------------------------------------
-- Glass Drag
function StartDragGlass(obj)
    StartDrag(obj)
    DragObject.What = 'Glass'
end

function UpdateDragGlass()
    if DragObject and DragObject.What == 'Glass' then
        UpdateDrag()
    end
end

function StopDragGlass()    
    local delta_x = pf:GetObject('glass'):GetX() - DragObject.Entity:GetX()
    local delta_y = pf:GetObject('glass'):GetY() - DragObject.Entity:GetY()
    local margin = 50
    if math.abs(delta_x) < margin and math.abs(delta_y) < margin then
        DragObject.Entity:Move(delta_x, delta_y, 0.2)
        DragObject.Entity:ChangeOpacity(1, 0, 0.3)
        pf:GetObject('glass'):ChangeOpacity(0, 1, 0.3)
        glass_inplace = true
        
        PlaySound('17_GlassApply');
    else
        delta_x = DragObject.InitX - DragObject.Entity:GetX()
        delta_y = DragObject.InitY - DragObject.Entity:GetY()
        DragObject.Entity:Move(delta_x, delta_y, 0.2)
    end     
    StopDrag();
    DragObject = nil
end
------------------------------------------------

function OnUpdate(dt)
    DefaultOnUpdate(dt)
    --[[
    if DragObject then
        if DragObject.What == 'FullPipette' then
            UpdateDragFullPipette()
        elseif DragObject.What == 'EmptyPipette' then
            UpdateDragEmptyPipette()
        elseif DragObject.What == 'Glass' then
            UpdateDragGlass()
        elseif DragObject.What == 'Seashell' then
            UpdateDragSeashell()
        end
    end
    --]]
end

function FinishMiniGame()
    if not HasGameState('MiniGameCompleted', '17_Bedroom_Microscope') then
        AddGameState('MiniGameCompleted', '17_Bedroom_Microscope');
    end
    if not HasGameState('ClosedScene', game_state.scene_path) then
        AddGameState('ClosedScene', game_state.scene_path);
    end
    
    TimerDoString('StartLevel("'..game_state.parent_scene..'")', 1, g_timer)
end

function SkipMiniGame()
    if not seashell_inplace then
        pf:GetObject('seashell'):ChangeOpacity(1, 0, 0.1)
        pf:GetObject('red'):ChangeOpacity(0, 1, 0.2)
        seashell_inplace = true
        play_field:GetObject('red'):AddParticleSystem('data/ParticleSystem/Acid.psi',
                                                     'SmokeParticle',
                                                     true);
    end
    
    if not glass_inplace then
        pf:GetObject('glass_01'):ChangeOpacity(1, 0, 0.2);
        pf:GetObject('glass'):ChangeOpacity(0, 1, 0.2);
        glass_inplace = true;
    end
        
    if not drip_inplace then
        pf:GetObject('pipette_01'):ChangeOpacity(1, 0, 0.2)
        pf:GetObject('drip'):ChangeOpacity(0, 1, 0.2)
        drip_inplace = true    
    end

    TimerDoString('FinishMiniGame()', 2, g_timer)
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)
    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_entire' then
    --    ShowMonolog('C_17_NOT_ALL_TOOL_APPLIED', 'C_17_NOT_ALL_TOOL_APPLIED');
    --end
    
    if obj_name == 'area_entire' then
        ShowMonolog('C_17_NOT_ALL_TOOL_APPLIED', 'C_17_NOT_ALL_TOOL_APPLIED');
    end
    
    if pieces_to_apply == 0 then
        if obj_name == 'pipette_01' then
            if pipette_full then
                StartDragFullPipette(object)
            else
                StartDragEmptyPipette(object)
            end
        elseif obj_name == 'glass_01' then
            StartDragGlass(object)
        elseif obj_name == 'seashell' then
            StartDragSeashell(object)
        end
    end
    
    DefaultOnObjectMouseDownProcessed(is_wrong_click);
end

function OnObjectMouseUp(object)
    DefaultOnObjectMouseUp(object)
    if DragObject then
        if DragObject.What == 'FullPipette' then
            StopDragFullPipette()
        elseif DragObject.What == 'EmptyPipette'  then
            StopDragEmptyPipette()
        elseif DragObject.What == 'Glass' then
            StopDragGlass()
        elseif DragObject.What == 'Seashell' then
            StopDragSeashell()
        end
    end
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)
    
    if DragObject then
        if DragObject.What == 'FullPipette' then
            UpdateDragFullPipette()
        elseif DragObject.What == 'EmptyPipette' then
            UpdateDragEmptyPipette()
        elseif DragObject.What == 'Glass' then
            UpdateDragGlass()
        elseif DragObject.What == 'Seashell' then
            UpdateDragSeashell()
        end
    end
end

function OnSetTool(tool)
    DefaultOnSetTool(tool)
end

function LevelLoaded(level)
end

function OnSceneDestroy(playfield)
    DefaultOnSceneDestroy(playfield)
    
    if pipette_full then
        AddGameState(game_state.scene_path .. '_pipette_full', 'true')
    end
    if glass_inplace then
        AddGameState(game_state.scene_path .. '_glass_inplace', 'true') 
    end
    if seashell_inplace then
        AddGameState(game_state.scene_path .. '_seashell_inplace', 'true')
    end
    if drip_inplace then
        AddGameState(game_state.scene_path .. '_drip_inplace', 'true')
    end
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/Scenes/17_Bedroom/Zone_microscope/background.jpg',0,0,1024,768,1,0)
	anim:SetHotSpot(512,384)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('background',anim,512,384,100,0,1,1)
	local anim = CreateAnimation('data/Texture/Scenes/17_Bedroom/Zone_microscope/fishki.png',0,0,126,127,1,0)
	anim:SetHotSpot(63,63)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('fishki',anim,575,437,104,0,1,1)
	local anim = CreateAnimation('data/Texture/Scenes/17_Bedroom/Zone_microscope/red.png',0,0,254,264,1,0)
	anim:SetHotSpot(127,132)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('red',anim,289,408,102,0,1,1)
	local anim = CreateAnimation('data/Texture/Scenes/17_Bedroom/Zone_microscope/glass_01.png',0,0,126,106,1,0)
	anim:SetHotSpot(63,53)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('glass_01',anim,458,388,110,0,1,1)
	local anim = CreateAnimation('data/Texture/Scenes/17_Bedroom/Zone_microscope/glass.png',0,0,132,130,1,0)
	anim:SetHotSpot(66,65)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('glass',anim,564,467,103,0,1,1)
	local anim = CreateAnimation('data/Texture/Scenes/17_Bedroom/Zone_microscope/drip.png',0,0,79,72,1,0)
	anim:SetHotSpot(39,36)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('drip',anim,557,455,107,0,1,1)
	local anim = CreateAnimation('data/Texture/Scenes/17_Bedroom/Zone_microscope/microscope.png',0,0,651,768,1,0)
	anim:SetHotSpot(325,384)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('microscope',anim,698,392,102,0,1,1)
	local anim = CreateAnimation('data/Texture/Scenes/17_Bedroom/Zone_microscope/pipette_01.png',0,0,298,283,1,0)
	anim:SetHotSpot(42,45)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('pipette_01',anim,712,401,110,0,1,1)
	local anim = CreateAnimation('data/Texture/Scenes/17_Bedroom/Zone_microscope/pipette_red.png',0,0,123,133,1,0)
	anim:SetHotSpot(61,66)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('pipette_red',anim,743,432,111,0,1,1)
	local anim = CreateAnimation('data/Texture/Scenes/17_Bedroom/Zone_microscope/seashell.png',0,0,69,62,1,0)
	anim:SetHotSpot(34,31)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('seashell',anim,348,526,101,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_entire',anim,511,316,120,0,128,79)
	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_red',anim,231,347,105,0,34,37)
end

function FreeData(screen)
end
-- CLEAR_ON_SAVE_END
