--[[
 regFillTypes

  @author: Ifko[nator]
  @date: 03.05.2017
  @version: 1.5
 
  @usage:

	<extraSourceFiles>
        <sourceFile filename="regFillTypes.lua"/>
    </extraSourceFiles>
	
	<l10n>
		<text name="kalk">
			<de>Kalk</de>
			<en>lime</en>
		</text>
	</l10n>

	<regFillTypes hudDirectoryFillTypes="maps/hud/fillTypes" textureDirectoryFillPlanes="maps/fillPlanes" newCategories="">
		<fillType name="kalk" categoryName="bulk" pricePerLiter="0.8" massPerLiter="0.0004" showOnPriceTable="true" maxPhysicalSurfaceAngle="20" createHeap="true" maxSurfaceAngle="30" collisionScale="1.0" collisionBaseOffset="0.08" minCollisionOffset="0.00" maxCollisionOffset="0.08" fillToGroundScale="1" allowsSmoothing="true" useToSpray="true" sprayerCategoryName="spreader" litersPerSecond="0.06" addToAnFoodGroup="true" animals="cow pig" foodGroups="grass base"/>
	</regFillTypes>
	
	with 'newCategories' you can register new fill type categories
	
	example for the huds from the fillTypes:
	
	../path_from_hudDirectoryFillTypes/hud_fill_kalk.dds	 --## necessarily required
	../path_from_hudDirectoryFillTypes/hud_fill_kalk_sml.dds --## not necessarily required 

	example for textures from 'TipAnywhere' heaps:
	
	../path_from_textureDirectoryFillPlanes/kalk_diffuse.dds 				  --## main textur 		   -- save in DXT5 ARGB 8 bpp | interpolated alpha
	../path_from_textureDirectoryFillPlanes/kalk_normal.dds 				  --## textur for details  -- save in DXT1 ARGB 4 bpp | 1 bit alpha
	../path_from_textureDirectoryFillPlanes/distance/kalkDistance_diffuse.dds --## textur for distance -- save in DXT1 ARGB 4 bpp | 1 bit alpha 
	
	supported values for 'categoryName': (multiply values are possible! e.g.: categoryName="bulk forageWagon trainWagon augerWagon")
	
	liquid			
	windrow
	piece
	animal
	combine
	forageHarvester
	forageWagon
	fork
	trainWagon
	augerWagon
	
	supported values for 'sprayerCategoryName': (multiply values are possible! e.g.: sprayerCategoryName="spreader manureSpreader")
	
	spreader 		--## should include ALL fertilizer spreaders (Düngerstreuer)
	sprayer			--## should include ALL sprayers (Spritzen)
	manureSpreader	--## should include ALL manure spreaders (Miststreuer)
	slurryTank		--## should include ALL slurry tanks (Güllefässer)
	
	supported values for 'animals': (multiply values are possible! e.g.: animals="cow sheep")
	
	cow	
	sheep
	pig
	
	supported values for 'foodGroups': (multiply values are possible! e.g.: foodGroups="grass base protein")
	
	grass 		--## possible for animal: sheep, cow and pig
	base 		--## possible for animal: cow
	power 		--## possible for animal: cow
	grain 		--## possible for animal: pig
	protein 	--## possible for animal: pig
	earth		--## possible for animal: pig
]]

local modDesc = loadXMLFile("modDescXML", g_currentModDirectory .. "modDesc.xml");
local key = "modDesc.regFillTypes";

local hudDirectoryFillTypes = getXMLString(modDesc, key .. "#hudDirectoryFillTypes");
local textureDirectoryFillPlanes = getXMLString(modDesc, key .. "#textureDirectoryFillPlanes");

local newCategories = Utils.splitString(" ", Utils.getNoNil(getXMLString(modDesc, key .. "#newCategories"), ""));

for _, newCategory in pairs(newCategories) do
	if FillUtil["FILLTYPE_CATEGORY_" .. string.upper(newCategory)] == nil then
		if newCategory ~= "" then
			FillUtil.registerFillTypeCategory(newCategory);
		
			print("\\____ Register fill type category: '" .. newCategory .. "'");
		end;
	else
		print("[INFO from the regFillTypes.lua]: The category: '" .. newCategory .. "' are allready exists!. Aborting register this category now!");
	end;
end;

if (hudDirectoryFillTypes and textureDirectoryFillPlanes) ~= nil then
	hudDirectoryFillTypes = g_currentModDirectory .. hudDirectoryFillTypes;
	textureDirectoryFillPlanes = g_currentModDirectory .. textureDirectoryFillPlanes;
	
	local fillTypeNumber = 0;
	
	while true do
		local fillTypeKey = key .. ".fillType(" .. tostring(fillTypeNumber) .. ")";
		
		if not hasXMLProperty(modDesc, fillTypeKey) then
			break;
		end;
	
		local name = getXMLString(modDesc, fillTypeKey .. "#name");
		
		if name == nil then
			print("Error: missing 'name' attribute for fillType(" .. fillTypeNumber .. ") in 'regFillTypes'. Adding fillTypes aborted.");
			
			break;
		end;
		
		local newFillType = "FILLTYPE_" .. string.upper(name);
		
		if FillUtil[newFillType] == nil then
			local fillType = {
				name = name,
				category = nil, --## will be set correctly in line 183
				pricePerLiter = Utils.getNoNil(getXMLFloat(modDesc, fillTypeKey .. "#pricePerLiter"), 0.8),
				massPerLiter = Utils.getNoNil(getXMLFloat(modDesc, fillTypeKey .. "#massPerLiter"), 0.0002),
				showOnPriceTable = Utils.getNoNil(getXMLBool(modDesc, fillTypeKey .. "#showOnPriceTable"), false),
				maxPhysicalSurfaceAngle = Utils.getNoNilRad(getXMLFloat(modDesc, fillTypeKey .. "#maxPhysicalSurfaceAngle"), 20),
				createHeap = Utils.getNoNil(getXMLBool(modDesc, fillTypeKey .. "#createHeap"), true),
				maxSurfaceAngle = Utils.getNoNilRad(getXMLFloat(modDesc, fillTypeKey .. "#maxSurfaceAngle"), 20),
				collisionScale = Utils.getNoNil(getXMLFloat(modDesc, fillTypeKey .. "#collisionScale"), 1.0),
				collisionBaseOffset = Utils.getNoNil(getXMLFloat(modDesc, fillTypeKey .. "#collisionBaseOffset"), 0.08),
				minCollisionOffset = Utils.getNoNil(getXMLFloat(modDesc, fillTypeKey .. "#minCollisionOffset"), 0.0),
				maxCollisionOffset = Utils.getNoNil(getXMLFloat(modDesc, fillTypeKey .. "#maxCollisionOffset"), 0.08),
				fillToGroundScale = Utils.getNoNil(getXMLFloat(modDesc, fillTypeKey .. "#fillToGroundScale"), 1),
				allowsSmoothing = Utils.getNoNil(getXMLBool(modDesc, fillTypeKey .. "#allowsSmoothing"), false),
				useToSpray = Utils.getNoNil(getXMLBool(modDesc, fillTypeKey .. "#useToSpray"), false),
				litersPerSecond = Utils.round(Utils.getNoNil(getXMLFloat(modDesc, fillTypeKey .. "#litersPerSecond"), 0.006), 3),
				sprayerCategoryName = Utils.getNoNil(getXMLString(modDesc, fillTypeKey .. "#sprayerCategoryName"), "spreader"),
				hud_fill = hudDirectoryFillTypes .. "/hud_fill_" .. name .. ".dds",
				addToAnFoodGroup = Utils.getNoNil(getXMLBool(modDesc, fillTypeKey .. "#addToAnFoodGroup"), false),
				animals = Utils.getNoNil(getXMLString(modDesc, fillTypeKey .. "#animals"), "cow pig"),
				foodGroups = Utils.getNoNil(getXMLString(modDesc, fillTypeKey .. "#foodGroups"), "grass base")
			};
	
			local localFillTypeName = fillType.name;
			
			if g_i18n:hasText(fillType.name) then
				localFillTypeName = g_i18n:getText(fillType.name);
			else
				print("[INFO from the regFillTypes.lua]: Missing the l10n entry for '" .. fillType.name .. "'. This is not a problem, but its not 100% perfect");
			end;
			
			g_i18n.globalI18N.texts[fillType.name] = localFillTypeName;
			
			local hudFile_small = hudDirectoryFillTypes .. "/hud_fill_" .. fillType.name .. "_sml.dds";
			
			if not fileExists(hudFile_small) then				
				print("[INFO from the regFillTypes.lua]: Can't find: '" .. hudFile_small .. "'. This is not a problem, but its not 100% perfect");
				
				hudFile_small = fillType.hud_fill;
			end;	
	
			local registeredFillType = FillUtil.registerFillType(
				fillType.name, 
				localFillTypeName, 
				nil, --## will be set correctly in line 183
				fillType.pricePerLiter, 
				fillType.showOnPriceTable, 
				fillType.hud_fill, 
				hudFile_small, 
				fillType.massPerLiter, 
				fillType.maxPhysicalSurfaceAngle
			);
			
			if registeredFillType ~= nil then
				print("\\__ Register fillType: '" .. localFillTypeName .. "' (" .. fillType.name .. ") [key ".. tostring(registeredFillType) .. "]");
			end;
			
			local fillTypeCategories = Utils.splitString(" ", getXMLString(modDesc, fillTypeKey .. "#categoryName"));
			
			for _, fillTypeCategory in pairs(fillTypeCategories) do
				if fillTypeCategory ~= "" then	
					fillTypeCategory = "FILLTYPE_CATEGORY_" .. string.upper(fillTypeCategory);
				
					if FillUtil[fillTypeCategory] ~= nil then
						FillUtil.addFillTypeToCategory(FillUtil[fillTypeCategory], FillUtil[newFillType]);
						
						print("\\____ Add fillType: '" .. localFillTypeName .. "' to category: '" .. fillTypeCategory .. "' [key " .. FillUtil[fillTypeCategory] .."]");
					else
						print("[ERROR from the regFillTypes.lua]: The category: '" .. fillTypeCategory .. "' are not exists!. Aborting adding fillType: '" .. localFillTypeName .. "' to this category now!");
					end;
				end;
			end;
			
			if fillType.useToSpray then
				local sprayType = "SPRAYTYPE_" .. string.upper(fillType.name);
				
				if Sprayer[sprayType] == nil then
					Sprayer.registerSprayType(
						fillType.name, 
						localFillTypeName, 
						nil, --## has added fillType already to the right category in line 183
						fillType.pricePerLiter, 
						fillType.litersPerSecond, 
						fillType.showOnPriceTable, 
						fillType.hud_fill, 
						hudFile_small, 
						fillType.massPerLiter
					);
					
					print("\\___ Register sprayType: '" .. localFillTypeName .. "'");
				else
					print("Info: spray type '" .. localFillTypeName .. "' already exists. 'regFillTypes' will skip its registration.");
				end;
				
				local sprayerCategories = Utils.splitString(" ", fillType.sprayerCategoryName);
				
				for _, sprayerCategory in pairs(sprayerCategories) do
					sprayerCategory = "FILLTYPE_CATEGORY_" .. string.upper(sprayerCategory);
				
					if FillUtil[sprayerCategory] ~= nil then
						FillUtil.addFillTypeToCategory(FillUtil[sprayerCategory], FillUtil[newFillType]);
						
						print("\\____ Add sprayType: '" .. localFillTypeName .. "' to category: '" .. sprayerCategory .. "' [key " .. FillUtil[sprayerCategory] .."]");
					else
						print("[ERROR from the regFillTypes.lua]: The category: '" .. sprayerCategory .. "' are not exists!. Aborting adding spray type: '" .. localFillTypeName .. "' to this category now!");
					end;
				end;
			end;
			
			if fillType.createHeap then
				fillType.diffuseMap = Utils.getFilename(string.format("%s/%s_diffuse.dds", textureDirectoryFillPlanes, fillType.name));
				fillType.normalMap = Utils.getFilename(string.format("%s/%s_normal.dds", textureDirectoryFillPlanes, fillType.name));
				fillType.distanceMap = Utils.getFilename(string.format("%s/distance/%sDistance_diffuse.dds", textureDirectoryFillPlanes, fillType.name));
				
				local hasAllTextures = fileExists(fillType.diffuseMap) and fileExists(fillType.normalMap) and fileExists(fillType.distanceMap);
				
				if hasAllTextures then
					TipUtil.registerDensityMapHeightType(
						FillUtil[newFillType], 
						fillType.maxSurfaceAngle, 
						fillType.collisionScale, 
						fillType.collisionBaseOffset, 
						fillType.minCollisionOffset, 
						fillType.maxCollisionOffset, 
						fillType.fillToGroundScale, 
						fillType.allowsSmoothing, 
						fillType.diffuseMap, 
						fillType.normalMap, 
						fillType.distanceMap
					);
					
					print("\\_____ Register heap for: '" .. localFillTypeName .. "'");
				else
					print("[ERROR from the regFillTypes.lua]: Aborting create heap for '" .. fillType.name.. "' now because:");
				end;
				
				if not fileExists(fillType.diffuseMap) then				
					print("    \\__ can't find: '" .. fillType.diffuseMap .. "' for the heap!");
				end;
				
				if not fileExists(fillType.normalMap) then				
					print("    \\__ can't find: '" .. fillType.normalMap .. "' for the heap!");
				end;
				
				if not fileExists(fillType.distanceMap) then				
					print("    \\__ can't find: '" .. fillType.distanceMap .. "' for the heap!");
				end;	
			end;
			
			if fillType.addToAnFoodGroup then
				local animals = Utils.splitString(" ", fillType.animals);
				local foodGroups = Utils.splitString(" ", fillType.foodGroups);
				
				for _, animal in pairs(animals) do	
					
					for _, foodGroup in pairs(foodGroups) do	
						local foodGroupIndex;
						local animalIndex;
						local stop = false;
					
						if animal == "sheep" then
							animalIndex = AnimalUtil.ANIMAL_SHEEP;
							
							if foodGroup == "grass" then
								foodGroupIndex = 1;
							else
								stop = true;
							end;
						elseif animal == "cow" then
							animalIndex = AnimalUtil.ANIMAL_COW;
							
							if foodGroup == "grass" then
								foodGroupIndex = 1;
							elseif foodGroup == "base" then
								foodGroupIndex = 2;
							elseif foodGroup == "power" then
								foodGroupIndex = 3;
							else
								stop = true;
							end;
						elseif animal == "pig" then
							animalIndex = AnimalUtil.ANIMAL_PIG;
							
							if foodGroup == "grass" then
								foodGroupIndex = 1;
							elseif foodGroup == "grain" then
								foodGroupIndex = 2;
							elseif foodGroup == "protein" then
								foodGroupIndex = 3;
							elseif foodGroup == "earth" then
								foodGroupIndex = 4;
							else
								stop = true;
							end;
						else
							stop = true;
						end;
						
						if not stop then
							FillUtil.registerFillTypeInFoodGroup(
								animalIndex, 
								foodGroupIndex, 
								FillUtil[newFillType]
							);
							
							print("\\______ Add fillType: '" .. localFillTypeName .. "' to food group: '" .. foodGroup .. "' [foodGroupIndex '" .. foodGroupIndex .. "'] from animal '" .. animal .. "' [animalIndex: '" .. animalIndex .. "']");
						end;
					end;
				end;
			end;
			
			fillTypeNumber = fillTypeNumber + 1;
		else
			fillTypeNumber = fillTypeNumber + 1;
			
			print("Info: fill type '" .. name .. "' already exists. 'regFillTypes' will skip its registration.");
		end;
	end;
else
	print("ERROR: The 'regFillTypes' script IS STOPPED NOW because:");

	if hudDirectoryFillTypes == nil then
		print("\\___ can't find hud directory for the fill types.");
	end;
	
	if textureDirectoryFillPlanes == nil then
		print("\\___ can't find texture directory for the fill planes.");
	end;
end;