class 'HiddenObjectIndicator'

function HiddenObjectIndicator:__init()
    -- constants
    self.MAIN_TASKS_COUNT =  12
    
    self.TASKS_X  = -300
    self.TASKS_Y  =  3
    self.TASKS_DY =  20
    self.WIDTH    =  640
    
    self.ADDITIONAL_TASKS_X  = -500
    self.ADDITIONAL_TASKS_Y  = -700
    self.ADDITIONAL_TASKS_DY =  30
    
    --self.TEXT_SCALE          = 0.95
    --self.TEXT_TRACKING       = -9
    self.SIMPLE_OBJECT_COLOR = '0xFFFFFFFF'
    self.ACTIVE_OBJECT_COLOR = '0xFFDE821F'
    
    -- init
    self.anchor  = self:_createAnchor()
    self.strings = {}
    self.visible = true
    
    self.cols = 4
    self.rows = math.ceil(self.MAIN_TASKS_COUNT / self.cols)
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:Fill()
    local tasksOrder = self:_getSortedTasksMap()
    self:_calculateTasksPos(tasksOrder)
    
    for _, taskInfo in pairs(tasksOrder) do
        local task  = taskInfo.task
        local field = self:_createTextField(task)
        field:SetXY(taskInfo.x, taskInfo.y)
        
        local info = {}
        info.field = field
        info.x     = taskInfo.x
        info.y     = taskInfo.y
        
        local key = task:GetTextSingular()
        self.strings[key] = info
        
        self:UpdateCaption(task, true)
        self:UpdateCaptionColor(task)
    end
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:SetVisible(visible, time)
    if self.visible ~= visible then
        self.visible = visible
        
        local opacity = visible and 1 or 0
        time = time or 0
        
        if time then
            self.anchor:ChangeOpacity(self.anchor:GetOpacity(), opacity, time)
        else
            self.anchor:SetOpacity(opacity)
        end
    end
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:GetAnchor()
    return self.anchor
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:GetField(task)
    local key = task:GetTextSingular()
    
    if self.strings[key] then
        return self.strings[key].field
    end
    
    return nil
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:GetTaskPos(task)
    local key   = task:GetTextSingular()
    local field = self.strings[key].field
    
    return Vector(field:GetScrX(), field:GetScrY())
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:UpdateCaption(task, save)
    local field   = self:GetField(task)
    local caption = self:_getTaskCaption(task)
    
    field:SetText(caption)
    
    local objectsCount = task:GetNumberOfObjects() +
                         task:GetNumberOfObjectsWithFindAnimationPlaying()
                         
    if objectsCount <= 0 then
        self:_strikeOutCaption(field, save)
    end
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:UpdateCaptionColor(task)
    local field = self:GetField(task)
	
	if field then
        if task:HasActionObject() then
            field:SetColor(self.ACTIVE_OBJECT_COLOR)
        else
            field:SetColor(self.SIMPLE_OBJECT_COLOR)
        end
    end
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:_getTaskCaption(task)
    local objectsCount = task:GetNumberOfObjects() + task:GetNumberOfObjectsWithFindAnimationPlaying()
    local caption = GetString(task:GetTextSingular())
    
    if objectsCount > 1 then
        caption = caption..' x'..tostring(objectsCount)
    end
    
    return caption
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:_getTaskCaptionWidth(task)
    local text = self:_getTaskCaption(task)
    local te   = CreateTextEntity(ITEMS_FONT, '')
    
    --te:SetScale(self.TEXT_SCALE)
 --   te:SetTracking(self.TEXT_TRACKING)
    local width = te:GetWidth(text)
    te:Destroy()
    
    return width
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:_getSortedTasksMap()
    local tasks = play_field:GetLevelScreen():GetTasks()
    local map   = {}
            
    for task in tasks do
        local info = {}
        info.task  = task
        info.width = self:_getTaskCaptionWidth(task)
        info.x     = 0
        info.y     = 0
        
        table.insert(map, info)
    end
    
    local mapSize = #map
    
    for i=1, mapSize-1 do
        for j = i+1, mapSize do
            if map[i].width < map[j].width then
                map[i], map[j] = map[j], map[i]
            end
        end
    end
    
    return map
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:_getColumnWidths(sortedTasksMap)
    local tasksCount       = #sortedTasksMap
    local columnWidths     = {}
    local reserveColumns  = {}
    local sumWidth         = 0
    
    for col = 1, self.cols do
        local width = 0
        for row = 1, self.rows do
            local i = (col - 1) * self.rows + row
            
            if i <= tasksCount then
                width = math.max(width, sortedTasksMap[i].width+20)
                if width < self.WIDTH/4 then
					width = self.WIDTH/4 
					table.insert(reserveColumns, col)
				end
            else
                break
            end
        end
        
        table.insert(columnWidths, width)
        sumWidth = sumWidth + width
    end
    
	if #reserveColumns ~= 4 then -- not all columns has default width
		local missingLenght = (self.WIDTH - sumWidth) / #reserveColumns
		
		for index in each(reserveColumns) do
			columnWidths[index] = columnWidths[index] + missingLenght
		end
	end
		
    return columnWidths
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:_calculateTasksPos(sortedTasksMap)
    local columnWidths  = self:_getColumnWidths(sortedTasksMap)
    local columnXoffset = {}
    
    for i, info in ipairs(sortedTasksMap) do
        if i > self.MAIN_TASKS_COUNT then
            local diff = i - self.MAIN_TASKS_COUNT
            
            info.x = self.ADDITIONAL_TASKS_X
            info.y = self.ADDITIONAL_TASKS_Y + self.ADDITIONAL_TASKS_DY * (diff - 1)
        else
            local zeroTypeId = i-1
            local col = math.floor(zeroTypeId / self.rows)
            local row = zeroTypeId - (col * self.rows)
            
            if not columnXoffset[col] then   
                columnXoffset[col] = 0
                
                for j=0, col-1 do
                    columnXoffset[col] = columnXoffset[col] + columnWidths[j+1]
                end
            end
            
            info.x = columnXoffset[col]
            info.y = row * self.TASKS_DY
        end
    end
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:_strikeOutCaption(field, save)
    local textureId = 1 --math.random(3)
    local objName   = 'Strikeout_'..field:GetText()
    local obj
    local panel = GetCurrentLevel():GetPanel()
    
    do
        local anim = CreateAnimation('data/Texture/GUI/Panel/strikeouts/Crossing'..textureId..'.png',0,0,162,88,20,20)
        anim:SetHotSpot(81,37)
        anim:SetBlendMode(2)
        anim:SetMode(HGEANIM_FWD + HGEANIM_NOLOOP)
        anim:SetColor('0xFFFFFFFF')
        obj = panel:CreateObject(objName,anim,field:GetWidth()/2,0,2,0,field:GetWidth()/anim:GetWidth() + 0.06,1)
    end
    
    obj:AttachTo(field)
    panel:IgnoreOnTestPoint(objName)
    
    if save then
        obj:GetAnimation():Rewind(true)
        obj:GetAnimation():Stop()
    else
        --PlaySound('Strike_out')
    end
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:_createTextField(task)
    local textKey = task:GetTextSingular()
    local field   = CreateTextEntity(ITEMS_FONT, textKey)
    
    field:SetName(textKey)
    field:SetZ(2)
    field:SetTextAlignment(HGETEXT_LEFT + HGETEXT_TOP)
    field:AttachTo(self.anchor)
   -- field:SetScale(self.TEXT_SCALE)
    --field:SetTracking(self.TEXT_TRACKING)
    field:Show()
    
    return field
end
-------------------------------------------------------------------------------

function HiddenObjectIndicator:_createAnchor()
    local panel = GetCurrentLevel():GetPanelLuaObject()
    local obj   = CreateAutoRegisterEntity()

    
    obj:AttachTo(panel:GetObject('panel_ho'))
    obj:SetZ(1)
    obj:SetXY(self.TASKS_X, self.TASKS_Y)
    
    return obj
end
-------------------------------------------------------------------------------