-- MixerWagon hud display when on foot or in a vehicle
-- put together by alfalfa6945
-- December 28/2018
-- version 0.1.0.1 

mixerDisplay = {}

function mixerDisplay:loadMap(name)
	if g_currentMission.mixerWagons == nil then
		g_currentMission.mixerWagons = {}
	end
	if not mixerDisplay:isDedicatedServer() then
		local uiScale = g_gameSettings:getValue("uiScale")
		mixerDisplay.mixerWagonFillLevelTextOffsetX, mixerDisplay.mixerWagonFillLevelTextOffsetY = getNormalizedScreenValues(28 * uiScale, 7 * uiScale)
		_, mixerDisplay.mixerWagonHelpHeightPerFruit = getNormalizedScreenValues(0, 22 * uiScale)
		_, mixerDisplay.mixerWagonHelpHeightOffset = getNormalizedScreenValues(0, 10 * uiScale)
		mixerDisplay.width, mixerDisplay.height = getNormalizedScreenValues(7 * uiScale, 12 * uiScale)
		local hudWidth, hudHeight = getNormalizedScreenValues(870*uiScale, 15*uiScale)
		mixerDisplay.posX = hudWidth
		mixerDisplay.posX2 = hudWidth * 1.35
		mixerDisplay.textSize = hudHeight
		mixerDisplay.nameWidthOffset = 0
		mixerDisplay:loadXMLvalue()
	end
end

function mixerDisplay:deleteMap()
end

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

function mixerDisplay:keyEvent(unicode, sym, modifier, isDown)
end

function mixerDisplay:update(dt)
end

function mixerDisplay:draw()
	if mixerDisplay:isDedicatedServer() then
		return
	end
	local mixerWagon = mixerDisplay.getNearestVehicle()
	if mixerWagon and mixerWagon.spec_mixerWagon then
		if mixerWagon.spec_attachable and mixerWagon.spec_attachable.attacherVehicle then
			if mixerWagon.spec_attachable.attacherVehicle:getIsControlled() then
				return
			end
		end
		if mixerWagon.spec_enterable then
			if mixerWagon.spec_enterable.isEntered then
				return
			end
		end
		local numFillTypes = #mixerWagon.spec_mixerWagon.mixerWagonFillTypes
		if numFillTypes > 0 then
			local helpHeight = (numFillTypes + 1) * mixerDisplay.mixerWagonHelpHeightPerFruit + mixerDisplay.mixerWagonHelpHeightOffset
			mixerDisplay:createMixerHud(mixerWagon, helpHeight)
		end
	end
end

function mixerDisplay:loadXMLvalue()
	local path = getUserProfileAppPath()
	local file, xmlFile = path.."modsSettings/mixerDisplayConfig.xml"
	if fileExists(file) then
		xmlFile = loadXMLFile("mixerDisplayXML", file, "mixerDisplay")
	else
		xmlFile = createXMLFile("mixerDisplayXML", file, "mixerDisplay")
		setXMLInt(xmlFile, "mixerDisplay.displayDistance", 20)
		setXMLString(xmlFile, "mixerDisplay.statusBarColorGood", "0.3763 0.6038 0.0782 1")
		setXMLString(xmlFile, "mixerDisplay.statusBarColorBad", "0.8069 0.0097 0.0097 1")
		setXMLString(xmlFile, "mixerDisplay.fillLevelStatusBarColor", "0.991 0.3865 0.01 1")
		setXMLString(xmlFile, "mixerDisplay.iconColor", "0.6307 0.6307 0.6307 1")
		setXMLString(xmlFile, "mixerDisplay.textColor", "0.8 0.8 0.8 0.5")
		setXMLBool(xmlFile, "mixerDisplay.backgroundOverlay.useBackgroundOverlay", true)
		setXMLBool(xmlFile, "mixerDisplay.useFillTypeNames", true)
		saveXMLFile(xmlFile)
	end
	if xmlFile then
		mixerDisplay.distance = getXMLInt(xmlFile, "mixerDisplay.displayDistance")
		mixerDisplay.statusBarColor = ConfigurationUtil.getColorFromString(getXMLString(xmlFile, "mixerDisplay.statusBarColorGood"))
		mixerDisplay.statusBarColor2 = ConfigurationUtil.getColorFromString(getXMLString(xmlFile, "mixerDisplay.statusBarColorBad"))
		mixerDisplay.fillLevelStatusBarColor = ConfigurationUtil.getColorFromString(getXMLString(xmlFile, "mixerDisplay.fillLevelStatusBarColor"))
		mixerDisplay.iconColor = ConfigurationUtil.getColorFromString(getXMLString(xmlFile, "mixerDisplay.iconColor"))
		mixerDisplay.textColor = ConfigurationUtil.getColorFromString(getXMLString(xmlFile, "mixerDisplay.textColor"))
		mixerDisplay.useBackgroundOverlay = getXMLBool(xmlFile, "mixerDisplay.backgroundOverlay.useBackgroundOverlay")
		mixerDisplay.mixerWagonFillRangeMarkerOverlay = Overlay:new(g_baseUIFilename, 0, 0, mixerDisplay.width, mixerDisplay.height)
		mixerDisplay.mixerWagonFillRangeMarkerOverlay:setAlignment(Overlay.ALIGN_VERTICAL_MIDDLE, Overlay.ALIGN_HORIZONTAL_LEFT)
		mixerDisplay.mixerWagonFillRangeMarkerOverlay:setUVs(getNormalizedUVs({880, 395, 18, 25}))
		mixerDisplay.mixerWagonFillRangeMarkerOverlay:setColor(unpack(mixerDisplay.iconColor))
		mixerDisplay.useBackgroundOverlay = getXMLBool(xmlFile, "mixerDisplay.backgroundOverlay.useBackgroundOverlay")
		mixerDisplay.useFillTypeNames = Utils.getNoNil(getXMLBool(xmlFile, "mixerDisplay.useFillTypeNames"),true)
		if mixerDisplay.useBackgroundOverlay then
			mixerDisplay.hudOverlay = Overlay:new("dataS2/menu/blank.dds", 0, 0, mixerDisplay.width, mixerDisplay.height)
			mixerDisplay.hudFrameElement = HUDFrameElement:new("dataS2/menu/hud/hud_elements_1080p.png", 0, 0, mixerDisplay.width, mixerDisplay.height)
			mixerDisplay.hudFrameElement:setColor(unpack(HUD.COLOR.FRAME_BACKGROUND))
		end
		delete(xmlFile)
	end
end

function mixerDisplay.getNearestVehicle()
	for _, vehicle in pairs(g_currentMission.vehicles) do
		if vehicle.spec_mixerWagon then
			local distanceToVehicle = calcDistanceFrom(vehicle.rootNode, getCamera())
			if distanceToVehicle < mixerDisplay.distance then
				local insertVehicle = true
				for _, rootNode in pairs(g_currentMission.mixerWagons) do
					if vehicle.rootNode == rootNode then
						insertVehicle = false
					end
				end
				if insertVehicle then
					mixerDisplay.setFillTypeOverlays(vehicle)
					table.insert(g_currentMission.mixerWagons, vehicle.rootNode)
				end
				return vehicle
			end
		end
	end
	return
end

function mixerDisplay.setFillTypeOverlays(mixerWagon)
	local uiScale = g_gameSettings:getValue("uiScale")
	local width, height = getNormalizedScreenValues(20 * uiScale, 20 * uiScale)
	if mixerWagon.fillTypeOverlays == nil then
		mixerWagon.fillTypeOverlays = {}
	end
	if mixerWagon.nameOffset == nil then
		mixerWagon.nameOffset = {}
	end
	if mixerWagon.spec_mixerWagon ~= nil and mixerWagon.spec_fillUnit ~= nil then
		local primaryFillType
		if mixerWagon.spec_mixerWagon.mixedFillType ~= nil then
			primaryFillType = g_fillTypeManager.fillTypes[mixerWagon.spec_mixerWagon.mixedFillType]
		else
			primaryFillType = g_fillTypeManager.fillTypes[FillType.FORAGE]
		end
		local forageFillType = g_fillTypeManager.fillTypes[FillType.FORAGE_MIXING]
		local tempTable = {}
		for _, fillType in pairs(mixerWagon.spec_mixerWagon.mixerWagonFillTypes) do
			table.insert(tempTable, fillType)
			if mixerDisplay.useFillTypeNames then
				local typeDesc = g_fillTypeManager:getFillTypeByName(fillType.name)
				table.insert(mixerWagon.nameOffset, string.len(typeDesc.title))
			end
		end
		for _, fillType in pairs({primaryFillType, forageFillType}) do
			table.insert(tempTable, fillType)
		end
		for _, mixerWagonFillType in ipairs(tempTable) do
			if mixerWagonFillType.name == "dryGrass" then
				mixerWagonFillType.name = "dryGrass_windrow"
			end
			local fillTypeDesc = g_fillTypeManager:getFillTypeByName(mixerWagonFillType.name)
			local entry = {}
			if fillTypeDesc ~= nil then
				entry.title = fillTypeDesc.title
				entry.name = fillTypeDesc.name
				entry.index = fillTypeDesc.index
				entry.overlay = Overlay:new(fillTypeDesc.hudOverlayFilenameSmall, 0, 0, width, height)
				entry.hudListElement = HUDElement:new(entry.overlay)
				entry.overlay:setColor(unpack(mixerDisplay.iconColor))
			end
			if entry.overlay ~= nil then
				local width, height = getNormalizedScreenValues(208 * uiScale, 8 * uiScale)
				if mixerWagon.spec_mixerWagon.fillTypeToMixerWagonFillType[entry.index] ~= nil then
					entry.statusBarColor = mixerDisplay.statusBarColor
					entry.statusBarColor2 = mixerDisplay.statusBarColor2
					entry.fillLevelStatusBarColor = mixerDisplay.fillLevelStatusBarColor
					entry.statusBar = StatusBar:new(g_baseUIFilename, g_colorBgUVs, nil, mixerDisplay.textColor, entry.statusBarColor2, nil, 0, 0, width, height)
				else
					entry.fillLevelStatusBarColor = mixerDisplay.fillLevelStatusBarColor
					entry.statusBar = StatusBar:new(g_baseUIFilename, g_colorBgUVs, nil, mixerDisplay.textColor, entry.fillLevelStatusBarColor, nil, 0, 0, width, height)
				end
			end
			table.insert(mixerWagon.fillTypeOverlays, entry)
		end
	end
	if mixerDisplay.useFillTypeNames then
		table.sort(mixerWagon.nameOffset)
		mixerWagon.nameWidthOffset, _ = getNormalizedScreenValues((mixerWagon.nameOffset[#mixerWagon.nameOffset] * mixerWagon.nameOffset[#mixerWagon.nameOffset]) * (1.25 * uiScale), uiScale)
	else
		mixerWagon.nameWidthOffset = mixerDisplay.nameWidthOffset
	end
end

function mixerDisplay:createMixerHud(mixerWagon, posY)
	local fillLevelPosY = posY
	setTextColor(unpack(mixerDisplay.textColor))
    posY = posY - mixerDisplay.mixerWagonHelpHeightPerFruit
    setTextBold(true)
	renderText(mixerDisplay.posX, posY + (mixerDisplay.mixerWagonHelpHeightPerFruit - mixerDisplay.textSize) * 0.5, mixerDisplay.textSize, g_i18n:getText("info_mixingRatio"))
    setTextBold(false)
    local totalFillLevel = 0
	if mixerWagon:getFillUnitFillLevel(mixerWagon.spec_mixerWagon.fillUnitIndex) > 0 then
		for _, mixerWagonFillType in pairs(mixerWagon.spec_mixerWagon.mixerWagonFillTypes) do
			if mixerWagonFillType.fillLevel ~= nil then
				totalFillLevel = totalFillLevel + mixerWagonFillType.fillLevel
			end
        end
    end
	if mixerDisplay.useBackgroundOverlay then
		mixerDisplay.hudFrameElement:setPosition(mixerDisplay.posX * 0.995, posY - (#mixerWagon.spec_mixerWagon.mixerWagonFillTypes * mixerDisplay.mixerWagonHelpHeightPerFruit) - (mixerDisplay.mixerWagonFillLevelTextOffsetY / 2))
		if totalFillLevel > 0 then
			mixerDisplay.hudFrameElement:setDimension(mixerDisplay.posX / 2.8 + mixerWagon.nameWidthOffset, (#mixerWagon.spec_mixerWagon.mixerWagonFillTypes + 2) * mixerDisplay.mixerWagonHelpHeightPerFruit + (mixerDisplay.mixerWagonFillLevelTextOffsetY / 2))
		else
			mixerDisplay.hudFrameElement:setDimension(mixerDisplay.posX / 2.8 + mixerWagon.nameWidthOffset, (#mixerWagon.spec_mixerWagon.mixerWagonFillTypes + 1) * mixerDisplay.mixerWagonHelpHeightPerFruit + (mixerDisplay.mixerWagonFillLevelTextOffsetY / 2))
		end
		mixerDisplay.hudFrameElement:draw()
	end
	local mixerWagonFillType = mixerWagon.spec_mixerWagon.fillTypeToMixerWagonFillType
	for _, fillType in pairs(mixerWagon.fillTypeOverlays) do
		if mixerWagonFillType[fillType.index] ~= nil then
			posY = posY - mixerDisplay.mixerWagonHelpHeightPerFruit
			local percentage = 0
			if mixerWagon:getFillUnitFillLevel(mixerWagon.spec_mixerWagon.fillUnitIndex) > 0 then
				percentage = mixerWagonFillType[fillType.index].fillLevel / totalFillLevel
			end
			if mixerWagonFillType[fillType.index].fillLevel > 0 then
				if mixerWagon:getFillUnitFillType(mixerWagon.spec_mixerWagon.fillUnitIndex) ~= g_fillTypeManager.nameToFillType["FORAGE_MIXING"].index or (percentage >= mixerWagonFillType[fillType.index].minPercentage and percentage <= mixerWagonFillType[fillType.index].maxPercentage) then
					fillType.statusBar:setColor(unpack(fillType.statusBarColor))
				else
					fillType.statusBar:setColor(unpack(fillType.statusBarColor2))
				end
			end
			fillType.statusBar:setPosition((mixerDisplay.posX2 - fillType.statusBar.width) + mixerWagon.nameWidthOffset, posY + (mixerDisplay.mixerWagonHelpHeightPerFruit - fillType.statusBar.height) * 0.5)
			fillType.statusBar:setValue(percentage)
			fillType.statusBar:render()
			if fillType.overlay ~= nil then
				fillType.overlay:setPosition(mixerDisplay.posX, posY + (mixerDisplay.mixerWagonHelpHeightPerFruit - fillType.overlay.height) * 0.5)
				fillType.overlay:render()
			end
			setTextAlignment(RenderText.ALIGN_LEFT)
			if mixerDisplay.useFillTypeNames then
				renderText(mixerDisplay.posX + mixerDisplay.mixerWagonFillLevelTextOffsetX, posY + mixerDisplay.mixerWagonFillLevelTextOffsetY, mixerDisplay.textSize, fillType.title)
			end
			renderText(mixerDisplay.posX + mixerDisplay.mixerWagonFillLevelTextOffsetX + mixerWagon.nameWidthOffset, posY + mixerDisplay.mixerWagonFillLevelTextOffsetY, mixerDisplay.textSize, string.format("%1.2f%%", percentage * 100))
			local y = fillType.statusBar.y + fillType.statusBar.height * 0.5
			local maxLeft = fillType.statusBar.x + fillType.statusBar.width
			local xLeft =  math.min(fillType.statusBar.x + fillType.statusBar.width * mixerWagonFillType[fillType.index].minPercentage, maxLeft)
			local xRight = math.min(fillType.statusBar.x + fillType.statusBar.width * mixerWagonFillType[fillType.index].maxPercentage, maxLeft)
			mixerDisplay.mixerWagonFillRangeMarkerOverlay:setInvertX(false)
			mixerDisplay.mixerWagonFillRangeMarkerOverlay:setPosition(xLeft, y)
			mixerDisplay.mixerWagonFillRangeMarkerOverlay:render()
			mixerDisplay.mixerWagonFillRangeMarkerOverlay:setInvertX(true)
			mixerDisplay.mixerWagonFillRangeMarkerOverlay:setPosition(xRight - mixerDisplay.mixerWagonFillRangeMarkerOverlay.width, y)
			mixerDisplay.mixerWagonFillRangeMarkerOverlay:render()
		end
		local fillUnit = mixerWagon.spec_fillUnit.fillUnits[mixerWagon.spec_mixerWagon.fillUnitIndex]
		if fillUnit.fillType ~= nil and fillUnit.fillType == fillType.index then
			local fillLevelPercentage = fillUnit.fillLevel / fillUnit.capacity
			if fillUnit.fillLevel > 0 then
				fillType.statusBar:setColor(unpack(fillType.fillLevelStatusBarColor))
			end
			fillType.statusBar:setPosition(mixerDisplay.posX2 - fillType.statusBar.width, fillLevelPosY + (mixerDisplay.mixerWagonHelpHeightPerFruit - fillType.statusBar.height) * 0.5)
			fillType.statusBar:setValue(fillLevelPercentage)
			fillType.statusBar:render()
			if fillType.hudListElement ~= nil then
				fillType.hudListElement:setPosition(mixerDisplay.posX, fillLevelPosY + (mixerDisplay.mixerWagonHelpHeightPerFruit - fillType.overlay.height) * 0.5)
				fillType.hudListElement:draw()
			end
			renderText(mixerDisplay.posX + mixerDisplay.mixerWagonFillLevelTextOffsetX, fillLevelPosY + mixerDisplay.mixerWagonFillLevelTextOffsetY, mixerDisplay.textSize, string.format("%.2f", fillUnit.fillLevel))
		end
	end
end

function mixerDisplay:isDedicatedServer()
	if g_server ~= nil and g_client ~= nil and g_dedicatedServerInfo ~= nil then
		return true
	end
	return
end

addModEventListener(mixerDisplay)