------------------------------------------------------------------------------
-- 
function InitGameState()
    gameState = {};
    gameState.zoomZones = {};
    gameState.activeZone = nil;
    gameState.prevActiveZoneStack = {};
	gameState.customCursors = {};
	gameState.lockedObjects = {};

    gameState.locker = ReferenceCounter();
    
	gameState.highlightPeriod = 15.0;
    gameState.randomZoneHighlightDelay = 0.0;

	gameState.elapsedTime = 0.0;
	gameState.punishmentDuration = 3.0;
	gameState.punishmentClickCount = 5;
	gameState.prevWrongClickTimeStamp = {-gameState.punishmentDuration,
                                         -gameState.punishmentDuration,
                                         -gameState.punishmentDuration,
                                         -gameState.punishmentDuration,
                                         -gameState.punishmentDuration,
                                         -gameState.punishmentDuration};

	gameState.finalZoomInPos = {SCREEN_WIDTH/2.0, SCREEN_HEIGHT/2.0};
	
	prevObjectName = nil;
end

------------------------------------------------------------------------------
-- 
function SetGameStateParameter(parameterName, value, additionalAction)
	assert(gameState[parameterName] ~= nil);

	gameState[parameterName] = value;
	if (additionalAction ~= nil) then
		additionalAction();
	end
end

------------------------------------------------------------------------------
-- 
function GetLevelGameStateDump()
    assert(gameState ~= nil);
    return auxGetTableFields(gameState, 'gameState.');
end

-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-- 
function auxFormTableElementCreationCode(prefix, fieldName, value, type)
    local result;
    local prefixLen = string.len(prefix);
    
    if (tonumber(fieldName) ~= nil) then
        assert(string.sub(prefix, prefixLen, prefixLen) == '.' and "Unacceptable prefix format. It must ends on char '.'!");
        local fieldNameAdjusted = fieldName;

        if (tonumber(fieldName) == nil) then
            fieldNameAdjusted = '\'' .. fieldName .. '\'';
        end
        result = string.sub(prefix, 1, prefixLen - 1) .. '[' .. fieldNameAdjusted .. '] = ';
    else
        result = prefix .. fieldName .. ' = ';
    end
    
    if (type == 'number') then
        result = result .. value .. ';';
    elseif (type == 'boolean') then
        result = result .. (value == true and 'true' or 'false') .. ';';
    elseif (type == 'string') then
        result = result .. '\'' .. value .. '\';';
    elseif (type == 'table') then
        result = result .. '{};';
    else 
        assert(false and "");
    end
    
    return result;
end
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-- 
function auxGetTableFields(table, prefix)
    local data = '';

    for fieldName, value in pairs(table) do
        local type = type(value);
        local isIgnoreField = (
            (type == 'table' and (fieldName == 'parentZoomZone' or fieldName == 'mapMarkers' or 
                                  fieldName == 'activeZone' or fieldName == 'toolMap') or
                                  fieldName == 'prevActiveZoneStack') or
            false
        );
        local ignoreTableRecreation = (
            (type == 'table' and (fieldName == 'zoomZones' or string.find(fieldName,'ZoomZone') ~= nil)) or
            false
        );
        
        if (isIgnoreField == false and (type == 'number' or type == 'boolean' or type == 'string' or type == 'table')) then
            
            data = data .. (ignoreTableRecreation and '-- ' or '') .. auxFormTableElementCreationCode(prefix, fieldName, value, type);
            if (type == 'table') then
                data = data .. auxGetTableFields(value, prefix  .. fieldName .. '.');
            else
                --// ignore types ('')
--              data = data .. '-- ' .. prefix .. fieldName .. ' (' .. type .. ');';
            end
        else
        --// ignored fields
            data = data .. '-- ' .. prefix .. fieldName ..  ' (' .. type .. ');';
        end
    end
    return data;
end
