-- by "Marhu" 
-- v 2.1.0
-- Date: 16.07.2013
--"Sort PDA Price and add missing storage"

local TITLE = "PDA Fix";
local FillTypeIsFutter = {
				["grass"] = 7;
				["grass_windrow"] = 12;
				["forage"] = 21;
				["water"] = 16;
				["wheat_windrow"] = 10;
				["dryGrass_windrow"] = 13;
				["silage"] = 20;
				["milk"] = 14;
				["forage_mixing"] = 22;
				["chaff"] = 9;
				["dryGrass"] = 8;
			};

PDAfix = {};
PDAfix.version = 20100;
			
local function Debug(...)
	if PDAfix.db.debug then
		local text = ""
		for i = 1, select("#", ...) do
			if type(select(i, ...)) == "boolean" then
				text = text..(select(i, ...) and "true" or "false").." "
			else
				text = text..(select(i, ...) or "nil").." "
			end
		end
		print(TITLE..": "..text)
	end
end	
			
function PDAfix:loadMap(name)
	
	self.db = {
		name = "PDAfix",
		debug = false,
		Stop = false,
		preview = true,
		ForageStor = false
	};
		
	if (g_currentMission.PDAfix == nil or g_currentMission.PDAfix.version < self.version) then
		g_currentMission.PDAfix = {};
		g_currentMission.PDAfix.version = self.version;
		if g_currentMission.DatenBank then
			g_currentMission.DatenBank.Add(self,self.db);
		end
	else
		self.version = 0;
		return;
	end	
	
	self.optionen = {
		name = "PDA Fix",
		desc = "PDA Fix",
		type = 'group',
		args = {
			hide = {
				name = "hide",
				desc = "hide PDA Fix",
				type = 'toggle',
				get = function() return self.db.Stop end,
				set = function(info, newValue)
					self.db.Stop = newValue
					if self.db.Stop then
						self:ResetStatsPages()
					else
						self:AddStatsPages()
					end
				end
			},
			debuging = {
				name = "Debug",
				desc = "Print Debug info in Log",
				type = 'toggle',
				get = function() return self.db.debug end,
				set = function(info, newValue)
					self.db.debug = newValue
				end
			},
			preview = {
				name = "preview",
				desc = "great Demands preview",
				type = 'toggle',
				get = function() return self.db.preview end,
				set = function(info, newValue)
					self.db.preview = newValue
				end
			},
			ForageStor = {
				name = "ForageStorage",
				desc = "show PDAExtensionForageStorage",
				type = 'toggle',
				get = function() return self.db.ForageStor end,
				set = function(info, newValue)
					self.db.ForageStor = newValue
					self:ResetStatsPages()
					self:AddStatsPages()
				end
			}
		}
	};	
	
	
	self.MaxFTPP = 10; -- Max FillType per Page
	self.MaxSPP = 2; -- Max Station per Page
	self.MaxSilosPP = 10; -- Max Silos per Page
	self.StationOffset = 0;
	self.FillTypeOffset = 0;
	self.NumFillTypes = 0;
	self.NumSilos = 0;
	self.FillTypes = {};
	self.Station = {};
	self.Silo = {};
	
	local Station = {};
	local Feldfrucht = {};
	local Futter = {};
	local Sonstige = {};
	local findFillTypes = {};
	local findSilo = {};
	
    for k,tip in pairs(g_currentMission.tipTriggers) do
		
		if (tip.appearsOnPDA) then
			local name = tip.stationName;
			if (g_i18n:hasText(tip.stationName)) then name = g_i18n:getText(tip.stationName); end;
			if not Station[name] then
				Station[name] = {};
				Station[name].tip = tip;
				Station[name].priceMultipliers = {};
			end
			for index in pairs(tip.acceptedFillTypes) do
				Station[name].priceMultipliers[index] = tip.priceMultipliers[index];
				Debug("priceM",index,Station[name].priceMultipliers[index],tip.priceMultipliers[index]);
			end;
		end;
		
		for i in pairs(tip.acceptedFillTypes) do
			if i == Fillable.FILLTYPE_BARLEY_WINDROW then i = Fillable.FILLTYPE_WHEAT_WINDROW end
			if (tip.appearsOnPDA) then
				if not findFillTypes[i] then
					findFillTypes[i] = true;
					self.NumFillTypes = self.NumFillTypes + 1;
					if FillTypeIsFutter[Fillable.fillTypeIntToName[i]] then
						Futter[i] = (Futter[i] or 0) + 1;
					elseif FruitUtil.fruitIndexToDesc[FruitUtil.fillTypeToFruitType[i]] then
						Feldfrucht[i] = (Feldfrucht[i] or 0) + 1;
					else
						Sonstige[i] = (Sonstige[i] or 0) + 1;
					end;
				end;
			end;
			
			if tip.isFarmTrigger and tip.animalHusbandry == nil then
				if not findSilo[i] then
					findSilo[i] = true;
					self.NumSilos = self.NumSilos + 1;
					if FillTypeIsFutter[Fillable.fillTypeIntToName[i]] then
						Futter[i] = (Futter[i] or 0) + 2;
					elseif FruitUtil.fruitIndexToDesc[FruitUtil.fillTypeToFruitType[i]] then
						Feldfrucht[i] = (Feldfrucht[i] or 0) + 2;
					else
						Sonstige[i] = (Sonstige[i] or 0) + 2;
					end;
				end;
			end;
		end;
		
	end;
	
	for k,v in pairs(Feldfrucht) do
		if v == 1 or v == 3 then
			table.insert(self.FillTypes,k);
		end;
		if v == 2 or v == 3 then
			table.insert(self.Silo,k);
		end;
	end;
	for k,v in pairs(Futter) do
		if v == 1 or v == 3 then
			table.insert(self.FillTypes,k);
		end;
		if v == 2 or v == 3 then
			table.insert(self.Silo,k);
		end;
	end;
	for k,v in pairs(Sonstige) do
		if v == 1 or v == 3 then
			table.insert(self.FillTypes,k);
		end;
		if v == 2 or v == 3 then
			table.insert(self.Silo,k);
		end;
	end;
		
	for SName, v in pairs(Station) do
		local t = {};
		t.stationName = SName;
		t.stationRawName = SName;
		t.tipTrigger = v.tip;
		t.priceMultipliers = v.priceMultipliers;
		table.insert(self.Station,t);
	end;
	
	self.Seite = 1;
	self.NumSeiten = (math.ceil(table.getn(self.Station) / self.MaxSPP)  *  math.ceil(self.NumFillTypes / self.MaxFTPP)) + 1;
	
	
end;

function PDAfix:deleteMap()
	self.hookPDA = nil;
	self.OrgStatsPages = nil;
	self.menueaddet = nil;
	self.OldVersChecked = nil;
	self.FillTypes = {}; 
	self.Silo = {};
end;

function PDAfix:mouseEvent(posX, posY, isDown, isUp, button)
end;

function PDAfix:keyEvent(unicode, sym, modifier, isDown)
end;

local function TimeDiff(d1,h1,d2,h2)
	local t1 = ((d1 * 24) + h1) - ((d2 * 24) + h2);
	local d3 = math.floor(t1/24);
	local h3 = math.mod(math.floor(t1), 24);
	if d3 > 0 then
		return tostring(d3).."d "..tostring(h3).."h";
	else
		return tostring(h3).."h";
	end;
end;

function PDAfix:update(dt)
	
	if g_currentMission.PDAfix == nil or g_currentMission.PDAfix.version > self.version then return end;
	
	if not self.menueaddet then
		self.menueaddet = true;
		if g_currentMission.ModMenue then
			g_currentMission.ModMenue:Add(self.optionen);
		end;
	end;
	
	if not self.hookPDA and not self.db.Stop then
		self.hookPDA = true;
		if MissionPDA.draw ~= nil then
			local orgdraw = MissionPDA.draw;
			MissionPDA.draw = function(a, b, c, d)
				
				if (a.screen ~= 4) or self.db.Stop then
					orgdraw(a, b, c, d);
				else
					-- PDA Hintergrund
					a.hudPDABackgroundOverlay:render();
					
					local y = a.pdaHeadRow;
						
					if self.GreatDemandSeite then	-- Seite Große Nachfrage
						
						setTextAlignment(RenderText.ALIGN_LEFT);
						setTextBold(true);
						renderText(a.pdaPricesCol[1],y,a.pdaFontSize,g_i18n:getText("PDATitleGreatDemands"));
						y = y - (a.pdaRowSpacing * 2);
						setTextBold(false);
						local greatDemands = g_currentMission.economyManager.greatDemands;
						local find = false;
						for i=1,table.getn(greatDemands) do
							if greatDemands[i].isRunning then -- Große Nachfrage
								find = true;
								local name = greatDemands[i].stationName;
								if g_i18n:hasText(name) then name = g_i18n:getText(name); end;
								renderText(a.pdaPricesCol[1],y,a.pdaFontSize,name);
								local t = Fillable.fillTypeIndexToDesc[greatDemands[i].fillTypeIndex].nameI18N;
								t = t..string.format(" x%.1f",greatDemands[i].demandMultiplier);
								renderText(a.pdaPricesCol[2],y,a.pdaFontSize,t);
								renderText(a.pdaPricesCol[3],y,a.pdaFontSize,
									string.format(g_i18n:getText("PDAGreatDemandTimeRemaining"),greatDemands[i].demandDuration));
								y = y - a.pdaRowSpacing;
							end;
						end;
						if not find then -- Keine große Nachfrage
							renderText(a.pdaPricesCol[1],y,a.pdaFontSize,g_i18n:getText("PDANoGreatDemands"));
							y = y - a.pdaRowSpacing;
						end;
						y = y - a.pdaRowSpacing;
						
						-- Vorschau nächste große Nachfragen --
						if self.db.preview then
							local currentDay  = g_currentMission.environment.currentDay;
							local currentHour  = g_currentMission.environment.currentHour;
							for i=1,table.getn(greatDemands) do
								if not greatDemands[i].isRunning then
									local name = greatDemands[i].stationName;
									if g_i18n:hasText(name) then name = g_i18n:getText(name); end;
									renderText(a.pdaPricesCol[1],y,a.pdaFontSize,name);
									local t = Fillable.fillTypeIndexToDesc[greatDemands[i].fillTypeIndex].nameI18N;
									local InTime = TimeDiff(greatDemands[i].demandStart.day, greatDemands[i].demandStart.hour, currentDay, currentHour);
									t = t..string.format(" Start in: %s", InTime);
									renderText(a.pdaPricesCol[2],y,a.pdaFontSize,t);
									y = y - a.pdaRowSpacing;
								end;
							end;
						end;
					else	
						--- Preise der Stationen ---
						
						table.sort(self.Station, MissionPDA.tipTriggerSorter);
						
						setTextAlignment(RenderText.ALIGN_CENTER);
						
						local priceMultipliers = {};
						setTextBold(true);
						local Col=2;
						local j = 1;
						for i = 1 + self.StationOffset, self.MaxSPP+self.StationOffset do
							if self.Station[i] then
								priceMultipliers[j] = self.Station[i].priceMultipliers; 
								local x = a.pdaPricesCol[Col] + ((a.pdaPricesCol[Col+1] - a.pdaPricesCol[Col])/2) -  getTextWidth(a.pdaFontSize ,"00");
								renderText(x,y,a.pdaFontSize,self.Station[i].stationRawName); -- render Stations Namen
								Col = Col + 1;
								j = j + 1;
							end;
						end;
										
						y = y - a.pdaRowSpacing;
						setTextBold(false);
						local pricePerTon = g_i18n:getText("PricePerTon");
						
						setTextAlignment(RenderText.ALIGN_LEFT);
						
						local PriceArrow = 1;
						
						for i = 1, table.getn(self.FillTypes) do
							if i > self.FillTypeOffset + self.MaxFTPP then 
								break;
							elseif i > self.FillTypeOffset then
								local Index = self.FillTypes[i];
						
								local name = Fillable.fillTypeIndexToDesc[Index].nameI18N;
								if Fillable.FILLTYPE_PIG == nil or Index ~= Fillable.FILLTYPE_PIG then
									name = name.." "..pricePerTon;
								end;
																
								local difficultyMultiplier = math.max(2 * (3 - g_currentMission.missionStats.difficulty), 1); -- 1  2  4
								local price = Fillable.fillTypeIndexToDesc[Index].pricePerLiter * difficultyMultiplier;
								setTextAlignment(RenderText.ALIGN_LEFT);
								renderText(a.pdaPricesCol[1],y,a.pdaFontSize,name); -- render FillType Name
								Col = 2;
								setTextAlignment(RenderText.ALIGN_RIGHT);
								
								for j = 1 ,table.getn(priceMultipliers) do
									if priceMultipliers[j][Index] then
										local x = a.pdaPricesCol[Col] + ((a.pdaPricesCol[Col+1] - a.pdaPricesCol[Col])/2);
										local price2 = price * priceMultipliers[j][Index];
										local greatDemands = g_currentMission.economyManager.greatDemands;
										for k = 1, table.getn(greatDemands) do
											if greatDemands[k].isRunning then -- greatDemands
												if greatDemands[k].fillTypeIndex == Index and 
												   greatDemands[k].stationName == self.Station[j+self.StationOffset].tipTrigger.stationName then
													setTextColor(0.2, 1, 0.2, 1);
													price2 = price2 * greatDemands[k].demandMultiplier;
												end;
											end;
										end;
										if Fillable.FILLTYPE_PIG and Index == Fillable.FILLTYPE_PIG then
											price2 = math.ceil(price2);
										else
											price2 = math.ceil(price2 * 1000);
										end;
										renderText(x,y,a.pdaFontSize,string.format("%d", price2)); -- render Preis pro Station
										setTextColor(1, 1, 1, 1);
									end;
									Col = Col + 1;
								end;
								
								-- Trend Pfeile
								if (Fillable.fillTypeIndexToDesc[Index].pricePerLiter < Fillable.fillTypeIndexToDesc[Index].previousHourPrice) then
									a.pdaPriceArrows[PriceArrow]:setImage(a.priceArrowDown);
								elseif (Fillable.fillTypeIndexToDesc[Index].pricePerLiter > Fillable.fillTypeIndexToDesc[Index].previousHourPrice) then
									a.pdaPriceArrows[PriceArrow]:setImage(a.priceArrowUp);
								else
									a.pdaPriceArrows[PriceArrow]:setImage(a.priceArrowFlat);
								end;
								a.pdaPriceArrows[PriceArrow].x = a.pdaPricesCol[4];
								a.pdaPriceArrows[PriceArrow]:render();
								PriceArrow = PriceArrow + 1;
								
								y = y - a.pdaRowSpacing;
							end;

						end;
					end;
					
					-- Seiten Zahl
					setTextAlignment(RenderText.ALIGN_RIGHT);
					renderText(a.pdaCoordsXPos + 0.004, a.pdaCoordsYPos - 0.002,a.pdaFontSize - 0.002,
						string.format("%d/%d", self.Seite, self.NumSeiten));
					setTextAlignment(RenderText.ALIGN_LEFT);
					
					-- Ramen
					a.hudPDAFrameOverlay:render();

					-- Titel
					setTextBold(true);
					setTextColor(0,0,0, 1);
					renderText(a.pdaTitleX - 0.001,a.pdaTitleY - 0.002,a.pdaTitleTextSize,a.textTitles[4]);
					setTextColor(1,1,1, 1);
					renderText(a.pdaTitleX,a.pdaTitleY,a.pdaTitleTextSize,a.textTitles[4]);
					
					-- Hilfe Text
					g_currentMission:addHelpButtonText(g_i18n:getText("PDAShowNextScreen"), InputBinding.TOGGLE_PDA);
					g_currentMission:addHelpButtonText(g_i18n:getText("PDAShowNextStations"), InputBinding.TOGGLE_PDA_ZOOM);
					
					--Seiten Blättern
					if InputBinding.hasEvent(InputBinding.TOGGLE_PDA_ZOOM) then
						if self.GreatDemandSeite then
							self.GreatDemandSeite = nil;
							self.Seite = 1;
						else
							self.StationOffset = self.StationOffset + self.MaxSPP;
							self.Seite = self.Seite + 1;
							if self.StationOffset >= table.getn(self.Station) then
								self.StationOffset = 0;
								self.FillTypeOffset = self.FillTypeOffset + self.MaxFTPP;
								if self.FillTypeOffset >= self.NumFillTypes then
									self.FillTypeOffset = 0;
									self.GreatDemandSeite = true;
								end;
							end;
						end;

						playSample(a.pdaBeepSound, 1, 0.5, 0);
					end;
				end;
			end;
		end;
		
		self:AddStatsPages()
		
	end;
	
	self.tick = (self.tick or 0) + dt;
	if self.tick >= 2000 then
		self:updateTick(self.tick);
	end;
end;

function PDAfix:updateTick(dt)
	self.tick = self.tick - 2000;
	
	if not self.OldVersChecked and not self.db.Stop then
		self.OldVersChecked = true;
		Debug("Check old Version Overwrite");
		local findOldVersion = false;
		local Pages = g_currentMission.missionPDA.statsPages;
		for i = 1, table.getn(Pages) do
			if Pages[i].param and string.find(Pages[i].param, "Silo") and not string.find(Pages[i].param, "SiloPages") then
				Debug("Find old Version Overwrite");
				findOldVersion = true;
				break;
			end;
		end;
		if findOldVersion == true then
			for i = table.getn(Pages), 1, -1 do
				if Pages[i].param and string.find(Pages[i].param, "Silo") then
					if not string.find(Pages[i].param, "SiloPages") then
						Pages[i].target.Stop = true;
					end;
					table.remove(g_currentMission.missionPDA.statsPages,i);
				end;
			end;
			MissionPDA.addStatsPage(g_currentMission.missionPDA, g_currentMission.missionPDA.drawStatsPageFarmSilos,g_currentMission.missionPDA,nil,1);
			self.OrgStatsPages = {};
			self.hookPDA = nil;
		end;
	end;
	
end;

function PDAfix:draw()
end;

function PDAfix:AddStatsPages()
	
	if self.hookPDA == true then
		self.OrgStatsPages = {};
		
		local findOldVersion = false;
		
		for i = table.getn(g_currentMission.missionPDA.statsPages), 1, -1 do
			local page = g_currentMission.missionPDA.statsPages[i];
			if not self.db.ForageStor then	
				if page.target and page.target.drawStatsPageAdditionalFarmSilos then
					self.OrgStatsPages[i] = g_currentMission.missionPDA.statsPages[i];
					table.remove(g_currentMission.missionPDA.statsPages,i);
					Debug("PDAExtensionForageStorage removed");
					break;
				end;
			end;
			if page.param and string.find(page.param, "Silo") and not string.find(page.param, "SiloPages") then
				Debug("Find old Version");
				findOldVersion = true;
				page.target.Stop = true;
				table.remove(g_currentMission.missionPDA.statsPages,i);
			end;
		end;
		
		if findOldVersion == true then
			MissionPDA.addStatsPage(g_currentMission.missionPDA, g_currentMission.missionPDA.drawStatsPageFarmSilos,g_currentMission.missionPDA,nil,1);
		end;
				
		self.OrgStatsPages[1] = g_currentMission.missionPDA.statsPages[1];
		table.remove(g_currentMission.missionPDA.statsPages,1);
		Debug("Pages 1 removed");
			
		local SiloPages = math.ceil((self.NumSilos+1) / self.MaxSilosPP);
		for i = 1 ,SiloPages do
			MissionPDA.addStatsPage(g_currentMission.missionPDA, self.DrawFarmSilos,self,"SiloPages"..i,i);
			Debug("add Pages","SiloPages"..i);
		end;
	end;
	
end;

function PDAfix:ResetStatsPages()
	
	if self.OrgStatsPages then
		local SiloPages = math.ceil((self.NumSilos+1) / self.MaxSilosPP);
		for i = SiloPages ,1 , -1 do
			if g_currentMission.missionPDA.statsPages[i].param and g_currentMission.missionPDA.statsPages[i].param == "SiloPages"..i then
				table.remove(g_currentMission.missionPDA.statsPages,i);
				Debug("Pages", "SiloPages"..i ,"removed");
			end;
		end;
		for k, v in pairs(self.OrgStatsPages) do
			table.insert(g_currentMission.missionPDA.statsPages,k,v);
			Debug("Orginal Pages", k ,"insert");
		end;
	end;
	
end;

function PDAfix:DrawFarmSilos(a)
	
	local von, bis, num = string.find(a,"(%d)");
	local off = ((tonumber(num)-1) * self.MaxSilosPP);
	local y = g_currentMission.missionPDA.pdaHeadRow - (g_currentMission.missionPDA.pdaRowSpacing/2);
	setTextColor(1, 1, 1, 1);
	local Gras,Stroh = nil,nil;
	for i = 1, table.getn(self.Silo) do
		if i > off + self.MaxSilosPP then 
			break;
		elseif i > off then
			Index = self.Silo[i];
								
			local name = Fillable.fillTypeIndexToDesc[Index].name.."_storage";
			if g_i18n:hasText(name) then
				name = g_i18n:getText(name);
			elseif g_i18n:hasText("storage") then
				name = Fillable.fillTypeIndexToDesc[Index].nameI18N..g_i18n:getText("storage");
			else
				name = Fillable.fillTypeIndexToDesc[Index].nameI18N;
			end;
			name = name.." ["..g_i18n:getText("fluid_unit_short").."]";
															
			setTextAlignment(RenderText.ALIGN_LEFT);
			renderText(g_currentMission.missionPDA.pdaPricesCol[1],y,g_currentMission.missionPDA.pdaFontSize,name); --FillType Name

			setTextAlignment(RenderText.ALIGN_RIGHT);
			
			local Amount = 0;
			if Index == Fillable.FILLTYPE_WHEAT_WINDROW then
				Amount = g_i18n:getFluid(g_currentMission:getSiloAmount(Index)+g_currentMission:getSiloAmount(Fillable.FILLTYPE_BARLEY_WINDROW));
			else
				Amount = g_i18n:getFluid(g_currentMission:getSiloAmount(Index));
			end;
						
			renderText(g_currentMission.missionPDA.pdaPricesCol[3],y,g_currentMission.missionPDA.pdaFontSize,string.format("%d", Amount)); --Amount
			
			y = y - g_currentMission.missionPDA.pdaRowSpacing;
		end;
	end;
	if tonumber(num) == math.ceil((self.NumSilos+1) / self.MaxSilosPP) then
		setTextAlignment(RenderText.ALIGN_LEFT);
		renderText(g_currentMission.missionPDA.pdaPricesCol[1],y,g_currentMission.missionPDA.pdaFontSize,g_i18n:getText("Eggs_carrying")); --FillType Name
		setTextAlignment(RenderText.ALIGN_RIGHT);
		local Amount = g_currentMission:getSiloAmount(Fillable.fillTypeNameToInt["egg"]);
		renderText(g_currentMission.missionPDA.pdaPricesCol[3],y,g_currentMission.missionPDA.pdaFontSize,string.format("%d", Amount)); --Amount
	end;
	
end;

addModEventListener(PDAfix);