--[[ screenFunctions 

Author: 		Antonis78

Description: 	script for various tractor onboard monitor informations

Version: 		1.0.0.0

Changelog: 		05/03/2020 	- initial release
				
Notes:          Bale count is under development and sometimes maybe skip bales. Works better with square baler
                
]]


screenFunctions = {};

screenFunctions.modDir = g_currentModDirectory;
screenFunctions.currentModName = g_currentModName;

function screenFunctions.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Motorized, specializations) and SpecializationUtil.hasSpecialization(PowerConsumer, specializations); 
end;

function screenFunctions.registerEventListeners(vehicleType)
	for _, spec in pairs({"onLoad", "onUpdate"}) do
		SpecializationUtil.registerEventListener(vehicleType, spec, screenFunctions)
	end
end

function screenFunctions:onLoad(savegame)
    totalBales = 0
    self.rotorRpm = 1030
	self.ptoRpm = 1000
	self.barPress = 2.8
	self.previousBaleCount = 0.0
	 self.previousFillRatio = 0.0
	self.indicatorBarNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.screenFunctions#indicatorBarNode"), self.i3dMappings);
	self.indicatorBarNodeWagon = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.screenFunctions#indicatorBarNodeWagon"), self.i3dMappings);
	self.indicatorBarNodeTipperCap = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.screenFunctions#indicatorBarNodeTipperCap"), self.i3dMappings);
	self.indicatorBarNodeCap = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.screenFunctions#indicatorBarNodeCap"), self.i3dMappings);
	self.ptoVisual = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.screenFunctions.indications#ptoicon"), self.i3dMappings);
	self.overload = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.screenFunctions.indications#overloadicon"), self.i3dMappings); 
	self.lowerArms = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.screenFunctions.indications#armsIcon1"), self.i3dMappings);
	self.raiseArms = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.screenFunctions.indications#armsIcon2"), self.i3dMappings);
	self.lowerPickup = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.screenFunctions.indications#pickupLIcon"), self.i3dMappings);
	self.raisePickup = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.screenFunctions.indications#pickupRIcon"), self.i3dMappings);
	self.lowerPickup2 = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.screenFunctions.indications#pickupL2Icon"), self.i3dMappings);
	self.raisePickup2 = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.screenFunctions.indications#pickupR2Icon"), self.i3dMappings);
	self.showInHud = Utils.getNoNil(getXMLBool(self.xmlFile, "vehicle.screenFunctions#showInHud"), true);
	self.loadLevel = 0.0
	self.loadLevel2 = 0.0
	self.loadWarnSamplePlayed = false
	self.currentVoltage = 24.8
	self.batvolt = VehicleHudUtils.loadHud(self, self.xmlFile, "batteryVolt");
	self.loadprc = VehicleHudUtils.loadHud(self, self.xmlFile, "loadPercent");
	self.slipprc = VehicleHudUtils.loadHud(self, self.xmlFile, "slipPercent");
	self.bales = VehicleHudUtils.loadHud(self, self.xmlFile, "balesCount");
	self.rotor = VehicleHudUtils.loadHud(self, self.xmlFile, "rotorBaler");
	self.pto = VehicleHudUtils.loadHud(self, self.xmlFile, "ptoActive");
	self.pto2 = VehicleHudUtils.loadHud(self, self.xmlFile, "ptoActive2");
	self.pressure = VehicleHudUtils.loadHud(self, self.xmlFile, "press");
	self.capacity = VehicleHudUtils.loadHud(self, self.xmlFile, "loadCapacity");
	self.capacity2 = VehicleHudUtils.loadHud(self, self.xmlFile, "loadCapacity2");
	self.capacity3 = VehicleHudUtils.loadHud(self, self.xmlFile, "loadCapacity3");
	self.tirePress = VehicleHudUtils.loadHud(self, self.xmlFile, "air");
	self.tirePress1 = VehicleHudUtils.loadHud(self, self.xmlFile, "air1");
end;


function screenFunctions:onUpdate(dt)
     local spec = self.spec_tirePressure
	 if self:getIsMotorStarted() then
            if self.tirePress ~= nil then
				if spec.inflationPressure ~= nil then
    				VehicleHudUtils.setHudValue(self, self.tirePress, spec.inflationPressure); 
				end;
			end;
		end; 
    if self:getIsMotorStarted() then
            if self.tirePress1 ~= nil then
				if spec.inflationPressure ~= nil then
    				VehicleHudUtils.setHudValue(self, self.tirePress1, spec.inflationPressure); 
				end;
			end;
		end; 
	local spec = self.spec_motorized
    local loadPercentage = spec.motor:getMotorAppliedTorque() / math.max(spec.motor:getMotorAvailableTorque(), 0.0001)
    spec.actualLoadPercentage = loadPercentage
        if spec.actualLoadPercentage > spec.smoothedLoadPercentage then
            spec.smoothedLoadPercentage = 0.95*spec.smoothedLoadPercentage + 0.05*loadPercentage
        else
            spec.smoothedLoadPercentage = 0.98*spec.smoothedLoadPercentage + 0.02*loadPercentage
        end
		if self:getIsMotorStarted() then
            if self.loadprc ~= nil then
				if spec.smoothedLoadPercentage ~= nil then
    				VehicleHudUtils.setHudValue(self, self.loadprc, spec.smoothedLoadPercentage * 106, 100); 
				end;
			end;
		end; 
		local currentVoltage = self.currentVoltage + (spec.motor:getLastMotorRpm() - spec.motor:getMinRpm()) / (spec.motor:getMaxRpm() - spec.motor:getMinRpm())
		spec.batteryVolt = currentVoltage
	 	if self:getIsMotorStarted() then
            if self.batvolt ~= nil then
				if spec.batteryVolt ~= nil then
    				VehicleHudUtils.setHudValue(self, self.batvolt, spec.batteryVolt, 100); 
				end;
			end;
		end; 
	local UseGUI = true;
	    if g_client and UseGUI then
		-- Check number of vehicles
		numVehicles = table.getn(g_currentMission.vehicles);
		-- If vehicles present run code
		if numVehicles ~= nil then
			-- Run code for vehicles
			if numVehicles >= 1 then
				-- Search for controlled vehicle
				for VehicleIndex=1, numVehicles do
		local vehicle = g_currentMission.vehicles[VehicleIndex];
		if vehicle ~= nil then
		    if vehicle.spec_motorized then
				if vehicle.spec_wheels ~= nil then	
					if vehicle:getIsControlled() then
						if g_currentMission.controlledVehicle == vehicle then
		                   if self:getIsMotorStarted() then
                             if self.slipprc ~= nil then
				               if vehicle.GUISlip ~= nil then
	        					VehicleHudUtils.setHudValue(self, self.slipprc, vehicle.GUISlip , 100); 
			                	end;
			                   end;
		                     end; 				  
					       end;
						end;
					end;
				end;
			end;
        end;
	    end;
	    end;
		end;
	    local fillLevelInformations = {}
        local fillRatio = 0.0							
        setScale(self.indicatorBarNode, 0, 1, 1);
        setScale(self.indicatorBarNodeWagon, 0, 1, 1);
        setScale(self.indicatorBarNodeCap, 0, 1, 8.117);
        setScale(self.indicatorBarNodeTipperCap, 0, 1, 16.47);
        self:getFillLevelInformation(fillLevelInformations)
		self.lastFT = spec.lastValidInputFruitType
        for _,fillLevelInformation in pairs(fillLevelInformations) do
        fillRatio = fillLevelInformation.fillLevel / fillLevelInformation.capacity
            if self.previousFillRatio == 0.0 then
               self.previousFillRatio = fillRatio 
				
		    end
	    local currentLoadLevel = math.min((fillRatio - self.previousFillRatio) * 500)
        self.loadLevel = self.loadLevel + (currentLoadLevel - self.loadLevel) / 30
		local currentLoadLevel2 = math.min((fillRatio - self.previousFillRatio) * 5500)
        self.loadLevel2 = self.loadLevel2 + (currentLoadLevel2 - self.loadLevel2) / 30
           end
			if self.loadLevel ~= nil then
			setScale(self.indicatorBarNode, self.loadLevel, 1, 1);
			setScale(self.indicatorBarNodeWagon, self.loadLevel2, 1, 1);
			end
			if self.loadLevel > 1.8 then
			--setScale(self.indicatorBarNode, 1, 1, 1);
			  setVisibility(self.overload, true);
			else
			--setScale(self.indicatorBarNode, self.loadLevel, 1, 1);
			setVisibility(self.overload, false);
			end
			self.previousFillRatio = fillRatio
			local hudcapacity = 0
			
			for _,fillLevelInformation in pairs(fillLevelInformations) do
			hudCapacity = fillLevelInformation.fillLevel 
			
			    if hudCapacity ~= nil then
				   if self.capacity ~= nil then 
				 VehicleHudUtils.setHudValue(self, self.capacity, hudCapacity , 100);
				 VehicleHudUtils.setHudValue(self, self.capacity2, hudCapacity , 100);
				 VehicleHudUtils.setHudValue(self, self.capacity3, hudCapacity , 100);
				   end
			 else 
			     VehicleHudUtils.setHudValue(self, self.capacity, hudCapacity , 0);
				 VehicleHudUtils.setHudValue(self, self.capacity2, hudCapacity , 0);
				 VehicleHudUtils.setHudValue(self, self.capacity3, hudCapacity , 0);
                end	
	        end
		  
		local animhudcapacity = 0
			
			 for _,fillLevelInformation in pairs(fillLevelInformations) do
			animhudCapacity = (fillLevelInformation.fillLevel / fillLevelInformation.capacity) / 2
			
   			    if animhudCapacity ~= nil then
			     setScale(self.indicatorBarNodeCap, animhudCapacity, 1, 8.117);
			      setScale(self.indicatorBarNodeTipperCap, animhudCapacity, 1, 16.47);
                end	
            end				  
    	local countBales = 0.0 				
		spec.smoothedcountBales = 0
		for _,fillLevelInformation in pairs(fillLevelInformations) do
        countBales = (fillLevelInformation.fillLevel / fillLevelInformation.capacity) 
        spec.countBales = countBales
		spec.countBales = spec.countBales + (countBales - spec.countBales) / 1.2
		--if self:getLastSpeed() > 1 then
		 --if spec.countBales > spec.smoothedcountBales then
           -- spec.smoothedcountBales = 0.95*spec.smoothedcountBales + 0.05*countBales
        --else
            --spec.smoothedcountBales = 0.98*spec.smoothedcountBales + 0.02*countBales
        --end
		 
	    	if spec.countBales < 1 and spec.countBales > 0.99496 then
		       self.addBales = 0.25
		       self.previousBaleCount = (self.previousBaleCount + self.addBales)
      
		local totalBales = self.previousBaleCount
		    if self.bales ~= nil then
	    		if totalBales ~= nil then
		        VehicleHudUtils.setHudValue(self, self.bales, totalBales , 100);
		        end;
		      end;
		    end;
		end;
		local spec = self.spec_powerConsumer
		
		setVisibility(self.ptoVisual, false);
		setVisibility(self.lowerArms, false);
		setVisibility(self.raiseArms, false);
		setVisibility(self.lowerPickup, false);
		setVisibility(self.raisePickup, false);
		setVisibility(self.lowerPickup2, false);
		setVisibility(self.raisePickup2, false);
       
		if self.getAttachedImplements ~= nil then
        for _, implement in pairs(self:getAttachedImplements()) do
		local object = implement.object
		spec.rpmr = 1.5 / 100
        spec.ptoFactor = 3	
		spec.rotorFactor = 3
		spec.pressFactor = 7
	    	if object:getDoConsumePtoPower() ~= nil then
        local delta = spec.rpmr * dt
            if object:getDoConsumePtoPower() then 
		       setVisibility(self.ptoVisual, true);
   		    if self.rotorRpm < 1730 then
               self.rotorRpm = self.rotorRpm + dt / spec.rotorFactor + delta
            end
        else
            if self.rotorRpm > 0.1 then
               self.rotorRpm = self.rotorRpm - dt / spec.rotorFactor + delta
            end
     	      end
		      VehicleHudUtils.setHudValue(self, self.rotor, self.rotorRpm, 100);
	        if object:getIsSelected() then
	           if not (object.getIsLowered ~= nil and object:getIsLowered(true)) then
		          setVisibility(self.raiseArms, true);
		          setVisibility(self.raisePickup, true);
		          setVisibility(self.raisePickup2, true);
		    else
		          setVisibility(self.lowerArms, true);
		          setVisibility(self.lowerPickup, true);
		          setVisibility(self.lowerPickup2, true);
		        end
		    end
			
	    local delta = spec.rpmr * dt
	        if object:getDoConsumePtoPower() then
		        if self.ptoRpm < 1000 then
                   self.ptoRpm = self.ptoRpm + dt / spec.ptoFactor + delta
                end
            else
                if self.ptoRpm > 0.1 then
                   self.ptoRpm = self.ptoRpm - dt / spec.ptoFactor + delta
		        end
            end
	        VehicleHudUtils.setHudValue(self, self.pto2, self.ptoRpm, 100);	
	        VehicleHudUtils.setHudValue(self, self.pto, self.ptoRpm, 100);
	    local delta = spec.rpmr * dt
	        if object:getDoConsumePtoPower() then
		       if self.barPress < 2.8 then
                  self.barPress = self.barPress + dt / spec.pressFactor 
              end
        else
            if self.barPress > 0.001 then
               self.barPress = self.barPress - dt / spec.pressFactor 
		    end 
           end
		       VehicleHudUtils.setHudValue(self, self.pressure, self.barPress, 100);    
		  end
		 end
		end
	        
end