class 'ScoreManagerBase'
-------------------------------------------------------------------------------

local theScoreManger = nil

function GetScoreManager()
	if not theScoreManger then
		theScoreManger = ScoreManagerBase()
	end
	return theScoreManger
end
-------------------------------------------------------------------------------

function ScoreManagerBase:__init()
	self.STATE_NAME		 = 'GamePoints'
	self.uniquePopupID	 = 0
	self.popupTextParent = nil
	self.bEnable		 = false

	self.EPointsType =
	{
		INTERACT	= 25,
		HOPICK		= 10,
		TOOLFIND	= 25,
		TOOLAPPLY	= 50,
		MONOLOG		= 15,
		MINIGAME	= 250,
		NOTE		= 20,
	}
end
-------------------------------------------------------------------------------

function ScoreManagerBase:submit()
	if not self.bEnable or not BFG then
		return
	end

	local value = self:getTotalPoints()
	BFG.submitScore(value)
end
-------------------------------------------------------------------------------

function ScoreManagerBase:enable()
	self.bEnable = true
end
-------------------------------------------------------------------------------

function ScoreManagerBase:disable()
	self.bEnable = false
end
-------------------------------------------------------------------------------

function ScoreManagerBase:isEnable()
	return self.bEnable
end
-------------------------------------------------------------------------------


-------------------------------------------------------------------------------
-- POINTS ---------------------------------------------------------------------
-------------------------------------------------------------------------------

function ScoreManagerBase:addPoints(value, tag)
	value = value or 0
	value = value + self:getPoints(tag)

	SetGameState(self.STATE_NAME, tostring(value), tag)
end
-------------------------------------------------------------------------------

function ScoreManagerBase:getPoints(tag)
	if HasGameState(self.STATE_NAME, nil, tag) then
		return tonumber(GetGameState(self.STATE_NAME, tag):get(0))
	end

	return 0
end
-------------------------------------------------------------------------------

function ScoreManagerBase:getTotalPoints()
	local valueSE = self:getPoints(EGameStateTag.SE)
	local valueCE = self:getPoints(EGameStateTag.CE)

	return valueSE + valueCE
end
-------------------------------------------------------------------------------


-------------------------------------------------------------------------------
-- POPUP TEXT -----------------------------------------------------------------
-------------------------------------------------------------------------------

function ScoreManagerBase:setPopupTextsParent(entity)
	self.popupTextParent = entity
end
-------------------------------------------------------------------------------

function ScoreManagerBase:getUniquePopupID()
	local id = self.uniquePopupID
	self.uniquePopupID = self.uniquePopupID + 1
	return id
end
-------------------------------------------------------------------------------

function ScoreManagerBase:createPopupEffector(popupText)
	local time	 = 1
	local pos	 = popupText:getPosition()
	local offset = Vector2f(25, -25)

	local effector = CreateAnimationEffector()
	effector:setDestroysOnEnd(true)
	effector:attachTo(popupText)
	
	effector:setKey(_TRACK_O, 0,			0)
	effector:setKey(_TRACK_O, time * 0.66,	1)
	effector:setKey(_TRACK_O, time,			1)
	effector:setKey(_TRACK_O, time * 2,		0)
			
	effector:setKey(_TRACK_S, 0,			0.75 )
	effector:setKey(_TRACK_S, time*0.0825,	0.875)
	effector:setKey(_TRACK_S, time*0.33,	1.0  )
	effector:setKey(_TRACK_S, time*0.66,	1.05 )
	effector:setKey(_TRACK_S, time,			1    )
	effector:setKey(_TRACK_S, time*2,		0.75 )
	
	effector:setKey(_TRACK_X, 0,			pos.x)
	effector:setKey(_TRACK_Y, 0,			pos.y)
	effector:setKey(_TRACK_X, time * 2,		pos.x + offset.x)
	effector:setKey(_TRACK_Y, time * 2,		pos.y + offset.y)
	effector:play()

	return effector
end
-------------------------------------------------------------------------------

function ScoreManagerBase:createPopupText(value, scrPos)
	local id	 = self:getUniquePopupID()
	local name	 = string.format('popupText_%d', id)
	local text	 = string.format('+%d', value)
	local parent = self.popupTextParent or getGameRoot()
	local entity = CreateTextEntity()

	entity:attachTo			( self.popupTextParent )
	entity:setName			( name )
	entity:setText			( text )
	entity:setTextAlignment	( TextEntity.ETextHorizontalAlignmentCenter )
	entity:setHotSpotType	( TextEntity.ETextHotSpotTypeCenter )
	entity:setFont			( 'Data/Fonts/Options.fnt' )
	entity:setHeight		( 30 )
	entity:setRespondable	( false )
	entity:setScrPosition	( scrPos )
	entity:setMaxOrder()
	entity:show()

	local effector = self:createPopupEffector(entity)
	effector.onFinish:add(	function()
								entity:destroy()
							end )
end
-------------------------------------------------------------------------------

function ScoreManagerBase:createPopupTextOverObject(value, object)
	local offset = Vector2f(20, -20)
	local scrPos = object:getScrPosition() + offset

	self:createPopupText(value, scrPos)
end
-------------------------------------------------------------------------------


-------------------------------------------------------------------------------
-- HELPERS --------------------------------------------------------------------
-------------------------------------------------------------------------------

function ScoreManagerBase:getBonusNameState(object, bSceneIndependent)
	assert(object or not bSceneIndependent)

	local result = 'GotScore'

	if not bSceneIndependent then
		result = result..'_'..current_scene:getName()
	end

	if object then
		local objectName = type(object) == 'string' and object or object:getName()
		result = result..'_'..objectName
	end

	return result
end
-------------------------------------------------------------------------------

function ScoreManagerBase:banScore(targetObject, bSceneIndependent)
	if not self.bEnable then
		return
	end

	local stateName = self:getBonusNameState(targetObject, bSceneIndependent)
	AddUniqueGameState(stateName, 'true')
end
-------------------------------------------------------------------------------

function ScoreManagerBase:addScore(targetObject, scoreValue, bRepeatedly)
	if not self.bEnable then
		return
	end

	local stateName = self:getBonusNameState(targetObject)

	if bRepeatedly or (not HasGameState(stateName)) then
		AddUniqueGameState(stateName, 'true')
		self:addPoints(scoreValue or self.EPointsType.INTERACT)

		if targetObject then
			self:createPopupTextOverObject(scoreValue, targetObject)
		end
	end
end
-------------------------------------------------------------------------------

function ScoreManagerBase:addScoreToolFound(toolName, targetObject)
	assert(toolName)

	if not self.bEnable then
		return
	end

	local stateName	 = self:getBonusNameState(toolName, true)
	local scoreValue = self.EPointsType.TOOLFIND

	if not HasGameState(stateName) then
		AddUniqueGameState(stateName, 'true')

		self:addPoints(scoreValue)
		self:createPopupTextOverObject(scoreValue, targetObject)
	end
end
-------------------------------------------------------------------------------

function ScoreManagerBase:addScoreNote(noteId, targetObject)
	assert(noteId)

	if not self.bEnable then
		return
	end

	local stateName	 = self:getBonusNameState(noteId, true)
	local scoreValue = self.EPointsType.NOTE

	if not HasGameState(stateName) then
		AddUniqueGameState(stateName, 'true')

		self:addPoints(scoreValue)
		if targetObject then
			self:createPopupTextOverObject(scoreValue, targetObject)
		end
	end
end
-------------------------------------------------------------------------------

function ScoreManagerBase:addScoreToolApply(targetObject)
	self:addScore(targetObject, self.EPointsType.TOOLAPPLY)
end
-------------------------------------------------------------------------------

function ScoreManagerBase:addScoreMGComplete()
	self:addScore(nil, self.EPointsType.MINIGAME)
end
-------------------------------------------------------------------------------

function ScoreManagerBase:addScoreHOPick(targetObject)
	self:addScore(targetObject, self.EPointsType.HOPICK)
end
-------------------------------------------------------------------------------

function ScoreManagerBase:addScoreBBT(targetObject)
	self:addScore(targetObject, self.EPointsType.MONOLOG)
end
-------------------------------------------------------------------------------

function ScoreManagerBase:addScoreInteractive(targetObject)
	self:addScore(targetObject, self.EPointsType.INTERACT)
end
-------------------------------------------------------------------------------