class 'TutorialBase'

function TutorialBase:__init(gameScene, tips)
	assert(gameScene and tips)

	self.scene		  = gameScene
	self.tips		  = tips			-- все зарегистрированые подсказки
	self.tipScreen	  = nil				-- скрин отображаемой в определенный момент времени подсказки
	self.showTipDelay = 0.7				-- задержка по-умолчанию отображения скрина подсказки

	self.states =
	{
		TUTORIAL_REQUESTED	= 'TutorialRequested',
		TUTORIAL_ACTIVE		= 'TutorialActive',
		TIP_SHOWN			= 'TutorialTipShown',
	}

	if not getPlayModeParameters().tutorialEnabled then -- not isCasualPlayMode() then
		self:setRequested(true)
		self:setActive(false)
	end
end
-------------------------------------------------------------------------------

--[[
 * Выводит диалог с предложением включить обучение и возвращает в callback результат
 * запроса. Если запрос уже был показан раньше, то просто выполняется callback с
 * сохраненным результатом. В callback будут переданые два параметра:
 *	- первый - согласился ли пользователь играть с обучением или нет
 *	- второй - сохранка или нет
--]]
function TutorialBase:showRequestDialog( callback )
	if not getPlayModeParameters().tutorialEnabled then -- not isCasualPlayMode() then
		return
	end

	if self:isRequested() then
		callback( self:isActive(), true )
	else
		self.scene:getPlayField():getMouseBlocker():push()

		createYesNoScreen('INTERACTIVE_HELP_NEEDED',
							bind(self.onRequested, self, callback, true),
							bind(self.onRequested, self, callback, false),
							false)
	end
end
-------------------------------------------------------------------------------

--[[
 * Обработчик результата запроса включить обучение.
--]]
function TutorialBase:onRequested(callback, bAgree)
	self:setRequested(true)
	self:setActive(bAgree)

	self.scene:getPlayField():getMouseBlocker():pop()

	if callback then
		callback(bAgree, false)
	end
end
-------------------------------------------------------------------------------

--[[
 * Проверяет, можно ли запустить и создает скрин подсказки.
 * @param	id			Уникальный ключ подсказки.
 * @param	delay		Задержка отображения скрина. На это время блокируется playfield.
 * @param	bHardShow	Позволяет обойти проверку того, включено ли обучение и показать подсказку в любом случае.
 * @param	bMultyShow	Позволяет показывать подсказку без проверки того, была ли она показана ранее
--]]
function TutorialBase:showTip(id, delay, bHardShow, bMultyShow)
	local tip = self.tips[id]
	assert(tip)

	delay = delay or self.showTipDelay

	local bActive	 = bHardShow or self:isActive()
	local bCompleted = not bMultyShow and self:isTipCompleted(id)

	if bActive and not bCompleted then
		if delay == 0 then
			self:createTutorialScreen(id)
		else
			local playfield	= self.scene:getPlayField()
			local timer		= tip.getTimer and tip.getTimer()
											or playfield:getTimer()

			playfield:getMouseBlocker():push()
			timer:add(	function()
							if not playfield:isDestroyed() then
								playfield:getMouseBlocker():pop()

								self:createTutorialScreen(id)
							end
						end, delay)
		end
	end
end
-------------------------------------------------------------------------------

function TutorialBase:createTutorialScreen(id)
	local tip = self.tips[ id ]
	local bGameSceneOnTop = PopUpScreensMgr:GetTop():getName() == self.scene:getName()

	local screenFile = tip.screenFile or 'Data/Scripts/Screens/TutorialScreen.lua'
	local className	 = ExtractFileName(screenFile)
	local screen	 = CreatedScreen(screenFile, className, self)
	screen:setId(id)
	
    if tip.constructor then
    	tip.constructor(screen)
    end
    
    PopUpScreensMgr:push(screen, false)

    if bGameSceneOnTop then
    	self.scene:go()
    end

    return screen
end
-------------------------------------------------------------------------------

function TutorialBase:hideTip()
	if self.tipScreen then
		self.tipScreen:close(true)
	end
end
-------------------------------------------------------------------------------

function TutorialBase:setTipShown(id)
	AddUniqueGameState(self.states.TIP_SHOWN, id)
end
-------------------------------------------------------------------------------

function TutorialBase:isTipShown(id)
	return HasGameState(self.states.TIP_SHOWN, id)
end
-------------------------------------------------------------------------------

function TutorialBase:isTipCompleted(id)
	local tip = self.tips[id]
	assert(tip)

	if tip.completeCondition then
		return tip.completeCondition(id)
	else
		return self:isTipShown(id)
	end
end
-------------------------------------------------------------------------------

function TutorialBase:skip()
	if self.tipScreen then
		self.tipScreen:skip()
	end

	self:setActive(false)
end
-------------------------------------------------------------------------------

function TutorialBase:setRequested(bRequested)
	assert(type(bRequested) == 'boolean')
	SetGameState(self.states.TUTORIAL_REQUESTED, tostring(bRequested))
end
-------------------------------------------------------------------------------

function TutorialBase:isRequested()
	return HasGameState(self.states.TUTORIAL_REQUESTED, 'true')
end
-------------------------------------------------------------------------------

function TutorialBase:setActive(bActive)
	assert(type(bActive) == 'boolean')
	SetGameState(self.states.TUTORIAL_ACTIVE, tostring(bActive))
end
-------------------------------------------------------------------------------

function TutorialBase:isActive()
	return HasGameState(self.states.TUTORIAL_ACTIVE, 'true')
end
-------------------------------------------------------------------------------