function TutorialDialogOut(receiver, arrivalMessage, noZGlass)
	if not noZGlass then
		SendMessage("Tutorial layer", "template ZGlassTemplate")
		SendMessage("Tutorial layer", "create top instance")
			-- чтобы второй раз не нажали
	end
	SendMessage("Tutorial alpha changer", "change alpha to 0.0")
	SendMessage("Tutorial mover", "report arrival to "..receiver)
		-- post, потому что почти всегда удаляем уехавший диалог
	SendMessage("Tutorial mover", "set arrival message "..arrivalMessage)
	SendMessage("Tutorial mover", "move to out")
end

function TutorialDialogIn(templateName)
	SendMessage("Tutorial layer", "clear children list")
	SendMessage("Tutorial layer", "template "..templateName)
	SendMessage("Tutorial layer", "create top instance")
	SendMessage("Tutorial mover", "report arrival to null")
	SendMessage("Tutorial mover", "set arrival message null")
	SendMessage("Tutorial mover", "move to in")
	SendMessage("Tutorial alpha changer", "change alpha to 1.0")
end

function TutorialFunc(message)
	if message == "Ask tutorial dialog no button pressed" then
		PermanentStorage.SetLocalBool("Want tutorial", false)
		SendMessage("Tutorial dialog", "hide")
		SendMessage("Ask tutorial mover", "report arrival to null")
		SendMessage("Ask tutorial mover", "set arrival message null")
		SendMessage("Ask tutorial mover", "move to out")
	elseif message == "Ask tutorial dialog yes button pressed" then
		PermanentStorage.SetLocalBool("Want tutorial", true)
		SendMessage("Tutorial dialog", "hide")
		SendMessage("Ask tutorial mover", "report arrival to lua:TutorialFunc")
		SendMessage("Ask tutorial mover", "set arrival message Ask tutorial dialog out")
		SendMessage("Ask tutorial mover", "move to out")
	elseif message == "Ask tutorial dialog out" then
		TutorialDialogIn("FirstPressShopTutorialTemplate")
	elseif message == "Skip tutorial button pressed" then
		TutorialDialogOut("post:lua:TutorialFunc", "A tutorial dialog out for skip tutorial")
	elseif message == "A tutorial dialog out for skip tutorial" then
		SendMessage("Tutorial dialog", "instantiate ConfirmSkipTutorialTemplate")
		SendMessage("Skip tutorial mover", "report arrival to null")
		SendMessage("Skip tutorial mover", "set arrival message null")
		SendMessage("Skip tutorial mover", "move to in")
	elseif message == "Skip tutorial dialog yes button pressed" then
		PermanentStorage.SetLocalBool("Want tutorial", false)
		SendMessage("Tutorial layer", "clear children list")
		SendMessage("Tutorial dialog", "hide")
		SendMessage("Skip tutorial mover", "report arrival to null")
		SendMessage("Skip tutorial mover", "set arrival message null")
		SendMessage("Skip tutorial mover", "move to out")
	elseif message == "Skip tutorial dialog no button pressed" then
		SendMessage("Tutorial dialog", "hide")
		SendMessage("Skip tutorial mover", "report arrival to lua:TutorialFunc")
		SendMessage("Skip tutorial mover", "set arrival message Skip tutorial dialog out for tutorial")
		SendMessage("Skip tutorial mover", "move to out")
	elseif message == "Skip tutorial dialog out for tutorial" then
		SendMessage("Tutorial mover", "report arrival to lua:TutorialFunc")
		SendMessage("Tutorial mover", "set arrival message Tutorial mover in after skip tutorial dialog")
		SendMessage("Tutorial mover", "move to in")
		SendMessage("Tutorial alpha changer", "change alpha to 1.0")
	elseif message == "Tutorial mover in after skip tutorial dialog" then
		SendMessage("post:Tutorial layer", "erase top child")
			-- удаление ZGlassControl
	elseif message == "Tutorial fish purchase" then
		TutorialDialogOut("post:lua:TutorialFunc", "Tutorial fish purchase dialog out")
	elseif message == "Tutorial fish purchase dialog out" then
		SendMessage("Tutorial reminder", "set delay 5.0")
		SendMessage("Tutorial reminder", "set message Tutorial fish shown after purchase")
		SendMessage("Tutorial reminder", "report to lua:TutorialFunc")
	elseif message == "Tutorial fish shown after purchase" then
		TutorialDialogIn("FishNotHappyTutorialTemplate")
	elseif message == "Tutorial fish not happy dialog next button pressed" then
		TutorialDialogOut("post:lua:TutorialFunc", "Tutorial fish not happy dialog out")
	elseif message == "Tutorial fish not happy dialog out" then
		TutorialDialogIn("NotMuchMoneyTutorialTemplate")
	elseif message == "Tutorial not much money dialog next button pressed" then
		TutorialDialogOut("post:lua:TutorialFunc", "Tutorial not much money dialog out")
	elseif message == "Tutorial not much money dialog out" then
		TutorialDialogIn("PressDoneTutorialTemplate")
	elseif message == "Tutorial it was easy dialog next button pressed" then
		TutorialDialogOut("post:lua:TutorialFunc", "Tutorial it was easy dialog out")
	elseif message == "Tutorial it was easy dialog out" then
		TutorialDialogIn("SecondPressShopTutorialTemplate")
	elseif message == "Tutorial fish tab pressed" then
		if PermanentStorage.GetLocalBool("Want tutorial") then
			-- Если посреди задания "нажмите на вкладку Beauty" отказались от tutorial,
			-- то выполнение следующих действий приведёт к ошибке,
			-- т.к. в тот момент некоторых из упомянутых объектов уже не будет.
			-- Поэтому всё под if'ом, не отказались ли.
			TutorialDialogOut("post:lua:TutorialFunc", "Tutorial press fish tab dialog out")
		end
	elseif message == "Tutorial press fish tab dialog out" then
		TutorialDialogIn("BuyFishTutorialTemplate")
	elseif message == "Tutorial beauty tab pressed" then
		if PermanentStorage.GetLocalBool("Want tutorial") then
			-- Если посреди задания "нажмите на вкладку Beauty" отказались от tutorial,
			-- то выполнение следующих действий приведёт к ошибке,
			-- т.к. в тот момент некоторых из упомянутых объектов уже не будет.
			-- Поэтому всё под if'ом, не отказались ли.
			TutorialDialogOut("post:lua:TutorialFunc", "Tutorial press beauty tab dialog out")
		end
	elseif message == "Tutorial press beauty tab dialog out" then
		TutorialDialogIn("PlaceThisItemTutorialTemplate")
	elseif message == "Tutorial ornament purchase started" then
		PermanentStorage.SetLocalBool("temp:Show tutorial purchase mask", false)
		TutorialDialogOut("post:lua:TutorialFunc", "Tutorial place this item dialog out", true)
			-- не ставим ZGlass, чтобы можно было быстро перетащить предмет на дно
	elseif message == "Tutorial place this item dialog out" then
		PermanentStorage.SetLocalBool("temp:Show tutorial purchase mask", true)
			-- на случай второго захода
		TutorialDialogIn("DragTowardsSandTutorialTemplate")
	elseif message == "Tutorial ornament purchase on sand" then
		TutorialDialogOut("post:lua:TutorialFunc", "Tutorial arrow to sand out")
	elseif message == "Tutorial arrow to sand out" then
		TutorialDialogIn("ChooseAnySpotTutorialTemplate")
	elseif message == "Tutorial ornament purchase cancelled" then
		TutorialDialogOut("post:lua:TutorialFunc", "Tutorial repeat ornament purchase")
	elseif message == "Tutorial repeat ornament purchase" then
		TutorialDialogIn("PlaceThisItemTutorialTemplate")
	elseif message == "Tutorial ornament purchase complete" then
		TutorialDialogOut("post:lua:TutorialFunc", "Tutorial ornament purchase dialog out")
	elseif message == "Tutorial ornament purchase dialog out" then
		TutorialDialogIn("ItemCanBeMovedTutorialTemplate")
	elseif message == "Tutorial item can be moved dialog next button pressed" then
		TutorialDialogOut("post:lua:TutorialFunc", "Tutorial item can be moved dialog out")
	elseif message == "Tutorial item can be moved dialog out" then
		TutorialDialogIn("NoticeMetersTutorialTemplate")
	elseif message == "Tutorial notice meters dialog next button pressed" then
		TutorialDialogOut("post:lua:TutorialFunc", "Tutorial notice meters dialog out")
	elseif message == "Tutorial notice meters dialog out" then
		TutorialDialogIn("GoodLuckTutorialTemplate")
	elseif message == "Tutorial good luck dialog continue button pressed" then
		PermanentStorage.SetLocalBool("Want tutorial", false)
		TutorialDialogOut("post:lua:TutorialFunc", "Tutorial good luck dialog out")
	elseif message == "Tutorial good luck dialog out" then
		SendMessage("Tutorial layer", "clear children list")
	elseif message == "Shop done button pressed" then
		if PermanentStorage.GetLocalBool("Want tutorial") then
			local pressing = PermanentStorage.GetLocalBoolOrDef("temp:Tutorial shop done button pressing", false)
			if not pressing then
				PermanentStorage.SetLocalBool("temp:Tutorial shop done button pressing", true)
				TutorialDialogOut("post:lua:ShopFunc", "Shop done button pressed")
				return true -- и НЕ сваливаемся в обычную обработку
			else
				PermanentStorage.SetLocalBool("temp:Tutorial shop done button pressing", false)
				PermanentStorage.SetLocalBool("temp:First shop tutorial complete", true)
				SendMessage("Tutorial layer", "clear children list")
				SendMessage("Tutorial layer", "template ZGlassTemplate")
				SendMessage("Tutorial layer", "create top instance")
					-- блокируем экран на время уезда панелей
				return false -- и сваливаемся в обычную обработку
			end
		else
			return false -- обычная обработка
		end
	elseif message == "Game field to main screen" then
		if PermanentStorage.GetLocalBool("Want tutorial") then
			SendMessage("Tutorial layer", "template ZGlassTemplate")
			SendMessage("Tutorial layer", "create top instance")
				-- блокируем экран на время приезда панелей
		end
	elseif message == "Main screen panels in" then
		local from = PermanentStorage.GetLocalStringOrDef("temp:Tutorial main screen panels in after", "")
		PermanentStorage.SetLocalString("temp:Tutorial main screen panels in after", "")
		if from == "shop" then
			if PermanentStorage.GetLocalBool("Want tutorial") then
				assert(PermanentStorage.GetLocalBoolOrDef("temp:First shop tutorial complete", false))
				SendMessage("Tutorial layer", "erase top child")
					-- ZGlass
				TutorialDialogIn("PressPlayTutorialTemplate")
			end
		elseif from == "game field" then
			if PermanentStorage.GetLocalBool("Want tutorial") then
				SendMessage("Tutorial layer", "erase top child")
					-- ZGlass
				TutorialDialogIn("ItWasEasyTutorialTemplate")
			end
		else
			assert(from == "")
		end
	elseif message == "Main screen shop button pressed" then
		if PermanentStorage.GetLocalBool("Want tutorial") then
			if not PermanentStorage.IsLocalNameDefined("temp:Tutorial first shop button pressing") then
				PermanentStorage.SetLocalBool("temp:Tutorial first shop button pressing", true)
				TutorialDialogOut("post:lua:MainScreenFunc", "Main screen shop button pressed")
				return true -- и НЕ сваливаемся в обычную обработку
			elseif PermanentStorage.GetLocalBool("temp:Tutorial first shop button pressing") then
				PermanentStorage.SetLocalBool("temp:Tutorial first shop button pressing", false)
				SendMessage("Tutorial layer", "clear children list")
				SendMessage("Tutorial layer", "template ZGlassTemplate")
				SendMessage("Tutorial layer", "create top instance")
					-- блокируем экран на время уезда панелей
				return false -- и сваливаемся в обычную обработку
			elseif not PermanentStorage.IsLocalNameDefined("temp:Tutorial second shop button pressing") then
				PermanentStorage.SetLocalBool("temp:Tutorial second shop button pressing", true)
				TutorialDialogOut("post:lua:MainScreenFunc", "Main screen shop button pressed")
				return true -- и НЕ сваливаемся в обычную обработку
			elseif PermanentStorage.GetLocalBool("temp:Tutorial second shop button pressing") then
				PermanentStorage.SetLocalBool("temp:Tutorial second shop button pressing", false)
				SendMessage("Tutorial layer", "clear children list")
				SendMessage("Tutorial layer", "template ZGlassTemplate")
				SendMessage("Tutorial layer", "create top instance")
					-- блокируем экран на время уезда панелей
				return false -- и сваливаемся в обычную обработку
			else
				assert(false) -- в tutorial, но не первые два нажатия
			end
		else
			return false -- обычная обработка
		end
	elseif message == "Main screen panel out for shop" then
		if PermanentStorage.GetLocalBool("Want tutorial") then
			SendMessage("Tutorial layer", "erase top child")
				-- ZGlass
			local currentTank = PermanentStorage.GetLocalString("Current Tank")
			if not PermanentStorage.GetLocalBoolOrDef("temp:First shop tutorial started", false) then
				PermanentStorage.SetLocalBool("temp:First shop tutorial started", true)
				TutorialDialogIn("PressFishTabTutorialTemplate")

				assert(currentTank == "1")
				assert(not PermanentStorage.IsLocalNameDefined("1 Shop tab set tab order"))
				SendMessage("1 Shop tab set", "report tab change to lua:TutorialFunc")
				SendMessage("1 Shop tab set", "set change message Tutorial fish tab pressed")
			else
				TutorialDialogIn("PressBeautyTabTutorialTemplate")

				assert(currentTank == "1")
				SendMessage("1 Shop tab set", "report tab change to lua:TutorialFunc")
				SendMessage("1 Shop tab set", "set change message Tutorial beauty tab pressed")
			end
		end
	elseif message == "Main screen to game field" then
		if PermanentStorage.GetLocalBool("Want tutorial") then
			local pressing = PermanentStorage.GetLocalBoolOrDef("temp:Tutorial main screen play button pressing", false)
			if not pressing then
				PermanentStorage.SetLocalBool("temp:Tutorial main screen play button pressing", true)
				TutorialDialogOut("post:lua:MainScreenFunc", "Main screen to game field")
				return true -- и НЕ сваливаемся в обычную обработку
			else
				PermanentStorage.SetLocalBool("temp:Tutorial main screen play button pressing", false)
				SendMessage("Tutorial layer", "clear children list")
				return false -- и сваливаемся в обычную обработку
			end
		else
			return false -- обычная обработка
		end
	elseif message == "Main menu panel out for main screen" then
		if not PermanentStorage.IsLocalNameDefined("Want tutorial") then
			SendMessage("Tutorial dialog", "instantiate AskTutorialTemplate")
			SendMessage("Ask tutorial mover", "report arrival to null")
			SendMessage("Ask tutorial mover", "set arrival message null")
			SendMessage("Ask tutorial mover", "move to in")
		else
			-- на всякий случай, если вылетит во время tutorial после автосохранения
			PermanentStorage.SetLocalBool("Want tutorial", false)
		end
	else
		assert(false, "Unknown message "..message)
	end
end