class 'M3Cell'
-------------------------------------------------------------------------------

M3Cell.TILE_Z        = 1
M3Cell.FLAT_BORDER_Z = 2
M3Cell.VERT_BORDER_Z = 3
M3Cell.CORNER_Z      = 4
M3Cell.GLOW_Z        = 5
M3Cell.ITEM_ANCHOR_Z = 6

M3Cell.CELL_SIZE      = 46
M3Cell.HALF_CELL_SIZE = M3Cell.CELL_SIZE / 2
M3Cell.INNER_CORNER_THICKNESS = 2

M3Cell.EBorderId = {
                    LBORDER = 1,
                    RBORDER = 2,
                    TBORDER = 3,
                    BBORDER = 4,
                    LTCORNERIN = 5,
                    LBCORNERIN = 6,
                    RTCORNERIN = 7,
                    RBCORNERIN = 8,
                    LTCORNEROUT = 9,
                    LBCORNEROUT = 10,
                    RTCORNEROUT = 11,
                    RBCORNEROUT = 12
                   }

-------------------------------------------------------------------------------

function M3Cell:__init(col, row)
    self.col = col   -- положение ячейки по оси x
    self.row = row   -- положение ячейки по оси y
    
    self.anchor       = nil   -- Entity, к которой будут аттачится спрайт плитки, рамка...
    self.borderAnchor = nil
    self.itemAnchor   = nil
    self.tile         = nil   -- GameObject, отображающий плитку
    self.item         = nil   -- экземпляр класса M3Item
    
    self.comboId = 0
    
    self.swapId       = nil    -- идентификатор операции смены ячеек
	self.bFocused     = false  -- наведен ли курсор на ячейку
	self.bSelected    = false  -- выбрана ли ячейка
	self.bCombination = false
	self.bPassable    = false  -- моджет ли предмет падать вниз, находясь в данной ячейке (имеются в виду самые нижние ячейки)
	self.bFallable    = true
	
	self:createAnchors()
	self:createTile()
end
-------------------------------------------------------------------------------

function M3Cell:destroy()
    if self.item then
        self.item:destroy()
        self.item = nil
    end
    
    --TODO: remove all borders from play_field:IgnoreOnTestPoint
    self.tile:destroy()
    self.itemAnchor:destroy()
    self.borderAnchor:destroy()
    self.anchor:destroy()
end
-------------------------------------------------------------------------------

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

function M3Cell:getItem()
    return self.item
end
-------------------------------------------------------------------------------

function M3Cell:getCenterPos()
    return Vector2f(self.anchor:getX() + self.itemAnchor:getX(),
                  self.anchor:getY() + self.itemAnchor:getY())
end
-------------------------------------------------------------------------------

function M3Cell:getComboId()
    return self.comboId
end
-------------------------------------------------------------------------------

--[[
--  Создает "якорный" объект, к которому будет аттачится контент ячейки
--]]
function M3Cell:createAnchors()
    local cellAnchorName   = 'cellAnchor_'..tostring(self.col)..'_'..tostring(self.row)
    local borderAnchorName = 'borderAnchor_'..tostring(self.col)..'_'..tostring(self.row)
    local itemAnchorName   = 'itemAnchor_'..tostring(self.col)..'_'..tostring(self.row)
    
    self.anchor = CreateSpriteEntity('')      
    self.anchor:setName(cellAnchorName)
    self.anchor:setOrder(1)
    self.anchor:setXY(self.col * M3Cell.CELL_SIZE,
                      self.row * M3Cell.CELL_SIZE)
    
    self.borderAnchor = CreateSpriteEntity('')
    self.borderAnchor:attachTo(self.anchor)
    self.borderAnchor:setName(borderAnchorName)
    self.borderAnchor:setOrder(0)
    self.borderAnchor:setXY(0, 0)
    
    self.itemAnchor = CreateSpriteEntity('')
    self.itemAnchor:attachTo(self.anchor)
    self.itemAnchor:setName(itemAnchorName)
    self.itemAnchor:setOrder(M3Cell.ITEM_ANCHOR_Z)
    self.itemAnchor:setXY(M3Cell.HALF_CELL_SIZE,
                          M3Cell.HALF_CELL_SIZE)
end
-------------------------------------------------------------------------------

function M3Cell:createTile()
    local anim
    local object
    
    local objectName = 'tile_'..tostring(self.col)..'_'..tostring(self.row)
    local texture    = M3Game.TEXTURE_PATH..'tile.png'
    local bEvenCell  = math.fmod(self.row + self.col, 2) == 0
    local opacity    = bEvenCell and 0.5 or 1
    
  --  anim = CreateAnimation(texture,0,0,M3Cell.CELL_SIZE,M3Cell.CELL_SIZE,1,0)

    anim = CreateSpriteEntity(texture)   

	anim:setHotSpot(M3Cell.HALF_CELL_SIZE, M3Cell.HALF_CELL_SIZE)
    anim:attachTo(self.anchor)
    anim:setColor(Colorf(1, 1, 1, 0.1))  
    anim:setOrder(M3Cell.TILE_Z)  
    anim:setXY(M3Cell.HALF_CELL_SIZE, M3Cell.HALF_CELL_SIZE)  
    anim:setName(objectName)  
	anim:setAnimationSize(M3Cell.CELL_SIZE, M3Cell.CELL_SIZE)  
    anim:setOpacity(opacity)

    anim:setSendEventsToParent(true)
	
	self.tile = anim
end
-------------------------------------------------------------------------------

function M3Cell:createBorder(borderId)
    local texture
    local anim
    local object
    local objectName = 'botder'..tostring(borderId)..'_'..
                                 tostring(self.col)..'_'..
                                 tostring(self.row)
    
    if borderId == M3Cell.EBorderId.LBORDER then
        texture = M3Game.TEXTURE_PATH..'Borders/border_left.png'
        
        anim = CreateSpriteEntity(texture)
        anim:setHotSpot(6,0)
        anim:setColor(Colorf(1, 1, 1, 1))  
        anim:setName(objectName) 
        anim:setOrder(M3Cell.VERT_BORDER_Z)
        anim:setAnimationSize(12, 46)
        anim:setXY(0, 0)   

        object = anim  
        
    elseif borderId == M3Cell.EBorderId.RBORDER then
        texture = M3Game.TEXTURE_PATH..'Borders/border_left.png' 

        anim = CreateSpriteEntity(texture)
        anim:setHotSpot(6,0)
        anim:setColor(Colorf(1, 1, 1, 1))  
        anim:setName(objectName) 
        anim:setOrder(M3Cell.VERT_BORDER_Z)
        anim:setAnimationSize(12, 46)
        anim:setXY(M3Cell.CELL_SIZE, 0)   
        anim:setScaleX(-1)

        object = anim  
        
    elseif borderId == M3Cell.EBorderId.TBORDER then
        texture = M3Game.TEXTURE_PATH..'Borders/border_top.png'      

        anim = CreateSpriteEntity(texture)
        anim:setHotSpot(0,6)
        anim:setColor(Colorf(1, 1, 1, 1))  
        anim:setName(objectName) 
        anim:setOrder(M3Cell.FLAT_BORDER_Z)
        anim:setAnimationSize(46, 12)
        anim:setXY(0, 0)   

        object = anim  
        
    elseif borderId == M3Cell.EBorderId.BBORDER then
        if self.bPassable then
            texture = M3Game.TEXTURE_PATH..'Borders/border_bottom_pass.png'    

            anim = CreateSpriteEntity(texture)
            anim:setHotSpot(0,6)
            anim:setColor(Colorf(1, 1, 1, 1))  
            anim:setName(objectName) 
            anim:setOrder(M3Cell.FLAT_BORDER_Z)
            anim:setAnimationSize(46, 12)
            anim:setXY(0, M3Cell.CELL_SIZE) 

            object = anim   
        else
            texture = M3Game.TEXTURE_PATH..'Borders/border_bottom.png' 

            anim = CreateSpriteEntity(texture)
            anim:setHotSpot(0,6)
            anim:setColor(Colorf(1, 1, 1, 1))  
            anim:setName(objectName) 
            anim:setOrder(M3Cell.FLAT_BORDER_Z)
            anim:setAnimationSize(46, 12)
            anim:setXY(0, M3Cell.CELL_SIZE)

            object = anim  
        end       
        
    elseif borderId == M3Cell.EBorderId.LTCORNERIN then
        texture = M3Game.TEXTURE_PATH..'Borders/corner.png'

        anim = CreateSpriteEntity(texture)
        anim:setHotSpot(6,6)
        anim:setColor(Colorf(1, 1, 1, 1))  
        anim:setName(objectName) 
        anim:setOrder(M3Cell.CORNER_Z)
        anim:setAnimationSize(12, 12)
        anim:setXY(-M3Cell.INNER_CORNER_THICKNESS, M3Cell.INNER_CORNER_THICKNESS)
        anim:setScale(0.8)
        anim:setRotationDeg(90)   

        object = anim 
    
    elseif borderId == M3Cell.EBorderId.RBCORNERIN then
        texture = M3Game.TEXTURE_PATH..'Borders/corner.png'

        anim = CreateSpriteEntity(texture)
        anim:setHotSpot(6,6)
        anim:setColor(Colorf(1, 1, 1, 1))  
        anim:setName(objectName) 
        anim:setOrder(M3Cell.CORNER_Z)
        anim:setAnimationSize(12, 12)
        anim:setXY(M3Cell.CELL_SIZE + M3Cell.INNER_CORNER_THICKNESS, M3Cell.CELL_SIZE - M3Cell.INNER_CORNER_THICKNESS)
        anim:setScale(0.8)
        anim:setRotationDeg(-90)   

        object = anim   
    
    elseif borderId == M3Cell.EBorderId.RTCORNERIN then
        texture = M3Game.TEXTURE_PATH..'Borders/corner.png'

        anim = CreateSpriteEntity(texture)
        anim:setHotSpot(6,6)
        anim:setColor(Colorf(1, 1, 1, 1))  
        anim:setName(objectName) 
        anim:setOrder(M3Cell.CORNER_Z)
        anim:setAnimationSize(12, 12)
        anim:setXY(M3Cell.CELL_SIZE + M3Cell.INNER_CORNER_THICKNESS, M3Cell.INNER_CORNER_THICKNESS)
        anim:setScale(0.8)
        anim:setRotationDeg(0)  

        object = anim     

    elseif borderId == M3Cell.EBorderId.LBCORNERIN then
        texture = M3Game.TEXTURE_PATH..'Borders/corner.png'

        anim = CreateSpriteEntity(texture)
        anim:setHotSpot(6,6)
        anim:setColor(Colorf(1, 1, 1, 1))  
        anim:setName(objectName) 
        anim:setOrder(M3Cell.CORNER_Z)
        anim:setAnimationSize(12, 12)
        anim:setXY(-M3Cell.INNER_CORNER_THICKNESS, M3Cell.CELL_SIZE - M3Cell.INNER_CORNER_THICKNESS)
        anim:setScale(0.8)
        anim:setRotationDeg(180)  

        object = anim        
    
    elseif borderId == M3Cell.EBorderId.LTCORNEROUT then
        texture = M3Game.TEXTURE_PATH..'Borders/corner.png'

        anim = CreateSpriteEntity(texture)
        anim:setHotSpot(6,6)
        anim:setColor(Colorf(1, 1, 1, 1))  
        anim:setName(objectName) 
        anim:setOrder(M3Cell.CORNER_Z)
        anim:setAnimationSize(12, 12)
        anim:setXY(0, 0)        

        object = anim 
             
    elseif borderId == M3Cell.EBorderId.RBCORNEROUT then
        texture = M3Game.TEXTURE_PATH..'Borders/corner.png'

        anim = CreateSpriteEntity(texture)
        anim:setHotSpot(6,6)
        anim:setColor(Colorf(1, 1, 1, 1))  
        anim:setName(objectName) 
        anim:setOrder(M3Cell.CORNER_Z)
        anim:setAnimationSize(12, 12)
        anim:setXY(M3Cell.CELL_SIZE, M3Cell.CELL_SIZE)        
        anim:setRotationDeg(180)  

        object = anim 
    
    elseif borderId == M3Cell.EBorderId.RTCORNEROUT then
        texture = M3Game.TEXTURE_PATH..'Borders/corner.png'

        anim = CreateSpriteEntity(texture)
        anim:setHotSpot(6,6)
        anim:setColor(Colorf(1, 1, 1, 1))  
        anim:setName(objectName) 
        anim:setOrder(M3Cell.CORNER_Z)
        anim:setAnimationSize(12, 12)
        anim:setXY(M3Cell.CELL_SIZE, 0)        
        anim:setRotationDeg(90)  

        object = anim        
                                         
    elseif borderId == M3Cell.EBorderId.LBCORNEROUT then
        texture = M3Game.TEXTURE_PATH..'Borders/corner.png'

        anim = CreateSpriteEntity(texture)
        anim:setHotSpot(6,6)
        anim:setColor(Colorf(1, 1, 1, 1))  
        anim:setName(objectName) 
        anim:setOrder(M3Cell.CORNER_Z)
        anim:setAnimationSize(12, 12)
        anim:setXY(0, M3Cell.CELL_SIZE)        
        anim:setRotationDeg(-90)  

        object = anim   
       
    end
    
    object:attachTo(self.borderAnchor)

    object:setRespondable(false)
end
-------------------------------------------------------------------------------

function M3Cell:show(time, delay)
    self.borderAnchor:ChangeOpacity(0, 1, delay)
    
    local scaleFrom = 1.5
    local effector = CreateAnimationEffector()
    effector:setDestroysOnEnd(true)
    effector:attachTo(self.anchor)    
    
    effector:setKey(_TRACK_O, 0, 0)
    effector:setKey(_TRACK_O, delay, 0)
    effector:setKey(_TRACK_O, delay + time, 1)
    
    effector:setKey(_TRACK_S, 0,            scaleFrom)
    effector:setKey(_TRACK_S, delay,        scaleFrom)
    effector:setKey(_TRACK_S, delay + time, 1)
    
    effector:play()
end
-------------------------------------------------------------------------------

function M3Cell:hide(time, delay)
    self.borderAnchor:ChangeOpacity(1, 0, delay)
    
    local scaleTo = 1.5
    local effector = CreateAnimationEffector()
    effector:setDestroysOnEnd(true)
    effector:attachTo(self.anchor)
    
    effector:setKey(_TRACK_O, 0, 1)
    effector:setKey(_TRACK_O, delay, 1)
    effector:setKey(_TRACK_O, delay + time, 0)
    
    effector:setKey(_TRACK_S, 0,            1)
    effector:setKey(_TRACK_S, delay,        1)
    effector:setKey(_TRACK_S, delay + time, scaleTo)
    
    effector:play()
end
-------------------------------------------------------------------------------

function M3Cell:glow()
    if not self.glowAnim then
        local scale = 2
        local objectName = 'glow_'..tostring(self.col)..'_'..tostring(self.row)
        local texture    = M3Game.TEXTURE_PATH..'/Anims/glowAnim.png'    
      
        local anim = CreateSpriteEntity(texture)
        anim:attachTo(self.anchor)
        anim:setAnimationSize(46, 46) 
        anim:setHotSpot(23,23)
        anim:setFramesCount(24)
        anim:setFPS(24)
        anim:setName(objectName) 
        anim:setPosition(Vector2f(0, 0)) 
        anim:setOrder(M3Cell.GLOW_Z)
        anim:setScale(scale) 
        anim:setX(self.itemAnchor:getX())
        anim:setY(self.itemAnchor:getY())

        self.glowAnim = anim
    end
    
    self.glowAnim:setVisible(true)
    self.glowAnim:setFrame(0)
    self.glowAnim:play()
    
    current_scene:getPlayField().timer:add(function()
                                     self.glowAnim:setVisible(false)
                                end, 1)
end
-------------------------------------------------------------------------------

function M3Cell:setItem(item)
    self.item = item
    
    if self.item then
        local anchor = self.item:getAnchor()
        local scrX   = anchor:getScrX()
        local scrY   = anchor:getScrY()
        
        anchor:attachTo(self.itemAnchor)
        anchor:setScrX(scrX)
	    anchor:setScrY(scrY)
    end
end
-------------------------------------------------------------------------------

function M3Cell:setFocused(bFocused)
    if self.bFocused ~= bFocused then
        self.bFocused = bFocused
    end
end
-------------------------------------------------------------------------------

function M3Cell:setSelected(bSelected)
    if self.bSelected ~= bSelected then
        self.bSelected = bSelected
        
        self.item:setSelected(bSelected)
    end
end
-------------------------------------------------------------------------------

function M3Cell:setCombination(bCombination)
    self.bCombination = bCombination
end
-------------------------------------------------------------------------------

function M3Cell:setComboId(comboId)
    self.comboId = comboId
end
-------------------------------------------------------------------------------

function M3Cell:setPassable(bPassable)
    self.bPassable = bPassable
end
-------------------------------------------------------------------------------

function M3Cell:isFocused()
    return self.bFocused
end
-------------------------------------------------------------------------------

function M3Cell:isSelected()
    return self.bSelected
end
-------------------------------------------------------------------------------

function M3Cell:isCombination()
    return self.bCombination
end
-------------------------------------------------------------------------------

function M3Cell:isTile(objectName)
    return self.tile:getName() == objectName
end
-------------------------------------------------------------------------------

function M3Cell:isPassable()
    return self.bPassable
end
-------------------------------------------------------------------------------
