class 'M3AbilityLogicTorch' (M3AbilityLogicBase)
-------------------------------------------------------------------------------

function M3AbilityLogicTorch:__init(ability, field)
    M3AbilityLogicBase.__init(self, ability, field)
end
-------------------------------------------------------------------------------

function M3AbilityLogicTorch:affect(cell)
    M3AbilityLogicBase.affect(self, cell)
    
    local indexes = self:_getItems(cell.col, cell.row)
    local depthDelay = 0.2
    
    for index, depth in pairs(indexes) do
        local row  = math.floor(index / self.pField.cols)
        local col  = index - row * self.pField.cols
        local cell = self.pField:getCell(col, row)
        local item = cell:getItem()
        
        if depth == 0 then
            self.pField:resetFlyingCharge(cell)
            
            if item:isLocked() then
                self.pField:setItemLocked(item, false, 2)
            else
                item:crash()
            end
        else
            local field = self.pField
            item.bAnimating = true
            
            field.timer:Add(function()
                                field:resetFlyingCharge(cell)
                                
                                if item:isLocked() then
                                    field:setItemLocked(item, false, 2)
                                else
                                    item:crash()
                                end
                            end,
                            depthDelay * depth)
        end
    end
    
    self.pField:_getTorchAnim(cell.col, cell.row)
    self.pField:playSound('m3_torch', true)
end
-------------------------------------------------------------------------------

function M3AbilityLogicTorch:canAffect(cell)
    return M3AbilityLogicBase.canAffect(self, cell) or self:_additionalCanAffect(cell)
end
-------------------------------------------------------------------------------


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

function M3AbilityLogicTorch:_getItems(col, row)
    local marcked = {}
    local checked = {}
    
    local function checkWave(col, row, depth)
        depth = depth and depth + 1 or 1
        
        local nearby = {}
        table.insert(nearby, {col + 1, row})
        table.insert(nearby, {col - 1, row})
        table.insert(nearby, {col, row + 1})
        table.insert(nearby, {col, row - 1})
        
        for i, pos in ipairs(nearby) do
            local c = pos[1]
            local r = pos[2]
            local item = self.pField:getItem(c, r)
            
            if item then
                local index = r * self.pField.cols + c
                
                if not checked[index] then
                    checked[index] = true
                    
                    if not marcked[index] then
                        local cell = self.pField:getCell(c, r)
                        
                        if self:canAffect(cell) then
                            marcked[index] = depth
                            checkWave(c, r, depth)
                        end
                    end
                end
            end
        end
    end
    
    local index = row * self.pField.cols + col
    marcked[index] = 0
    checked[index] = true
    checkWave(col, row)
    
    return marcked
end
-------------------------------------------------------------------------------

function M3AbilityLogicTorch:_additionalCanAffect(cell)
     local item = cell:getItem()
    
    return not self.pField.bShuffle    and
            item                       and
            item:isLocked()            and
            item:isCalm()              and
            not item.ability
end
-------------------------------------------------------------------------------
