dofile('data/Scripts/match3/panel/M3AbilitySlot.lua')

-------------------------------------------------------------------------------
class 'M3AbilitiesPanel' (EventDispatcher)
-------------------------------------------------------------------------------

M3AbilitiesPanel.APPEARING_DELAY_RANGE = 0.2
-------------------------------------------------------------------------------

function M3AbilitiesPanel:__init()
    EventDispatcher.__init(self)
    
    self.anchor = nil
    self.slotCursor = 'CursorActive'
    self.fastYSlotId   = nil

    self.bActive = true
    
    self.slots         = {}
    self.visibleSlots  = {}
    self.moveEffectors = {}
    
    self:createAnchor()
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:destroy()
    for id, slot in pairs(self.slots) do
        slot:destroy()
    end
    
    self.slots = nil    
    
    self.anchor:setRespondable(true)
    
    EventDispatcher.destroy(self)
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:registerEvents(dispatcher)
  
    -- dispatcher:addEventListener('ObjectMouseDown', bind(self.onObjectMouseDown, self))
    -- dispatcher:addEventListener('ObjectMouseOver', bind(self.onObjectMouseOver, self))
    -- dispatcher:addEventListener('ObjectMouseOut',  bind(self.onObjectMouseOut,  self))
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:createAnchor()
    local objectName = 'm3abilitiesPanelAnchor' 	
	
    local anim = CreateSpriteEntity('')
    anim:attachTo(current_scene:getPlayField():getMainEntity())
    anim:setAnimationSize(8, 8) 
    anim:setHotSpot(4, 4)
    anim:setName(objectName) 
    anim:setPosition(Vector2f(0, 0)) 
    anim:setOrder(1)
    anim:setColor(Colorf(1, 0, 0, 0.01))  

    self.anchor = anim
	self.anchor:setOpacity(1)	
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:createSlot(id, maxCount)
    local slot = M3AbilitySlot(id, maxCount)
    slot:getAnchor():attachTo(self.anchor)
    slot:addEventListener('SlotShow', bind(self.onSlotShow, self))
    slot:addEventListener('SlotHide', bind(self.onSlotHide, self))

    local area = slot:getArea()
    area.onClickBegin:add( bind(self.onObjectMouseDown, self) )
    area.onFocusIn:add( bind(self.onObjectMouseOver, self) )
    area.onFocusOut:add( bind(self.onObjectMouseOut, self) )
    
    self.slots[id] = slot
    return slot
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:getAnchor()
    return self.anchor
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:getSlot(id)
    return self.slots[id]
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:getAbilityCountsSaveString()
    local str = ''
    
    for ability, slot in pairs(self.slots) do
        if str ~= '' then
            str = str..'|'
        end
        
        str = str..ability..'='..tostring(slot:getCount())
    end
    
    return str
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:getAbilityFlyTargetPos(ability)
    for i, slot in ipairs(self.visibleSlots) do
        if slot.id == ability then
            local panelHeight = M3AbilitySlot.CLICKABLE_AREA_SIZE * #self.visibleSlots
            local anchorY     = -panelHeight / 2
            local slotY       = M3AbilitySlot.CLICKABLE_AREA_SIZE * i - M3AbilitySlot.CLICKABLE_AREA_SIZE/2
            
            return Vector2f(SCR_W + M3AbilitySlot.OPEN_X,
                          SCR_H/2 + anchorY + slotY)
        end
    end
    
    return nil
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:open()
    self.bOpening = true
    
    for ability, slot in pairs(self.slots) do
        local delayPercent = M3AbilitiesPanel.APPEARING_DELAY_RANGE * math.random()
        local delay        = M3AbilitySlot.APPEARING_TIME * delayPercent
        
        if slot:getCount() > 0 then
            slot:show(nil, delay)
        end
    end
    
    self.bOpening = false
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:close()
    self.bClosing = true
    
    for ability, slot in pairs(self.slots) do
        local delayPercent = M3AbilitiesPanel.APPEARING_DELAY_RANGE * math.random()
        local delay        = M3AbilitySlot.APPEARING_TIME * delayPercent
        
        slot:hide(nil, delay)
    end
    
    self.bClosing = false
end
-------------------------------------------------------------------------------


-------------------------------------------------------------------------------
-- EVENTS
-------------------------------------------------------------------------------

function M3AbilitiesPanel:onObjectMouseDown(entity)
    if not self.bActive then
        return
    end

    for ability, slot in pairs(self.slots) do
        if slot:getArea():getName() == entity:getName() then
            local event = {
                            eventName = 'AbilityChosen',
                            slot      = slot,
                            ability   = slot:getAbility()
                          }
            self:dispatchEvent(event)
            return
        end
    end
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:onObjectMouseOver(entity)
    if not self.bActive then
        return
    end

    for ability, slot in pairs(self.slots) do
        if slot:getArea():getName() == entity:getName() then
           -- SetCursor(self.slotCursor)
            return
        end
    end
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:onObjectMouseOut(entity)
    if not self.bActive then
        return
    end

    for ability, slot in pairs(self.slots) do
        if slot:getArea():getName() == entity:getName() then
           -- SetCursor('CursorDefault')
            return
        end
    end
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:onSlotShow(e)
    table.insert(self.visibleSlots, e.slot)
    
    self.fastYSlotId = e.slot.id
    self:_updateVisibleSlotsPos(e.time)
end
-------------------------------------------------------------------------------

function M3AbilitiesPanel:onSlotHide(e)
    for i, slot in ipairs(self.visibleSlots) do
        if slot.id == e.slot.id then
            table.remove(self.visibleSlots, i)
            self:_updateVisibleSlotsPos(e.time)
            return
        end
    end
end
-------------------------------------------------------------------------------


-------------------------------------------------------------------------------
-- PRIVATE
-------------------------------------------------------------------------------

function M3AbilitiesPanel:_updateVisibleSlotsPos(time)
    for i, effector in ipairs(self.moveEffectors) do
        effector:destroy()
    end
    self.moveEffectors = {}
    
    for i, slot in ipairs(self.visibleSlots) do
        local y        = M3AbilitySlot.CLICKABLE_AREA_SIZE * i - M3AbilitySlot.CLICKABLE_AREA_SIZE/2
        local object   = slot:getAnchor()
        
        if self.fastYSlotId == slot.id  then
            self.fastYSlotId = nil
            object:setY(y)
        else
            local effector = CreateAnimationEffector()
            effector:setDestroysOnEnd(false)
            effector:attachTo(object)
            effector:setKey(_TRACK_Y, 0,    object:getY())
            effector:setKey(_TRACK_Y, time, y)
            effector:play()
            
            table.insert(self.moveEffectors, effector)
        end
    end
    
    if not self.bClosing then
        local panelHeight = M3AbilitySlot.CLICKABLE_AREA_SIZE * #self.visibleSlots
        local targetY = -panelHeight / 2
        
        if self.bOpening then
            self.anchor:setY(targetY)
        else
            local effector = self.anchor:MoveTo(self.anchor:getX(), targetY, time)
            effector:setDestroysOnEnd(false)
            
            table.insert(self.moveEffectors, effector)
        end
    end
end
-------------------------------------------------------------------------------

