ZoneCode = {}

ZoneCode.Assets = {
    IW3 = {
        "PhysPreset",
        "XAnimParts",
        "XModel",
        "Material",
        "MaterialTechniqueSet",
        "GfxImage",
        "snd_alias_list_t",
        "SndCurve",
        "LoadedSound",
        "clipMap_t",
        "ComWorld",
        "GameWorldSp",
        "GameWorldMp",
        "MapEnts",
        "GfxWorld",
        "GfxLightDef",
        "Font_s",
        "MenuList",
        "menuDef_t",
        "LocalizeEntry",
        "WeaponDef",
        "FxEffectDef",
        "FxImpactTable",
        "RawFile",
        "StringTable"
    },

    IW4 = {
        "PhysPreset",
        "PhysCollmap",
        "XAnimParts",
        "XModel",
        "Material",
        "MaterialPixelShader",
        "MaterialVertexShader",
        "MaterialVertexDeclaration",
        "MaterialTechniqueSet",
        "GfxImage",
        "snd_alias_list_t",
        "SndCurve",
        "LoadedSound",
        "clipMap_t",
        "ComWorld",
        "GameWorldSp",
        "GameWorldMp",
        "MapEnts",
        "FxWorld",
        "GfxWorld",
        "GfxLightDef",
        "Font_s",
        "MenuList",
        "menuDef_t",
        "LocalizeEntry",
        "WeaponCompleteDef",
        "FxEffectDef",
        "FxImpactTable",
        "RawFile",
        "StringTable",
        "LeaderboardDef",
        "StructuredDataDefSet",
        "TracerDef",
        "VehicleDef",
        "AddonMapEnts"
    },

    IW5 = {
        "PhysPreset",
        "PhysCollmap",
        "XAnimParts",
        "XModelSurfs",
        "XModel",
        "Material",
        "MaterialPixelShader",
        "MaterialVertexShader",
        "MaterialVertexDeclaration",
        "MaterialTechniqueSet",
        "GfxImage",
        "snd_alias_list_t",
        "SndCurve",
        "LoadedSound",
        "clipMap_t",
        "ComWorld",
        "GlassWorld",
        "PathData",
        "VehicleTrack",
        "MapEnts",
        "FxWorld",
        "GfxWorld",
        "GfxLightDef",
        "Font_s",
        "MenuList",
        "menuDef_t",
        "LocalizeEntry",
        "WeaponAttachment",
        "WeaponCompleteDef",
        "FxEffectDef",
        "FxImpactTable",
        "SurfaceFxTable",
        "RawFile",
        "ScriptFile",
        "StringTable",
        "LeaderboardDef",
        "StructuredDataDefSet",
        "TracerDef",
        "VehicleDef",
        "AddonMapEnts",
    },

    QOS = {
        "PhysPreset",
        "PhysConstraints",
        "DestructibleDef",
        "XAnimParts",
        "XModel",
        "Material",
        "MaterialTechniqueSet",
        "GfxImage",
        "snd_alias_list_t",
        "SndCurve",
        "clipMap_t",
        "ComWorld",
        "GameWorldSp",
        "GameWorldMp",
        "MapEnts",
        "GfxWorld",
        "GfxLightDef",
        "Font_s",
        "MenuList",
        "menuDef_t",
        "LocalizeEntry",
        "WeaponDef",
        "FxEffectDef",
        "FxImpactTable",
        "RawFile",
        "StringTable",
        "XmlTree",
        "SceneAnimation",
        "Cutscene",
        "CustomCamera",
    },

    T4 = {
        "PhysPreset",
        "PhysConstraints",
        "DestructibleDef",
        "XAnimParts",
        "XModel",
        "Material",
        "MaterialTechniqueSet",
        "GfxImage",
        "snd_alias_list_t",
        "SndDriverGlobals",
        "LoadedSound",
        "clipMap_t",
        "ComWorld",
        "GameWorldSp",
        "GameWorldMp",
        "MapEnts",
        "GfxWorld",
        "GfxLightDef",
        "Font_s",
        "MenuList",
        "menuDef_t",
        "LocalizeEntry",
        "WeaponDef",
        "FxEffectDef",
        "FxImpactTable",
        "RawFile",
        "StringTable",
        "PackIndex",
    },

    T5 = {
        "PhysPreset",
        "PhysConstraints",
        "DestructibleDef",
        "XAnimParts",
        "XModel",
        "Material",
        "MaterialTechniqueSet",
        "GfxImage",
        "SndBank",
        "SndPatch",
        "clipMap_t",
        "ComWorld",
        "GameWorldSp",
        "GameWorldMp",
        "MapEnts",
        "GfxWorld",
        "GfxLightDef",
        "Font_s",
        "MenuList",
        "menuDef_t",
        "LocalizeEntry",
        "WeaponVariantDef",
        "SndDriverGlobals",
        "FxEffectDef",
        "FxImpactTable",
        "RawFile",
        "StringTable",
        "PackIndex",
        "XGlobals",
        "ddlRoot_t",
        "Glasses",
        "EmblemSet"
    },

    T6 = {
        "PhysPreset",
        "PhysConstraints",
        "DestructibleDef",
        "XAnimParts",
        "XModel",
        "Material",
        "MaterialTechniqueSet",
        "GfxImage",
        "SndBank",
        "SndPatch",
        "clipMap_t",
        "ComWorld",
        "GameWorldSp",
        "GameWorldMp",
        "MapEnts",
        "GfxWorld",
        "GfxLightDef",
        "Font_s",
        "FontIcon",
        "MenuList",
        "menuDef_t",
        "LocalizeEntry",
        "WeaponVariantDef",
        "WeaponAttachment",
        "WeaponAttachmentUnique",
        "WeaponCamo",
        "SndDriverGlobals",
        "FxEffectDef",
        "FxImpactTable",
        "RawFile",
        "StringTable",
        "LeaderboardDef",
        "XGlobals",
        "ddlRoot_t",
        "Glasses",
        "EmblemSet",
        "ScriptParseTree",
        "KeyValuePairs",
        "VehicleDef",
        "MemoryBlock",
        "AddonMapEnts",
        "TracerDef",
        "SkinnedVertsDef",
        "Qdb",
        "Slug",
        "FootstepTableDef",
        "FootstepFXTableDef",
        "ZBarrierDef"
    }
}

function ZoneCode:allTestFiles()
    result = {}

    for game, assets in pairs(self.Assets) do
        local gameLower = string.lower(game)

        for i, assetName in ipairs(assets) do
            local assetNameLower = string.lower(assetName)
            table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_struct_test.cpp")
        end
    end
    
    return result
end

function ZoneCode:allMarkFiles()
    result = {}

    for game, assets in pairs(self.Assets) do
        local gameLower = string.lower(game)

        -- PerAsset
        for i, assetName in ipairs(assets) do
            local assetNameLower = string.lower(assetName)
            table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_mark_db.cpp")
            table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_mark_db.h")
        end
        
        -- PerTemplate
        table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/AssetMarker" .. game .. ".h")
    end
    
    return result
end

function ZoneCode:allLoadFiles()
    result = {}

    for game, assets in pairs(self.Assets) do
        local gameLower = string.lower(game)

        -- PerAsset
        for i, assetName in ipairs(assets) do
            local assetNameLower = string.lower(assetName)
            table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_load_db.cpp")
            table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_load_db.h")
        end
        
        -- PerTemplate
        table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/AssetLoader" .. game .. ".h")
    end
    
    return result
end

function ZoneCode:allWriteFiles()
    result = {}

    for game, assets in pairs(self.Assets) do
        local gameLower = string.lower(game)

        -- PerAsset
        for i, assetName in ipairs(assets) do
            local assetNameLower = string.lower(assetName)
            table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_write_db.cpp")
            table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_write_db.h")
        end
        
        -- PerTemplate
        table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/AssetWriter" .. game .. ".h")
    end
    
    return result
end

function ZoneCode:include(includes)
	if includes:handle(self:name()) then
		Common:include(includes)
        includedirs {
            path.join(ProjectFolder(), "ZoneCode"),
            "%{wks.location}/src/ZoneCode"
        }
    end
end

function ZoneCode:link(links)
    
end

function ZoneCode:use()
	dependson(self:name())
end

function ZoneCode:name()
    return "ZoneCode"
end

function ZoneCode:project()
	local folder = ProjectFolder()
	local includes = Includes:create()

	project(self:name())
        targetdir(TargetDirectoryLib)
		location "%{wks.location}/src/%{prj.name}"
		kind "Utility"
		
		files {
			path.join(folder, "ZoneCode/**.gen"),
			path.join(folder, "ZoneCode/**.h"),
			path.join(folder, "ZoneCode/**.txt")
        }
		
        vpaths {
			["*"] = {
				path.join(folder, "ZoneCode")
			}
		}

        self:include(includes)
        ZoneCodeGenerator:use()

        filter "files:**.gen"
            buildmessage "Generating ZoneCode for game %{file.basename}"
            buildcommands {
                '"' .. TargetDirectoryBuildTools .. '/' .. ExecutableByOs('ZoneCodeGenerator') .. '"' 
                    .. ' --no-color'
                    .. ' -h "' .. path.join(path.getabsolute(ProjectFolder()), 'ZoneCode/Game/%{file.basename}/%{file.basename}_ZoneCode.h') .. '"'
                    .. ' -c "' .. path.join(path.getabsolute(ProjectFolder()), 'ZoneCode/Game/%{file.basename}/%{file.basename}_Commands.txt') .. '"'
                    .. ' -o "%{wks.location}/src/ZoneCode/Game/%{file.basename}"'
                    .. ' --build-log "%{wks.location}/src/ZoneCode/Game/%{file.basename}.log"'
                    .. ' -g ZoneLoad'
                    .. ' -g ZoneMark'
                    .. ' -g ZoneWrite'
                    .. ' -g AssetStructTests'
            }
            buildinputs {
                path.join(ProjectFolder(), "ZoneCode/Game/%{file.basename}/%{file.basename}_ZoneCode.h"),
                path.join(ProjectFolder(), "ZoneCode/Game/%{file.basename}/%{file.basename}_Commands.txt"),
                path.join(ProjectFolder(), "Common/Game/%{file.basename}/%{file.basename}_Assets.h"),
                TargetDirectoryBuildTools .. "/" .. ExecutableByOs('ZoneCodeGenerator')
            }
            buildoutputs {
                "%{wks.location}/src/ZoneCode/Game/%{file.basename}.log"
            }
        filter {}
end
