-- by "Marhu" 
-- v 2.0
-- Date: 16.03.2013
-- "Map WaterMod"

WaterMod = {};
WaterMod.Triggers = {}
WaterMod.Animals = {}
WaterMod.Needs = {["cow"]={[16]=60},["sheep"]={[16]=10},["chicken"]={[16]=1,[1]=0.5}}

if AnimalHusbandry.load ~= nil then
	local orgload = AnimalHusbandry.load
	AnimalHusbandry.load = function(a, b, c, d, e, f)
		local ra = orgload(a, b, c, d, e, f)
		
		for i = 1 ,table.getn(a.tipTriggers) do
			if WaterMod.Animals[a.typeName] == nil then  WaterMod.Animals[a.typeName] = {} end;
			
			for FillType,v in pairs(a.tipTriggers[i].acceptedFillTypes) do
				
				if WaterMod.Needs[a.typeName][FillType] then
					if a.tipTriggersFillLevels then
						if a.tipTriggersFillLevels[FillType] == nil then a.tipTriggersFillLevels[FillType] = {} end;
						local haveTrigger = false
						
						for j = 1 ,table.getn(a.tipTriggersFillLevels[FillType]) do
							if a.tipTriggersFillLevels[FillType][j].tipTrigger == a.tipTriggers[i] then
								haveTrigger = true
							end
						end
						if haveTrigger == false then
							table.insert(a.tipTriggersFillLevels[FillType],{tipTriggerIndex = i,tipTrigger = a.tipTriggers[i],fillLevel = 0});
						end;
						WaterMod.Animals[a.typeName][FillType] = true
					else
						Print("WaterMod Needs Patch 1.4")
					end;
				end;
				
			end;
		end;
		
		return ra
	end;
end;

local WaterMod_mt = Class(WaterMod);

function WaterMod.onCreate(id)
	g_currentMission:addUpdateable(WaterMod:new(id));
	
	if not WaterMod.HookAnimalHusbandry then
		WaterMod.HookAnimalHusbandry = true
	
		if AnimalHusbandry.getHasSpaceForTipping ~= nil then
			local orggetHasSpaceForTipping = AnimalHusbandry.getHasSpaceForTipping
			AnimalHusbandry.getHasSpaceForTipping = function(a, b, c, d, e, f)
				local ra, rb, rc, rd = orggetHasSpaceForTipping(a, b, c, d, e, f)
				
				if WaterMod.Animals[a.typeName] and WaterMod.Animals[a.typeName][b] then
					ra = false
					local FillLevel = 0
					for i = 1 ,table.getn(a.tipTriggersFillLevels[b]) do
						FillLevel = FillLevel + a.tipTriggersFillLevels[b][i].fillLevel
					end;
					if a.totalNumAnimals * ((WaterMod.Needs[a.typeName][b] or 0)*6) >= FillLevel then
						ra = true
					end;
				end;
				return ra
			end;
		end;	

		if AnimalHusbandry.updateTrailerTipping ~= nil then
			local orgupdateTrailerTipping = AnimalHusbandry.updateTrailerTipping
			AnimalHusbandry.updateTrailerTipping = function(a, b, c, d, e, f)
				local ra, rb, rc, rd = orgupdateTrailerTipping(a, b, c, d, e, f)
				if WaterMod.Triggers[e.rootNode] and not a.useCowFeeding then
					for i = 1 ,table.getn(e.animalHusbandry.tipTriggersFillLevels[d]) do
						local trigger = e.animalHusbandry.tipTriggersFillLevels[d][i]
						if trigger.tipTrigger == e then
							trigger.fillLevel = trigger.fillLevel - c
						end;
					end;
				end;
				return ra
			end;
		end;
			
		if AnimalHusbandry.minuteChanged ~= nil then
			local orgminuteChanged = AnimalHusbandry.minuteChanged
			AnimalHusbandry.minuteChanged = function(a, b, c, d, e, f)
				if a.typeName == "chicken" and a.updateMinutes == a.updateMinutesInterval then
					for FillType,Triggers in pairs(a.tipTriggersFillLevels) do
						if WaterMod.Needs[a.typeName][FillType] then
							local bedarf = a.totalNumAnimals * ((WaterMod.Needs[a.typeName][FillType] or 0)/1440*a.updateMinutesInterval) -- eine Kuh 60 l/tag
							if bedarf > 0 then
								for i = 1 ,table.getn(Triggers) do
									local index = Triggers[i].tipTriggerIndex
									if WaterMod.Triggers[a.tipTriggers[index].rootNode] then
										local delta = math.min(Triggers[i].fillLevel,  bedarf)
										bedarf = math.max(0, bedarf - delta)
									end
								end;
								if bedarf == 0 then --nur wenn bedarf gedeckt
									a.numPickupObjectsToSpawn = a.numPickupObjectsToSpawn + ((a.totalNumAnimals - 1) * (0.069445/2000) * a.updateMinutesInterval) --(a.totalNumAnimals - 1) = abzug Hahn
								end;
							end;
						end;
					end;
				end;
				
				local ra, rb, rc, rd = orgminuteChanged(a, b, c, d, e, f)
				
				if a.updateMinutes == 0 then
					for FillType,Triggers in pairs(a.tipTriggersFillLevels) do
						if WaterMod.Needs[a.typeName][FillType] then
							local bedarf = a.totalNumAnimals * ((WaterMod.Needs[a.typeName][FillType] or 0)/1440*a.updateMinutesInterval) -- eine Kuh 60 l/tag
							if bedarf > 0 then
								for i = 1 ,table.getn(Triggers) do
									local index = Triggers[i].tipTriggerIndex
									if WaterMod.Triggers[a.tipTriggers[index].rootNode] then
										local delta = math.min(Triggers[i].fillLevel,  bedarf)
										Triggers[i].fillLevel = math.max(0, Triggers[i].fillLevel - delta)
										bedarf = math.max(0, bedarf - delta)
									end;
								end;
								if bedarf == 0 then --nur wenn bedarf gedeckt
									if a.typeName == "cow" then
										a.productivity = a.productivity + .1
										a.fillLevelMilk = a.fillLevelMilk + (a.totalNumAnimals * 0.04956 * a.updateMinutesInterval)
									elseif a.typeName == "sheep" then
										a.productivity = a.productivity + .1
										if a.currentPallet then 
											local newFillLvl = a.currentPallet.fillLevel + (a.totalNumAnimals * 0.001667 * a.updateMinutesInterval)
											a.currentPallet:setFillLevel(newFillLvl)
										end;
									elseif a.typeName == "chicken" then
										a.productivity = a.productivity + .05
									end;
								end;
							end;
						end;
					end;
				end;
			end;
			
		end;

		if AnimalHusbandry.writeStream ~= nil then
			local orgwriteStream = AnimalHusbandry.writeStream
			AnimalHusbandry.writeStream = function(a, b, c, d, e, f)
				orgwriteStream(a, b, c, d, e, f)
				for FillType,Triggers in pairs(a.tipTriggersFillLevels) do
					if WaterMod.Needs[a.typeName][FillType] then
						for i = 1 ,table.getn(Triggers) do
							streamWriteFloat32(b,Triggers[i].fillLevel)
						end;
					end;
				end;
				if a.typeName == "chicken" then
					streamWriteFloat32(b,a.productivity)
				end;
			end;
		end;
			
		if AnimalHusbandry.readStream ~= nil then
			local orgreadStream = AnimalHusbandry.readStream
			AnimalHusbandry.readStream = function(a, b, c, d, e, f)
				orgreadStream(a, b, c, d, e, f)
				for FillType,Triggers in pairs(a.tipTriggersFillLevels) do
					if WaterMod.Needs[a.typeName][FillType] then
						for i = 1 ,table.getn(Triggers) do
							Triggers[i].fillLevel = streamReadFloat32(b)
						end;
					end;
				end;
				if a.typeName == "chicken" then
					a.productivity = streamReadFloat32(b)
				end;
			end;
		end;

		if AnimalHusbandry.writeUpdateStream ~= nil then
			local orgwriteUpdateStream = AnimalHusbandry.writeUpdateStream
			AnimalHusbandry.writeUpdateStream = function(a, b, c, d, e, f)
				orgwriteUpdateStream(a, b, c, d, e, f)
				for FillType,Triggers in pairs(a.tipTriggersFillLevels) do
					if WaterMod.Needs[a.typeName][FillType] then
						for i = 1 ,table.getn(Triggers) do
							streamWriteFloat32(b,Triggers[i].fillLevel)
						end;
					end;
				end;
				if a.typeName == "chicken" then
					streamWriteFloat32(b,a.productivity)
				end;
			end;
		end;
			
		if AnimalHusbandry.readUpdateStream ~= nil then
			local orgreadUpdateStream = AnimalHusbandry.readUpdateStream
			AnimalHusbandry.readUpdateStream = function(a, b, c, d, e, f)
				orgreadUpdateStream(a, b, c, d, e, f)
				for FillType,Triggers in pairs(a.tipTriggersFillLevels) do
					if WaterMod.Needs[a.typeName][FillType] then
						for i = 1 ,table.getn(Triggers) do
							Triggers[i].fillLevel = streamReadFloat32(b)
						end;
					end;
				end;
				if a.typeName == "chicken" then
					a.productivity = streamReadFloat32(b)
				end;
			end;
		end;

	end
end;

function WaterMod:new(id, customMt)
  
	local instance = {};
	if customMt ~= nil then
		setmetatable(instance, customMt);
	else
		setmetatable(instance, WaterMod_mt);
	end;
	
	instance.id = id
	WaterMod.Triggers[id] = instance
	   
    return instance;
end;
 
function WaterMod:load()
end;

function WaterMod:delete()
	WaterMod.HookPDA = nil
end;
  
function WaterMod:update(dt)

	if not WaterMod.HookPDA then
		WaterMod.HookPDA = true
		for i = 1 ,table.getn(g_currentMission.missionPDA.statsPages) do
			local param = g_currentMission.missionPDA.statsPages[i].param
			if param and (param == "cow" or param == "sheep" or param == "chicken") then
				local orgstatsPages = g_currentMission.missionPDA.statsPages[i].func
				g_currentMission.missionPDA.statsPages[i].func = function(a, b, c, d, e, f)
					local ra, rb, rc, rd = orgstatsPages(a, b, c, d, e, f)
			
					local h = g_currentMission.missionPDA.pdaFontSize;
					local y = g_currentMission.missionPDA.pdaTitleY - (h * 1);
					if a.typeName == "chicken" then
						if WaterMod.Animals[a.typeName] ~= nil then
							y = y -	(g_currentMission.missionPDA.pdaRowSpacing * 3 )		
							local x = g_currentMission.missionPDA.pdaCol1
							local desc = g_i18n:getText("Productivity")
							renderText(x, y, h, string.format("%s",desc));
							x = g_currentMission.missionPDA.pdaCol2;
							renderText(x, y, h, string.format("%d%%",a.productivity * 100));
							y = y - g_currentMission.missionPDA.pdaRowSpacing;
						end;
					elseif a.typeName == "sheep" then
						y = y -	(g_currentMission.missionPDA.pdaRowSpacing * 5 )	
					else
						y = y - (g_currentMission.missionPDA.pdaRowSpacing * 10 )
					end;
					for FillType,Triggers in pairs(a.tipTriggersFillLevels) do
						local FillLevel
						for j = 1 ,table.getn(Triggers) do
							local index = Triggers[j].tipTriggerIndex
							if WaterMod.Triggers[a.tipTriggers[index].rootNode] then
								FillLevel = (FillLevel or 0) + Triggers[j].fillLevel
							end;
						end;
						if FillLevel ~= nil then
							local x = g_currentMission.missionPDA.pdaCol1
							local desc = Fillable.fillTypeIndexToDesc[FillType].nameI18N
							renderText(x, y, h, string.format("%s",desc.." [l]"));
							x = g_currentMission.missionPDA.pdaCol2;
							renderText(x, y, h, string.format("%d",FillLevel));
							y = y - g_currentMission.missionPDA.pdaRowSpacing;
						end;
					end;
				end;
			end;
		end;
	end;
  
end;
   
g_onCreateUtil.addOnCreateFunction("WaterMod", WaterMod.onCreate);
 