-------------------------------------------------------------------------------
--[[
 * GameState - движковый класс, реализующий механизм сохранений в игре. У каждого
 * профиля существует свой экземпляр данного класса. Получить доступ к нему можно
 * через поле профиля "gameState". Для разных частей игры (таких как StandartEdition,
 * CollectorsEdition и прочих) сохранение осуществляется в определенные раззделы
 * gameState. При сохранениее и извлечении сохраненных записей, нужно указывать,
 * с каким разделом должна выполняться работа. За это в коде отвечает параметр "tag".
 * Формат сохранение имеет вид "ключ значение" (далее в коде state, value). Ключ
 * является идентификатором доступа к экземпляру движкового класса GameStateRecord,
 * в котором значения хранятся в виде вектора. Таким образом можно добавлять произвольное
 * количество записей с одинаковими ключами (метод addState). И ключ, и значение
 * должны быть строками.
--]]
-------------------------------------------------------------------------------

--[[
 * Функция определяет с каким разделом gameState нужно работать по-умолчанию.
--]]
function getDefaultGameStateTag()
	if PRIMARY_GAME_STATE_TAG then
		return PRIMARY_GAME_STATE_TAG
	end

	if current_scene then
		return getLevelsGameStateTag()
	end

	return EGameStateTag.SE
end
-------------------------------------------------------------------------------

--[[
 * Функция определяет, существует ли запись в определенном разделе gameState с 
 * указаными ключ/значение.
 * @param	state		Ключ записей, которые проверяются.
 * @param	value		Проверяемое на cущесвование в gameState значение. Если
 * 						не указан, то будет проверятся существование "хоть одной"
 *						записи с указаным ключом.
 * @param	tag			Раздел gameState, в котором должен осуществляться поиск.
 *						Если не указан, то определяется в функции getDefaultGameStateTag.
--]]
function HasGameState(state, value, tag)
	tag = tag or getDefaultGameStateTag()
	
	local gameState	= current_player.gameState
	
	if gameState:hasState(state, tag) then
		return (not value) or gameState:getState(state, tag):hasValue(value)
	end

	return false
end
-------------------------------------------------------------------------------

--[[
 * Функция добавляет новую запись в указаный раздел gameState. При этом, если записи с
 * указаными ключем или ключем/значением уже существуют, то они не удаляются. А новая запись
 * добавится как дубликат.
 * @param	state		Ключ добавляемой записи.
 * @param	value		Значение добавляемой записи.
 * @param	tag			Раздел gameState, в котором должна быть добавлена запись.
 *						Если не указан, то определяется в функции getDefaultGameStateTag.
--]]
function AddGameState(state, value, tag)
	tag = tag or getDefaultGameStateTag()
	current_player.gameState:addState(state, value, tag)
end
-------------------------------------------------------------------------------

--[[
 * Функция добавляет новую запись в указаный раздел gameState, УДАЛЯЯ ВСЕ уже существующие
 * записи с переданым ключем. Таким образом гарантируется уникальность записи.
 * @param	state		Ключ добавляемой записи.
 * @param	value		Значение добавляемой записи.
 * @param	tag			Раздел gameState, в котором должна быть добавлена запись.
 *						Если не указан, то определяется в функции getDefaultGameStateTag.
--]]
function SetGameState(state, value, tag)
	tag = tag or getDefaultGameStateTag()
	current_player.gameState:setState(state, value, tag)
end
-------------------------------------------------------------------------------

--[[
 * Функция возращает экземпляр класса GameStateRecord, который хранит в себе все значения для
 * указаного ключа. Получить конкретного значение можно с помощью метода "get",
 * передав его индекс. Также GameStateRecord имеет методы addValue, hasValue и getSize.
 * @param	state		Ключ, значени которого необходимо получить.
 * @param	tag			Раздел gameState, из которого должна быть получена запись.
 *						Если не указан, то определяется в функции getDefaultGameStateTag.
--]]
function GetGameState(state, tag)
	tag = tag or getDefaultGameStateTag()
	return current_player.gameState:getState(state, tag)
end
-------------------------------------------------------------------------------

--[[
 * Функция удаляет запись с указыными ключ/значение в определенном разделе gameState.
 * Можно удалить либо конкретную запись (указав и value), либо все записи с указаным ключем.
 * @param	state		Ключ удаляемой записи.
 * @param	value		Значение удаляемой записи. Если не указано, то удалятся все записи с
 *						ключем, переданым в state.
 * @param	tag			Раздел gameState, в котором должна быть удалена запись.
 *						Если не указан, то определяется в функции getDefaultGameStateTag.
--]]
function RemoveGameState(state, value, tag)
    tag = tag or getDefaultGameStateTag()

    if not value then
        current_player.gameState:removeState(state, tag)
    else
        current_player.gameState:removeStateValue(state, value, tag)
    end
end
-------------------------------------------------------------------------------

--[[
 * Функция добавляет новую запись только в том случае, если записи с такими же ключ/значение
 * еще не было добавлено в указаный раздел gameState. Это обеспечивает защиту бесполезного
 * переполнения gameState идентичными записями.
 * @param	state		Ключ добавляемой записи.
 * @param	value		Значение добавляемой записи.
 * @param	tag			Раздел gameState, в котором должна быть добавлена запись.
 *						Если не указан, то определяется в функции getDefaultGameStateTag.
--]]
function AddUniqueGameState(state, value, tag)
	tag = tag or getDefaultGameStateTag()

    if not HasGameState(state, value, tag) then
        AddGameState(state, value, tag)
    end
end
-------------------------------------------------------------------------------

--[[
 * Функция проверяет, существует ли запись с указыными ключ/значение в определенном разделе gameState
 * и удаляет ее если она найдена.
 * Можно удалить либо конкретную запись (указав и value), либо все записи с указаным ключем.
 * @param	state		Ключ удаляемой записи.
 * @param	value		Значение удаляемой записи. Если не указано, то удалятся все записи с
 *						ключем, переданым в state.
 * @param	tag			Раздел gameState, в котором должна быть удалена запись.
 *						Если не указан, то определяется в функции getDefaultGameStateTag.
--]]
function SafeRemoveGameState(state, value, tag)
	tag = tag or getDefaultGameStateTag()

	if HasGameState(state, value, tag) then
		RemoveGameState(state, value, tag)
	end
end
-------------------------------------------------------------------------------