maizePlus_animalFood = {};
maizePlus_animalFood.modDirectory = g_currentModDirectory;

maizePlus_animalFood.CONSUMPTION_TYPE_PARALLEL = 2;
maizePlus_animalFood.CONSUMPTION_TYPE_SERIAL = 1;

-- load our default animalFood XML from our mod
maizePlus_animalFood.xmlFile = loadXMLFile("animalFoodXMLFile", maizePlus_animalFood.modDirectory.."animalFood.xml")


function maizePlus_animalFood:loadMixerWagonStuff(xmlFile)

    if xmlFile ~= nil then

        maizePlus_animalFood.mixerWagonFillTypes = {}
        maizePlus_animalFood.fillTypeToMixerWagonFillType = {}
		
		local sumRatio = 0
		
        local i = 0
        while true do
            local key = "animalFood.mixerWagonSettings.mixerWagonFillTypes.mixerWagonFillType(".. i ..")"

            local name = getXMLString(xmlFile, key .. "#name")

            if name ~= "" and name ~= nil then
                local fillType = {}

                fillType.fillLevel = 0
                fillType.minPercentage = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#minPercentage"), 0)*0.01
                fillType.maxPercentage = Utils.getNoNil(getXMLFloat(xmlFile, key .. "#maxPercentage"), 100)*0.01
                fillType.name = name
                fillType.ratio = fillType.maxPercentage - fillType.minPercentage

                -- load fillTypes for fillType 
                fillType.fillTypes = {}
                local x = 0
                while true do
                    local keyX = key .. ".fillType("..x..")#fillType"
                    local fillTypeName = getXMLString(xmlFile, keyX)
                    if fillTypeName ~= "" and fillTypeName ~= nil then
                    
                        -- get fillType index from name 
                        local index = g_fillTypeManager:getFillTypeIndexByName(fillTypeName)

                        if index ~= nil then

                            fillType.fillTypes[index] = true

                            maizePlus_animalFood.fillTypeToMixerWagonFillType[index] = fillType
                        else
							if not maizePlus_animalFood.ignoreFillTypesWithoutWarning[tostring(string.upper(fillTypeName))] then
								print("MaizePlus_forageExtension: Filltype "..tostring(fillTypeName).." in mixerWagonSettings does not exist.")
							end
                        end
                    else
                        break
                    end
                    x = x+1
                end
                maizePlus_animalFood.mixerWagonFillTypes[i+1] = fillType   
				sumRatio = sumRatio + fillType.ratio
            else
                break
            end

            i = i+1
        end
		
		for _, fillType in pairs(maizePlus_animalFood.mixerWagonFillTypes) do
			fillType.ratio = fillType.ratio / sumRatio
		end
 
    end

end

function maizePlus_animalFood.buyableBale_onLoad(self, savegame)
    self.spec_buyableBale.baleFilename = Utils.getFilename(self.spec_buyableBale.baleFilename, self.baseDirectory)

    self.spec_buyableBale.wantedFillLevel = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.buyableBale#wantedFillLevel"), 4000)
end

function maizePlus_animalFood.buyableBale_loadBaleAtPosition(self, superFunc, position)
    local spec = self.spec_buyableBale

    -- only replace function for bales loaded from our folder, otherwise use superFunc
    if self.customEnvironment == "FS19_MaizePlus_forageExtension" then

        if self.isServer or self.propertyState == Vehicle.PROPERTY_STATE_SHOP_CONFIG then
            local x, y, z = localToWorld(self.components[1].node, unpack(position.position))
            local rx, ry, rz = localRotationToWorld(self.components[1].node, unpack(position.rotation))
    
            local baleObject = Bale:new(self.isServer, self.isClient)
            baleObject:load(spec.baleFilename, x,y,z, rx,ry,rz, self.spec_buyableBale.wantedFillLevel)
            baleObject:setOwnerFarmId(self:getActiveFarm(), true)
            if self.propertyState ~= Vehicle.PROPERTY_STATE_SHOP_CONFIG then
                baleObject:register()
            end
            baleObject:setCanBeSold(false)
    
            if spec.isWrapped then
                baleObject:setWrappingState(1)
    
                if self.configurations["baseColor"] ~= nil then
                    local color = ConfigurationUtil.getColorByConfigId(self, "baseColor", self.configurations["baseColor"])
                    baleObject:setColor(unpack(color))
                end
            end
    
            setPairCollision(self.components[1].node, baleObject.nodeId, false)
    
            table.insert(spec.loadedBales, baleObject)
        end

    else
        superFunc(self, position)
    end

end

-- load ignore fillTypes 
function maizePlus_animalFood:loadIgnoreFillTypesWithoutWarning(xmlFile)
	local fillTypesString = getXMLString(xmlFile, "animalFood.ignoreFillTypesWithoutWarning#fillTypes")
	if fillTypesString ~= nil and fillTypesString ~= "" then
		local fillTypeTable = StringUtil.splitString(" ", fillTypesString)
		for x = 1, #fillTypeTable do
			maizePlus_animalFood.ignoreFillTypesWithoutWarning[string.upper(tostring(fillTypeTable[x]))] = true
		end
	end
end

function maizePlus_animalFood:loadMap(n)

    g_particleSystemManager:addParticleType("pellet")
    g_particleSystemManager:addParticleType("pellet_move")
    g_particleSystemManager:addParticleType("pellet_smoke")

	
	-- load mixer wagon stuff 
    maizePlus_animalFood:loadMixerWagonStuff(maizePlus_animalFood.xmlFile)
    

    -- load additional file from map if it exists. Additional animals can be added via Map, also default settings can be overwritten
    if fileExists(g_currentMission.missionInfo.baseDirectory.."maizePlus/animalFoodAdditions.xml") then
        local mapXMLFile = loadXMLFile("mapAnimalFoodXMLFile", g_currentMission.missionInfo.baseDirectory.."maizePlus/animalFoodAdditions.xml")
		
        if mapXMLFile ~= nil then
			self:loadIgnoreFillTypesWithoutWarning(mapXMLFile)
			
            self:loadFoodGroupsAppend(nil, nil, mapXMLFile)

            self:loadMixturesAppend(nil, nil, mapXMLFile)
			
			maizePlus_animalFood:loadMixerWagonStuff(mapXMLFile)
            print("MaizePlus_forageExtion: animalFoodAdditions.xml from Map "..tostring(g_currentMission.missionInfo.customEnvironment).." loaded.")
        end
    end
	
	local mod = g_modManager:getModByName("FS19_maizePlus_animalFoodAdditions")
	if mod ~= nil then
		if g_modIsLoaded["FS19_maizePlus_animalFoodAdditions"] then
			local modAfaXMLFile = loadXMLFile("modAfaXMLFile", mod.modDir.."animalFoodAdditions.xml");
			 
	        if modAfaXMLFile ~= nil then
				self:loadIgnoreFillTypesWithoutWarning(modAfaXMLFile)
				
				self:loadFoodGroupsAppend(nil, nil, modAfaXMLFile)

				self:loadMixturesAppend(nil, nil, modAfaXMLFile)
				
				maizePlus_animalFood:loadMixerWagonStuff(modAfaXMLFile)
				print("MaizePlus_forageExtension: animalFoodAdditions.xml from FS19_maizePlus_animalFoodAdditions loaded. This has Priority over other animalFoodAdditions in the map.")	
			end;
		end;
	end;
	
	-- loading material holders 
    local particle_materialHolderFilename = Utils.getFilename("materialHolder/particle_materialHolder.i3d", maizePlus_animalFood.modDirectory)
    maizePlus_animalFood.particle_materialHolderFilename = loadI3DFile(particle_materialHolderFilename, false, true, false)
    
    local effect_materialHolderFilename = Utils.getFilename("materialHolder/effect_materialHolder.i3d", maizePlus_animalFood.modDirectory)
    maizePlus_animalFood.effect_materialHolderFilename = loadI3DFile(effect_materialHolderFilename, false, true, false)

    local fillPlane_materialHolderFilename = Utils.getFilename("materialHolder/fillPlane_materialHolder.i3d", maizePlus_animalFood.modDirectory)
    maizePlus_animalFood.fillPlane_materialHolderFilename = loadI3DFile(fillPlane_materialHolderFilename, false, true, false)  
	
    local additionalFillplanes_materialHolderFilename = Utils.getFilename("materialHolder/additionalFillplanes_materialHolder.i3d", maizePlus_animalFood.modDirectory)
    maizePlus_animalFood.additionalFillplanes_materialHolderFilename = loadI3DFile(additionalFillplanes_materialHolderFilename, false, true, false)  
	
    local additionalParticle_materialHolderFilename = Utils.getFilename("materialHolder/additionalParticle_materialHolder.i3d", maizePlus_animalFood.modDirectory)
    maizePlus_animalFood.additionalParticle_materialHolderFilename = loadI3DFile(additionalParticle_materialHolderFilename, false, true, false)
    	
    local additionalEffect_materialHolder = Utils.getFilename("materialHolder/additionalEffect_materialHolder.i3d", maizePlus_animalFood.modDirectory)
    maizePlus_animalFood.additionalEffect_materialHolder = loadI3DFile(additionalEffect_materialHolder, false, true, false)
	
	loadI3DFile(Utils.getFilename("materialHolder/pigFood2/effect_materialHolder.i3d", maizePlus_animalFood.modDirectory), false, true, false)	
	loadI3DFile(Utils.getFilename("materialHolder/pigFood2/fillPlane_materialHolder.i3d", maizePlus_animalFood.modDirectory), false, true, false)	
	loadI3DFile(Utils.getFilename("materialHolder/matHolder.i3d", maizePlus_animalFood.modDirectory), false, true, false)	
	loadI3DFile(Utils.getFilename("materialHolder/particles.i3d", maizePlus_animalFood.modDirectory), false, true, false)	
		
end;

function maizePlus_animalFood:keyEvent(unicode, sym, modifier, isDown)
end;
function maizePlus_animalFood:update(dt)
end;
function maizePlus_animalFood:draw()
end;
function maizePlus_animalFood:deleteMap()
end;
function maizePlus_animalFood:mouseEvent(posX, posY, isDown, isUp, button)
end;

addModEventListener(maizePlus_animalFood);

function maizePlus_animalFood.loadFillType(hudFile, hudFileSmall, price, massPerLiter, fillTypeName, textName, heapAngle, windrow, notBulk, notForageWagon, notSilageTrailer, notFork, notLiquid)

    local fillType = g_fillTypeManager:addFillType(fillTypeName, g_i18n:getText(textName), true, price, massPerLiter, heapAngle, hudFile, hudFileSmall, maizePlus_animalFood.modDirectory, nil, {1, 1, 1}, nil, false)
    
    if fillType == nil then
        print("MaizePlus_forageExtension: Error, could not add FillType "..tostring(fillTypeName))       
    else
        local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillTypeName)
		
		if windrow then
			g_fillTypeManager:addFillTypeToCategory(fillTypeIndex, g_fillTypeManager.nameToCategoryIndex["WINDROW"])
		end
		if not notBulk then
			g_fillTypeManager:addFillTypeToCategory(fillTypeIndex, g_fillTypeManager.nameToCategoryIndex["BULK"])
		end
		if not notForageWagon then
			g_fillTypeManager:addFillTypeToCategory(fillTypeIndex, g_fillTypeManager.nameToCategoryIndex["FORAGEWAGON"])
		end
		if not notSilageTrailer then
			g_fillTypeManager:addFillTypeToCategory(fillTypeIndex, g_fillTypeManager.nameToCategoryIndex["SILAGETRAILER"])	
		end
		if not notFork then
			g_fillTypeManager:addFillTypeToCategory(fillTypeIndex, g_fillTypeManager.nameToCategoryIndex["FORK"])
		end			
		if not notLiquid then
			g_fillTypeManager:addFillTypeToCategory(fillTypeIndex, g_fillTypeManager.nameToCategoryIndex["LIQUID"])		
		end;
    end
end


function maizePlus_animalFood.addHeightType(fillType, diffuseName, normalName, distanceName, heapAngle, colScale, baseOffset, minOffset, maxOffset, fillToGroundScale, allowSmoothing, soundFillType)
	local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillType)

	g_fillTypeManager.fillTypeToSample[fillTypeIndex] = g_fillTypeManager.fillTypeToSample[g_fillTypeManager:getFillTypeIndexByName(soundFillType)]

	local diffuseMapFilename = Utils.getFilename("fillTypes/"..diffuseName.."_diffuse.png", maizePlus_animalFood.modDirectory)
	local normalMapFilename = Utils.getFilename("fillTypes/"..normalName.."_normal.png", maizePlus_animalFood.modDirectory)	
	local distanceMapFilename = Utils.getFilename("fillTypes/"..distanceName.."_distance_diffuse.png", maizePlus_animalFood.modDirectory)	

    local ht = g_densityMapHeightManager:addDensityMapHeightType(fillType, math.rad(heapAngle), colScale, baseOffset, minOffset, maxOffset, fillToGroundScale, allowSmoothing, diffuseMapFilename, normalMapFilename, distanceMapFilename, false)
	if ht == nil then
		print("MaizePlus Forage Extension: Error, HeightType "..tostring(fillType).." could not be added.")
	end
end


function maizePlus_animalFood.loadHeightTypes(mission, node)

	maizePlus_animalFood.addHeightType("BREWERSGRAIN", "brewersGrain", "brewersGrain", "brewersGrain", 35, 0.8, 0.1, 0.1, 1.2, 1.0, true, "CHAFF") 
	maizePlus_animalFood.addHeightType("BREWERSGRAIN_FERMENTED", "brewersGrain_fermented", "brewersGrain_fermented", "brewersGrain_fermented", 50, 0.95, 0.0, 0.0, 0.0, 1.0, true, "SILAGE") 
	
	maizePlus_animalFood.addHeightType("BEETPULP", "beetPulp", "beetPulp", "beetPulp", 35, 0.8, 0.1, 0.1, 1.2, 1.0, true, "CHAFF") 
	maizePlus_animalFood.addHeightType("BEETPULP_FERMENTED", "beetPulp_fermented", "beetPulp_fermented", "beetPulp_fermented", 50, 0.95, 0.0, 0.0, 0.0, 1.0, true, "SILAGE") 
    -- refreshing the vehicle fillLevels HUD
    g_currentMission.hud.fillLevelsDisplay:refreshFillTypes(g_fillTypeManager)
end

-- 
function maizePlus_animalFood.mixerWagonOnLoadAdd(vehicle, savegame)


    local spec = vehicle.spec_mixerWagon
	
    -- check if we have custom mixerWagon stuff even 
    if #maizePlus_animalFood.mixerWagonFillTypes > 0 then

        -- reset mixerWagon FillTypes 
        spec.mixerWagonFillTypes = {}
        spec.fillTypeToMixerWagonFillType = {}

        -- save our MaizePlus fillTypes into local table for performance reasons? Now that I think of it.. that don't make sense.
        local mp_mixerWagonFillTypes = maizePlus_animalFood.mixerWagonFillTypes
        local mp_fillTypeToMixerWagonFillType = maizePlus_animalFood.fillTypeToMixerWagonFillType

        -- create a list of all fillTypes used in the mixerWagon for later
        local fillTypesList = {}

        -- go through the MP mw fillTypes Table and copy all the values including fillTypes
        for i, value in pairs(mp_mixerWagonFillTypes) do
            spec.mixerWagonFillTypes[i] = {}
            spec.mixerWagonFillTypes[i].fillLevel = value.fillLevel
            spec.mixerWagonFillTypes[i].ratio = value.ratio
            spec.mixerWagonFillTypes[i].minPercentage = value.minPercentage      
            spec.mixerWagonFillTypes[i].maxPercentage = value.maxPercentage  
            spec.mixerWagonFillTypes[i].name = value.name 
            spec.mixerWagonFillTypes[i].fillTypes = {}
            for fillTypeIndex, _ in pairs (value.fillTypes) do
                spec.mixerWagonFillTypes[i].fillTypes[fillTypeIndex] = true
                spec.fillTypeToMixerWagonFillType[fillTypeIndex] = spec.mixerWagonFillTypes[i]
                fillTypesList[fillTypeIndex] = fillTypeIndex
            end
        end

        -- find our fillUnit used for the mixerWagon
        local fillUnit = vehicle.spec_fillUnit.fillUnits[spec.fillUnitIndex]   
        -- reset supportet fillTypes
        fillUnit.supportedFillTypes = {}

        -- go through our new fillType list and add those
        for fillTypeIndex, _ in pairs(fillTypesList) do
            fillUnit.supportedFillTypes[fillTypeIndex] = true
        end

        -- also add forage and forage_mixing
        fillUnit.supportedFillTypes[g_fillTypeManager:getFillTypeIndexByName("FORAGE")] = true
        fillUnit.supportedFillTypes[g_fillTypeManager:getFillTypeIndexByName("FORAGE_MIXING")] = true

    end
	
	if savegame ~= nil then
		for i, entry in ipairs(spec.mixerWagonFillTypes) do
			local fillTypeKey = savegame.key .. string.format(".mixerWagon.fillType(%d)#fillLevel", i - 1)
			local fillLevel = Utils.getNoNil(getXMLFloat(savegame.xmlFile, fillTypeKey), 0)

			if fillLevel > 0 then
				vehicle:addFillUnitFillLevel(vehicle:getOwnerFarmId(), spec.fillUnitIndex, fillLevel, next(entry.fillTypes), ToolType.UNDEFINED, nil)
			end
		end
	end
end

local function registerFillTypes()

    -- ALFALFA_WINDROW 
    maizePlus_animalFood.loadFillType("huds/hud_fill_alfalfa_windrow.png", "huds/hud_fill_alfalfa_windrow_sml.png", 0.048, 0.0005, "ALFALFA_WINDROW", "fillType_alfalfa_windrow", 40, true)

    -- DRYALFALFA_WINDROW
    maizePlus_animalFood.loadFillType("huds/hud_fill_dryAlfalfa_windrow.png", "huds/hud_fill_dryAlfalfa_windrow_sml.png", 0.06, 0.0005, "DRYALFALFA_WINDROW", "fillType_dryAlfalfa_windrow", 40, true)

    -- ALFALFA_FERMENTED 
    maizePlus_animalFood.loadFillType("huds/hud_fill_alfalfa_fermented.png", "huds/hud_fill_alfalfa_fermented_sml.png", 0.14, 0.0007, "ALFALFA_FERMENTED", "fillType_alfalfa_fermented", 40, true)

    -- CLOVER_WINDROW
    maizePlus_animalFood.loadFillType("huds/hud_fill_clover_windrow.png", "huds/hud_fill_clover_windrow_sml.png", 0.048, 0.0005, "CLOVER_WINDROW", "fillType_clover_windrow", 40, true)

    -- DRYCLOVER_WINDROW
    maizePlus_animalFood.loadFillType("huds/hud_fill_dryClover_windrow.png", "huds/hud_fill_dryClover_windrow_sml.png", 0.06, 0.0005, "DRYCLOVER_WINDROW", "fillType_dryClover_windrow", 40, true)
    
    -- CLOVER_FERMENTED
    maizePlus_animalFood.loadFillType("huds/hud_fill_clover_fermented.png", "huds/hud_fill_clover_fermented_sml.png", 0.14, 0.0007, "CLOVER_FERMENTED", "fillType_clover_fermented", 40, true)

    -- CARROT
    maizePlus_animalFood.loadFillType("huds/hud_fill_carrot.png", "huds/hud_fill_carrot_sml.png", 0.122, 0.00065, "CARROT", "fillType_carrot", 34)
	
	-- Version 1.4 additions 
    maizePlus_animalFood.loadFillType("huds/hud_fill_DEUKA_feedPellets.png", "huds/hud_fill_DEUKA_feedPellets_sml.png", 0.85, 0.0003125, "FEEDPELLETS", "fillType_feedPellets", 34, false, false)
    maizePlus_animalFood.loadFillType("huds/hud_fill_DEUKA_grainGrist.png", "huds/hud_fill_DEUKA_grainGrist_sml.png", 0.65, 0.0004, "GRAINGRIST", "fillType_grainGrist", 34, false, false)
    maizePlus_animalFood.loadFillType("huds/hud_fill_DEUKA_minerals.png", "huds/hud_fill_DEUKA_minerals_sml.png", 1.80, 0.001, "MINERALS", "fillType_minerals", 34, false, false)
    maizePlus_animalFood.loadFillType("huds/hud_fill_DEUKA_powerFood.png", "huds/hud_fill_DEUKA_powerFood_sml.png", 1.80, 0.00045, "POWERFOOD", "fillType_powerFood", 34, false, false)
    maizePlus_animalFood.loadFillType("huds/hud_fill_DEUKA_sheepFood.png", "huds/hud_fill_DEUKA_sheepFood_sml.png", 1.80, 0.00043, "SHEEPFOOD", "fillType_sheepFood", 34, false, false)
    maizePlus_animalFood.loadFillType("huds/hud_fill_DEUKA_horseFood.png", "huds/hud_fill_DEUKA_horseFood_sml.png", 1.80, 0.00046, "HORSEFOOD", "fillType_horseFood", 34, false, false)
    maizePlus_animalFood.loadFillType("huds/hud_fill_DEUKA_chickenFood.png", "huds/hud_fill_DEUKA_chickenFood_sml.png", 1.80, 0.00046, "CHICKENFOOD", "fillType_chickenFood", 34, false, false)
	
    maizePlus_animalFood.loadFillType("huds/hud_fill_DEUKA_pig.png", "huds/hud_fill_DEUKA_pig_sml.png", 1.80, 0.00046, "PIGFOOD2", "fillType_pigFood2", 34, false, false)
	
    maizePlus_animalFood.loadFillType("huds/hud_fill_molasses.png", "huds/hud_fill_molasses_sml.png", 1.36, 0.000725, "MOLASSES", "fillType_molasses", 34, false, false, true, true, true, false)

    maizePlus_animalFood.loadFillType("huds/hud_fill_beetPulp.png", "huds/hud_fill_beetPulp_sml.png", 0.141, 0.00044, "BEETPULP", "fillType_beetPulp", 34, false, false)
    maizePlus_animalFood.loadFillType("huds/hud_fill_beetPulp_fermented.png", "huds/hud_fill_beetPulp_fermented_sml.png", 0.141, 0.00044, "BEETPULP_FERMENTED", "fillType_beetPulp_fermented", 34, false, false)
	
    maizePlus_animalFood.loadFillType("huds/hud_fill_beetShreds.png", "huds/hud_fill_beetShreds_sml.png", 0.161, 0.000451, "BEETSHREDS", "fillType_beetShreds", 34, false, false)
    maizePlus_animalFood.loadFillType("huds/hud_fill_potatoShreds.png", "huds/hud_fill_potatoShreds_sml.png", 0.151, 0.00038, "POTATOSHREDS", "fillType_potatoShreds", 34, false, false)
	
    maizePlus_animalFood.loadFillType("huds/hud_fill_clearedWater.png", "huds/hud_fill_clearedWater_sml.png", 0.151, 0.001, "CLEAREDWATER", "fillType_clearedWater", 34, false, true, true, true, true, false)
    maizePlus_animalFood.loadFillType("huds/hud_fill_brewersGrain.png", "huds/hud_fill_brewersGrain_sml.png", 0.151, 0.001, "BREWERSGRAIN", "fillType_brewersGrain", 34, false, false)
    maizePlus_animalFood.loadFillType("huds/hud_fill_brewersGrain_fermented.png", "huds/hud_fill_brewersGrain_fermented_sml.png", 0.151, 0.001, "BREWERSGRAIN_FERMENTED", "fillType_brewersGrain_fermented", 34, false, false)
	
	maizePlus_animalFood.loadFillType("huds/hud_fill_horseGrass_fermented.png", "huds/hud_fill_horseGrass_fermented_sml.png", 0.048, 0.0005, "HORSEGRASS_FERMENTED", "fillType_horseGrass_fermented", 40, true, true, true, true, true, false)
	maizePlus_animalFood.loadFillType("huds/hud_fill_dryHorseGrass_windrow.png", "huds/hud_fill_dryHorseGrass_windrow_sml.png", 0.048, 0.0005, "DRYHORSEGRASS_WINDROW", "fillType_dryHorseGrass_windrow", 40, true, true, true, true, true, false)

	
	
	--loadFillType(hudFile, hudFileSmall, price, massPerLiter, fillTypeName, textName, heapAngle, windrow, notBulk, notForageWagon, notSilageTrailer, notFork, notLiquid)

end

function maizePlus_animalFood.loadFoodGroupsAppend(self, superFunc, xmlFile, xmlFile2)

	local returnValue = false;
	if superFunc ~= nil then
		returnValue = superFunc(self, xmlFile);
	end;
	
	-- get the current XML file either the maizePlus_FE one or the one from the map 
	xmlFile = Utils.getNoNil(xmlFile2, maizePlus_animalFood.xmlFile)
	local i = 0
    while true do -- run through all foodGroups 
        local key = "animalFood.foodGroups.foodGroup("..i..")"
        local animalType = getXMLString(xmlFile, key .. "#animalType")
        if animalType ~= nil and animalType ~= "" then -- if animalType isn't nil 
		
			if g_animalFoodManager.foodGroups[animalType] == nil then -- check if we have this animalType in the foodGroups already, if not create the table 
				g_animalFoodManager.foodGroups[string.upper(animalType)] = {}			
			end;
			
			-- current local foodGroup for the current animal 
            local foodGroup = g_animalFoodManager.foodGroups[animalType]
			
			-- get consumptionType from string 
            foodGroup.consumptionType = maizePlus_animalFood[tostring("CONSUMPTION_TYPE_"..string.upper(getXMLString(xmlFile, key .. "#consumptionType")))] 
		
			-- create/replace content table 
            foodGroup.content = {}
            local x = 0
            while true do
                local keyX = key .. ".content("..x..")"
                local title = getXMLString(xmlFile, keyX .. "#title")
                if title ~= nil and title ~= "" then
                    foodGroup.content[x+1] = {}
                    local content = foodGroup.content[x+1]

                    content.title = title

                    content.productionWeight = Utils.getNoNil(getXMLFloat(xmlFile, keyX .. "#productionWeight"), 0)
                    content.eatWeight = Utils.getNoNil(getXMLFloat(xmlFile, keyX .. "#eatWeight"), 1)
                    
                    content.fillTypes = {}

                    local fillTypeTable = StringUtil.splitString(" ", getXMLString(xmlFile, keyX.."#fillTypes"))

                    for a = 1, #fillTypeTable do
                        local fillType = g_fillTypeManager:getFillTypeIndexByName(tostring(string.upper(fillTypeTable[a])))
                        if fillType ~= nil then
                            table.insert(content.fillTypes, fillType )
                        else
							if not maizePlus_animalFood.ignoreFillTypesWithoutWarning[tostring(string.upper(fillTypeTable[a]))] then
								print("MaizePlus_forageExtension: Filltype "..tostring(fillTypeTable[a]).." in foodGroups does not exist.")
							end
                        end
                    end
                else
                    break
                end
                x = x + 1
            end
        else 
            break
        end
        i = i + 1
    end
	
	return returnValue
end

function maizePlus_animalFood.loadMixturesAppend(self, superFunc, xmlFile, xmlFile2)
	local returnValue = false;
	if superFunc ~= nil then
		returnValue = superFunc(self, xmlFile);
	end;
	
	xmlFile = Utils.getNoNil(xmlFile2, maizePlus_animalFood.xmlFile)
	local b = 0
    while true do
        local key = "animalFood.foodMixtures.foodMixture("..b..")"
        local animalType = getXMLString(xmlFile, key .. "#animalType")
        if animalType ~= nil and animalType ~= "" then
            local fillType = getXMLString(xmlFile, key .. "#fillType")
            fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(fillType)

            if fillTypeIndex ~= nil then
            
                g_animalFoodManager.foodMixtures[fillTypeIndex] = {}
                g_animalFoodManager.foodMixtures[fillTypeIndex].ingredients = {}

                local x = 0
                while true do
                    local key2 = key .. ".ingredient(".. x .. ")"
                    
                    local ingredient = {}

                    ingredient.weight = getXMLFloat(xmlFile, key2 .. "#weight")

                    if ingredient.weight ~= nil then
                    
                        local fillTypeTable = StringUtil.splitString(" ", getXMLString(xmlFile, key2.."#fillTypes"))

                        ingredient.fillTypes = {}
                        for a = 1, #fillTypeTable do
                            local fillType = g_fillTypeManager:getFillTypeIndexByName(tostring(string.upper(fillTypeTable[a])))
                            if fillType ~= nil then
                                table.insert(ingredient.fillTypes, fillType )
                            else
								if not maizePlus_animalFood.ignoreFillTypesWithoutWarning[tostring(string.upper(fillTypeTable[a]))] then
									print("MaizePlus_forageExtension: Filltype "..tostring(fillTypeTable[a]).." in foodMixture does not exist.")
								end
                            end
                        end

                        table.insert(g_animalFoodManager.foodMixtures[fillTypeIndex].ingredients, ingredient)  
                    else
                        break
                    end

                    x = x + 1
                end

				if g_animalFoodManager.animalFoodMixtures[string.upper(animalType)] == nil then
					g_animalFoodManager.animalFoodMixtures[string.upper(animalType)] = {}
				end

                g_animalFoodManager.animalFoodMixtures[string.upper(animalType)][#g_animalFoodManager.animalFoodMixtures[string.upper(animalType)]+1] = fillTypeIndex;
            else
                print("MaizePlus_forageExtension: Filltype "..tostring(fillType).." in foodMixtures does not exist.")
            end
        else
            break
        end
		b = b + 1
	end
	
	return returnValue
end

local function init()
    -- Init fill types
    FillTypeManager.loadMapData = Utils.appendedFunction(FillTypeManager.loadMapData, registerFillTypes)

    -- unload/delete stuff before game closes 
    FSBaseMission.delete = Utils.appendedFunction(FSBaseMission.delete, maizePlus_animalFood.unload)    

    -- append to mixerWagon onLoad
    MixerWagon.onLoad = Utils.appendedFunction(MixerWagon.onLoad, maizePlus_animalFood.mixerWagonOnLoadAdd)

    -- append to buyableBale load to fix filename bug
    BuyableBale.onLoad = Utils.appendedFunction(BuyableBale.onLoad, maizePlus_animalFood.buyableBale_onLoad) 

    -- overwrite loadBaleAtPosition function to inject capacity/fillLevel value
    BuyableBale.loadBaleAtPosition = Utils.overwrittenFunction(BuyableBale.loadBaleAtPosition, maizePlus_animalFood.buyableBale_loadBaleAtPosition)
	
	AnimalFoodManager.loadMixtures = Utils.overwrittenFunction(AnimalFoodManager.loadMixtures, maizePlus_animalFood.loadMixturesAppend)	
	
	AnimalFoodManager.loadFoodGroups = Utils.overwrittenFunction(AnimalFoodManager.loadFoodGroups, maizePlus_animalFood.loadFoodGroupsAppend)
	
	StrawBlower.onLoad = Utils.overwrittenFunction(StrawBlower.onLoad, maizePlus_animalFood.strawBlowerOnLoadNew)
	
	-- Add fillTypes before loadMapFinished to not get stuff mixed up
	FSBaseMission.loadMap = Utils.prependedFunction(FSBaseMission.loadMap, maizePlus_animalFood.loadHeightTypes)
	
	
	maizePlus_animalFood.ignoreFillTypesWithoutWarning = {}
	maizePlus_animalFood:loadIgnoreFillTypesWithoutWarning(maizePlus_animalFood.xmlFile)
end

function maizePlus_animalFood.strawBlowerOnLoadNew(self, superFunc, ...)
	local returnValue = superFunc(self, ...)
	
	local fillUnit = self:getFillUnitByIndex(self.spec_strawBlower.fillUnitIndex)
	
	local names = {"dryGrass_windrow", "dryClover_windrow", "dryAlfalfa_windrow", "grass_fermented", "clover_fermented", "alfalfa_fermented", "horseGrass_fermented", "dryHorseGrass_windrow" }
	
	for _, name in pairs(names) do
		if g_fillTypeManager:getFillTypeIndexByName(name) ~= nil then
			fillUnit.supportedFillTypes[g_fillTypeManager:getFillTypeIndexByName(name)] = true
		end;
	end;
	
	return returnValue
end;

function maizePlus_animalFood.unload()
	if maizePlus_animalFood.effect_materialHolderFilename ~= nil then
		delete(maizePlus_animalFood.effect_materialHolderFilename)
		maizePlus_animalFood.effect_materialHolderFilename = nil
	end	
	if maizePlus_animalFood.particle_materialHolderFilename ~= nil then
		delete(maizePlus_animalFood.particle_materialHolderFilename)
		maizePlus_animalFood.particle_materialHolderFilename = nil
    end	
    if maizePlus_animalFood.fillPlane_materialHolderFilename ~= nil then
		delete(maizePlus_animalFood.fillPlane_materialHolderFilename)
		maizePlus_animalFood.fillPlane_materialHolderFilename = nil
	end	   
end

init()
