local TOOL_NAME_TEXT_OFFSET_X   = 30
local TOOL_NAME_TEXT_OFFSET_Y   = -10
local TOOL_NAME_TEXT_Z		    = 1300
local INVENTORY_TOOL_SIZE 		= 64

------------------------------------------------
class 'HiddenPictureIndicator'

function HiddenPictureIndicator:__init(game_scene)
	self.game_scene = game_scene
	
    self.SLOTS_COUNT = 5
    -- self.TASKS_X  = -120
    -- self.TASKS_Y  = 20
	self.TASKS_X  = 310
    self.TASKS_Y  = 716
    self.TASKS_DX = 99
    
    self.COLOR_SHADOW    = Colorf(0.0, 0.0, 0.0, 1.0)
    self.COLOR_DEFAULT   = Colorf(1.0, 1.0, 1.0, 1.0)
    self.COLOR_DRAGGING  = Colorf(0.33, 0.33, 0.33, 1.0)
    self.COLOR_HIGHLIGHT = Colorf(0.1, 0.18, 0.25, 1.0)
    
    self.anchor  = self:_createAnchor()
    self.objects = {}
    self.slots  = {}
	
	-- flying animation consts
	self.pop_duration = 1.1
	self.flying_to_panel_duration = 0.7
	self.disappear_time = 0
	self.strike_out_duration = 1

    show_hint_text = false
    self.hintText = CreateTextEntity()
    self.hintText:setName('hp_hint_text')
    self.hintText:attachTo( self.game_scene:getEntityNamed('Panel') )
    self.hintText:setOrder(200)
    self.hintText:setRespondable(false)
    self.hintText:setHotSpotType(ETextHotSpotTypeLeftBottom)
    self.hintText:setFont('Data/Fonts/Options.fnt')
    self.hintText:setOpacity(0)
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function HiddenPictureIndicator:update(dt)
    if self.show_hint_text then
        local current_pos = GetCursorEntity():getPosition()
        self.hintText:setXY(current_pos.x + 15, current_pos.y - 5)
    end
end

function HiddenPictureIndicator:destroy()
	self.anchor:destroy()
    self.hintText:destroy()
end

function HiddenPictureIndicator:getAnchor()
    return self.anchor
end

-------------------------------------------------------------------------------
function HiddenPictureIndicator:CreateIndicator(taskName, templateObject)
	local icon = CreateSpriteEntityInstant(templateObject:getTexture():getRelativePath())
	icon:setName('icon_'..templateObject:getName())
	icon:setScale(math.min(	INVENTORY_TOOL_SIZE/icon:getBoundingBox():getWidth(),
							INVENTORY_TOOL_SIZE/icon:getBoundingBox():getHeight()))
	icon:attachTo(self.anchor)
	
	local back = self.game_scene:getPlayField():getEntityNamed('back_'..templateObject:getName())    
	back:setRespondable(true)
    back:setScale(math.max( icon:getBoundingBox():getWidth()/back:getBoundingBox():getWidth(),
                            icon:getBoundingBox():getHeight()/back:getBoundingBox():getHeight()))
	back:attachTo(icon)
    back.onFocusIn:add(function() self:HighlightItem(taskName) end)
    back.onFocusOut:add(function() self:DisableHighlight(taskName) end)

	icon.back = back
    self.objects[taskName] = icon
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:setIndicatorColor(taskName, color)
    local object = self.objects[taskName]
    object:setColor(color)
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:SetIndicatorIgnoreTestPoint(taskName, ignore)
    -- local panel  = GetCurrentLevel():GetPanel()
    local object = self.objects[taskName]
    
    if ignore then
        -- panel:IgnoreOnTestPoint(object:GetName())
		object:setRespondable(false)
    else
        -- panel:DoNotIgnoreOnTestPoint(object:GetName())
		object:setRespondable(true)
    end
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:ShowIndicator(taskName)
    local slot = self:_getSavedSlot(taskName)
    
    if not slot then
        slot = self:_getFreeSlot()
        self:_saveSlot(slot, taskName)
    end
    
    self.slots[slot] = taskName
    
    local object = self.objects[taskName]
	local task_x = self.TASKS_DX * (slot - 1)
    object:setX(task_x)
    object:setOpacity(1)
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:HideIndicator(taskName)
    local slot = self:_getSavedSlot(taskName)
    
    self.slots[slot] = nil
    self:_saveSlot(slot, nil)
    
    local object = self.objects[taskName]
    object:setX(self.TASKS_X)
    object:setOpacity(0)
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:GetTaskPos(task)
    local taskName = task:GetTextSingular()
    local object   = self.objects[taskName]
    
    return Vector2f(object:getX(), object:getY())
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:GetIconScale(taskName)
    return self.objects[taskName]:getScale()
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:GetTaskName(objectName)
    for taskName, object in pairs(self.objects) do
        if object:GetName() == objectName or object.back:GetName() == objectName then
            return taskName
        end
    end
    
    return nil
end

-------------------------------------------------------------------------------
function HiddenPictureIndicator:FreeSlotsExist()
    for i=1, self.SLOTS_COUNT do
        if self.slots[i] == nil then
            return true
        end
    end
    
    return false
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:ClearSlotStates()
    for i=1, self.SLOTS_COUNT do
        local state = self:_getTaskSlotState(i)
        
        if HasGameState(state) then
            RemoveGameState(state)
        end
    end
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:HighlightItem(task_name)
	if not IsTaskObjectFound(self.game_scene:getPlayField():getName(), string.sub(self.objects[task_name]:getName(), 6)) then
		self:setIndicatorColor(task_name, self.COLOR_HIGHLIGHT)
	end

    self.hintText:setText( StringManager:getString(task_name) )
    self.hintText:setOpacity(1)
    self.show_hint_text = true
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:DisableHighlight(task_name)
	if not IsTaskObjectFound(self.game_scene:getPlayField():getName(), string.sub(self.objects[task_name]:getName(), 6)) then
		self:setIndicatorColor(task_name, self.COLOR_SHADOW)
	end

    self.hintText:setOpacity(0)
    self.show_hint_text = false
end

-------------------------------------------------------------------------------
function HiddenPictureIndicator:createFlyAnimation(object, task)
	local max_delta_pos   = 256
    local anchor = self:getAnchor()
    
	local scale = object:getScale()
	local num_keys =  40
    
    local start_pos  = Vector2f(object:getX(), object:getY())
    local finish_pos = self:getTaskPosition(task)
	local finish_scale = self:getTaskScale(task)

    local mover = CreateAnimationEffector()

    mover:setKey(_TRACK_SX, 0,				scale.x * 1)
    mover:setKey(_TRACK_SX, self.pop_duration * 0.25,	scale.x * 1.5)
    mover:setKey(_TRACK_SX, self.pop_duration * 0.5,	scale.x * 1)
    mover:setKey(_TRACK_SX, self.pop_duration * 0.75,	scale.x * 1.5)
    mover:setKey(_TRACK_SX, self.pop_duration,			scale.x * 1)
    mover:setKey(_TRACK_SX, self.pop_duration + self.flying_to_panel_duration,	scale.x * 0.3)

    mover:setKey(_TRACK_SY, 0,				scale.y * 1)
    mover:setKey(_TRACK_SY, self.pop_duration * 0.25,	scale.y * 1.5)
    mover:setKey(_TRACK_SY, self.pop_duration * 0.5,	scale.y * 1)
    mover:setKey(_TRACK_SY, self.pop_duration * 0.75,	scale.y * 1.5)
    mover:setKey(_TRACK_SY, self.pop_duration,			scale.y * 1)
    mover:setKey(_TRACK_SY, self.pop_duration + self.flying_to_panel_duration,	finish_scale)
    
    mover:setKey(_TRACK_O, self.pop_duration + self.flying_to_panel_duration, object:getColor():getA())
    mover:setKey(_TRACK_O, self.pop_duration + self.flying_to_panel_duration + self.disappear_time,	0)
	
	local keys = HelpersEffect.createSplineBezier(	start_pos,
													start_pos + Vector2f(RandomFloat(-max_delta_pos, max_delta_pos),
																		RandomFloat(-max_delta_pos, max_delta_pos)),
													finish_pos,
													finish_pos + Vector2f(RandomFloat(-max_delta_pos, max_delta_pos), -200),
													num_keys)
	
	local time_step = self.flying_to_panel_duration / num_keys
	for i, position in ipairs(keys) do
		mover:setKey(_TRACK_X, self.pop_duration + (i - 1) * time_step, position.x)
		mover:setKey(_TRACK_Y, self.pop_duration + (i - 1) * time_step, position.y)
	end
    
    return mover
end

-------------------------------------------------------------------------------
function HiddenPictureIndicator:getTaskPosition(task)
	local task_object = self.objects[task:getName()]
	return Vector2f(task_object:getX(), task_object:getY())
end

-------------------------------------------------------------------------------
function HiddenPictureIndicator:getTaskScrPosition(task)
	local task_object = self.objects[task:getName()]
	return Vector2f(task_object:getScrX(), task_object:getScrY())
end

-------------------------------------------------------------------------------
function HiddenPictureIndicator:getTaskScale(task)
	local task_object = self.objects[task:getName()]
	return task_object:getScale().x
end

-------------------------------------------------------------------------------
function HiddenPictureIndicator:getFindAnimationDuration()
	return self.pop_duration + self.flying_to_panel_duration + self.disappear_time
end


--------------------------------------------------------------------------------
-- PRIVATE METHODS -------------------------------------------------------------
--------------------------------------------------------------------------------

function HiddenPictureIndicator:_createAnchor()
    local anchor = CreateSpriteEntity('')
	local hp_panel = self.game_scene:getPanel():getHPPanel()
	anchor:attachTo(hp_panel:getMainEntity())
	anchor:setName('HPPanelAnchor')
	anchor:setXY(self.TASKS_X, self.TASKS_Y)
	anchor:setOrder(11)
    
    return anchor
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:_getSavedSlot(taskName)
    for i=1, self.SLOTS_COUNT do
        local state = self:_getTaskSlotState(i)
        
        if HasGameState(state) then
            if taskName == GetGameState(state):get(0) then
                return i
            end
        end
    end
    
    return nil
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:_getFreeSlot()
    for i=1, self.SLOTS_COUNT do
        local state = self:_getTaskSlotState(i)
        
        if not HasGameState(state) then
            return i
        end
    end
    
    return nil
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:_saveSlot(slot, taskName)
    self.slots[slot] = taskName
    
    local state = self:_getTaskSlotState(slot)
    
    if taskName then
        SetGameState(state, taskName)
    else
        RemoveGameState(state)
    end
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:_getTaskSlotState(slot)
	local level_name = self.game_scene:getPlayField():getName()
    return 'TASK_SLOT_'..tostring(slot)..'_'..string.upper(level_name)
end
-------------------------------------------------------------------------------

function HiddenPictureIndicator:createFlyParticleSystem()
    local particle = CreateParticleEntity()
    particle:setParticle( 'Data/ParticleSystems/item_highlight.psi',
        'Data/Textures/Particles/particle_ho.png' )
    particle:setBlend( _EBlendModeColorAdd )
    particle:setHotSpot( 10, 10 )
    particle:setLifetime( 1.26 )

    return particle, -1
end
