class 'l_10_hotel_z_lock' (ZoomEventHandler)

function l_10_hotel_z_lock:__init(name)
    ZoomEventHandler.__init(self, name)
    
    play_field:IgnoreOnTestPoint('z_lock_cover')
    ObjectVisible('area_click_zc_open_doors', false)
    
    self.SLOT_WIDTH  = 48
    self.SLOT_HEIGHT = 51
    
    self.AREA_HEIGHT = 80
    self.LINE_OFFSET_Y = - (51 - (self.AREA_HEIGHT-self.SLOT_HEIGHT) / 2)
    
    self.SLOTS_COUNT = 4
    self.POS_COUNT   = 9
    self.MOVE_TIME   = 0.3
    
    self.anchor = Object('area_slots_anchor')
    self.slots = {}
    self.startPopes   = {5,7,1,4}
    self.correctPoses = {1,1,1,1}
    self.clippingRect = {   self.zone.empty_obj:GetScrX() - 175 + 90,  -- x
                            self.zone.empty_obj:GetScrY() - 175 + 110,  -- y
                            220,                                        -- width
                            165                                         -- height
                        }
    
    for id=1, self.SLOTS_COUNT do
        self:createSlot(id)
    end
    
    if self:IsComplete() then
        self:OnComplete(true)
    end
    
    if IsToolApplied('11_binoculars') then
        ObjectVisible('area_hint_zl_no_code', false)
    else
        for id, slot in pairs(self.slots) do
            slot.area:SetVisible(false)
        end
        
        RegisterMonologObject('area_hint_zl_no_code', 'BBT_10_NO_CODE')
    end
end
-------------------------------------------------------------------------------

function l_10_hotel_z_lock:createSlot(id)
    local slot = {}
    slot.id        = id
    slot.saveState = 'SCENE_10_LOCK_LINE_POS_'..tostring(id)
    slot.pos       = HasGameState(slot.saveState) and tonumber(GetGameState(slot.saveState):Get(0))
                                                   or self.startPopes[id] --self:GetRandomPos(id)
    slot.bCorrect  = (slot.pos == self.correctPoses[id])
    self.slots[id] = slot
    
    SetGameState(slot.saveState, tostring(slot.pos))
    
    -- add line
    do
        slot.line = Object('z_lock_numbers_'..tostring(id))
        slot.line:AttachTo(self.anchor)
        slot.line:SetZ(1)
        
        local textureWidth = 46
        local dx = self.SLOT_WIDTH - textureWidth
        
        slot.line:SetX(self.SLOT_WIDTH  * (id - 1) + dx/2)
        slot.line:SetY(-self.SLOT_HEIGHT * (slot.pos - 1) + self.LINE_OFFSET_Y)
        slot.line:SetClippingRect(unpack(self.clippingRect))
    end
    
    -- create area
    do
        local areaName = 'area_'..slot.line:GetName()
        local anim     = CreateAnimationByTextureName('data/Texture/Common/area.png')
        local scaleX   = self.SLOT_WIDTH  / anim:GetWidth()
        local scaleY   = self.AREA_HEIGHT / anim:GetHeight()
        
        anim:SetHotSpot(0, 0)
        anim:SetColor('0x01FFFFFF')
        
        slot.area = play_field:CreateObject(areaName,anim,0,0,1,0,scaleX,scaleY)
        self.zone:AddObject(areaName)
        
        slot.area:AttachTo(self.anchor)
        slot.area:SetZ(2)
        slot.area:SetX(self.SLOT_WIDTH * (id - 1))
        slot.area:SetY(0)
        
        GetCurrentLevel().ignore_on_highlight[areaName] = true
    end
    
    -- callback
    do
        local function on_click(e)
            if e.save then
                return
            end
            
            local level = GetCurrentLevel()
            local id    = tonumber(string.sub(e.target, -1))
            local slot  = self.slots[id]
            local nextPos = (slot.pos < self.POS_COUNT) and slot.pos + 1 or 1
            
            self:SetSlotPos(slot, nextPos, self.MOVE_TIME)
            
            if self:IsComplete() then
                AddActionCompletedState('lockOpened')
                
                level.timer:Add(function()
                                    self:OnComplete(false)
                                end,
                                self.MOVE_TIME)
            end
        end
        
        RegisterActiveObject(slot.area:GetName(), on_click, true)
    end
end
-------------------------------------------------------------------------------

function l_10_hotel_z_lock:GetRandomPos(id)
    local pos
    
    repeat
        pos = math.random(self.POS_COUNT)
    until pos ~= self.correctPoses[id]
    
    return pos
end
-------------------------------------------------------------------------------

function l_10_hotel_z_lock:SetSlotPos(slot, pos, time)
    time = time or 0
    
    SetGameState(slot.saveState, tostring(pos))
    
    slot.pos = pos
    slot.bCorrect = (pos == self.correctPoses[slot.id])
    
    if time == 0 then
        local y = -self.SLOT_HEIGHT * (pos - 1)
        slot.line:SetY(y + self.LINE_OFFSET_Y)
    else
        local bNeedReserve = (pos == 1 or pos == self.POS_COUNT)
        local newPos = pos
        local level  = GetCurrentLevel()
        
        if bNeedReserve then
            if pos == 1 then
                pos = self.POS_COUNT + 1
            end
        end
        
        local y     = -self.SLOT_HEIGHT * (pos - 1) + self.LINE_OFFSET_Y
        local yDist = y - slot.line:GetY()
        local eff   = CreateAnimationEffector()
        
        eff:SetDestroysOnEnd(false)
        eff:AttachTo(slot.line)
        eff:SetKey(_TRACK_Y, 0.0,         slot.line:GetY())
        eff:SetKey(_TRACK_Y, time * 0.5,  y + yDist*0.05)
        eff:SetKey(_TRACK_Y, time * 0.75, y - yDist*0.025)
        eff:SetKey(_TRACK_Y, time * 0.90, y + yDist*0.012)
        eff:SetKey(_TRACK_Y, time, y)
        eff:Play()
        
        level.mouseBlocker:Push()
        level.timer:Add(function()
                            level.mouseBlocker:Pop()
                            eff:Destroy()
                            
                            if bNeedReserve then
                                if newPos == 1 then
                                    slot.line:SetY(self.LINE_OFFSET_Y)
                                end
                            end
                        end,
                        time)
    end
end
-------------------------------------------------------------------------------

function l_10_hotel_z_lock:IsComplete()
    for id, slot in ipairs(self.slots) do
        if not slot.bCorrect then
            return false
        end
    end
    
    return true
end
-------------------------------------------------------------------------------

function l_10_hotel_z_lock:OnComplete(save)
    for id, slot in pairs(self.slots) do
        slot.area:SetVisible(false)
    end
    
    if save then
        self.zone:Disable()
        ObjectVisible('area_click_zc_open_doors', true)
    else
        local level = GetCurrentLevel()
        self.zone:CloseAndDisable()
        
        level.mouseBlocker:Push()
        level.timer:Add(function()
                            level.mouseBlocker:Pop()
                            ObjectVisible('area_click_zc_open_doors', true)
                        end,
                        ZOOM_ZONE_APPEARING_TIME)
    end
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
-- CLEAR_ON_SAVE_BEGIN
-- Do not edit code listed below (generated by the editor on each save)
function l_10_hotel_z_lock:LoadData(screen)
	local anim
	anim = CreateAnimation('data/Texture/Scenes/10_hotel/main/z_lock/z_lock_bg.png',0,0,350,350,1,0)
	anim:SetHotSpot(175,175)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('z_lock_bg',anim,512,384,50,0,1,1)
	
	anim = CreateAnimation('data/Texture/Scenes/10_hotel/main/z_lock/z_lock_arc.png',0,0,160,280,1,0)
	anim:SetHotSpot(80,140)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('z_lock_arc',anim,450,390,51,0,1,1)
	
	anim = CreateAnimation('data/Texture/Scenes/10_hotel/main/z_lock/z_lock_body.png',0,0,306,272,1,0)
	anim:SetHotSpot(153,136)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('z_lock_body',anim,535,407,52,0,1,1)
	
	anim = CreateAnimation('data/Texture/Common/area.png',0,0,8,8,1,0)
	anim:SetHotSpot(0,0)
	anim:SetBlendMode(2)
	anim:SetColor('0x01FFFFFF')
	screen:CreateObject('area_slots_anchor',anim,435,406,60,-26,1,1)
	
	anim = CreateAnimation('data/Texture/Common/area.png',0,0,8,8,1,0)
	anim:SetHotSpot(4,4)
	anim:SetBlendMode(2)
	anim:SetColor('0x01FFFFFF')
	screen:CreateObject('area_hint_zl_no_code',anim,530,399,100,-26,30,16)
	
	anim = CreateAnimation('data/Texture/Scenes/10_hotel/main/z_lock/z_lock_cover.png',0,0,350,350,1,0)
	anim:SetHotSpot(175,175)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('z_lock_cover',anim,512,384,90,0,1,1)
	
	anim = CreateAnimation('data/Texture/Scenes/10_hotel/main/z_lock/z_lock_numbers.png',0,0,46,612,1,0)
	anim:SetHotSpot(0,0)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('z_lock_numbers_1',anim,40,233,100,0,1,1)
	
	anim = CreateAnimation('data/Texture/Scenes/10_hotel/main/z_lock/z_lock_numbers.png',0,0,46,612,1,0)
	anim:SetHotSpot(0,0)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('z_lock_numbers_2',anim,220,237,100,0,1,1)
	
	anim = CreateAnimation('data/Texture/Scenes/10_hotel/main/z_lock/z_lock_numbers.png',0,0,46,612,1,0)
	anim:SetHotSpot(0,0)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('z_lock_numbers_3',anim,171,238,100,0,1,1)
	
	anim = CreateAnimation('data/Texture/Scenes/10_hotel/main/z_lock/z_lock_numbers.png',0,0,46,612,1,0)
	anim:SetHotSpot(0,0)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('z_lock_numbers_4',anim,100,231,100,0,1,1)
	
end
-- CLEAR_ON_SAVE_END
