-- by modelleicher
-- www.schwabenmodding.bplaced.net

EicherEM300Animations = {};

function EicherEM300Animations.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Motorized, specializations);
end;

function EicherEM300Animations:load(xmlFile)
	self.changeSitzBankState = EicherEM300Animations.changeSitzBankState; -- self:changeSitzBankState(state, noEventSend)
	
	-- extraItems Settings
	self.extraItemsNode = Utils.indexToObject(self.components, Utils.getNoNil(getXMLString(xmlFile, "vehicle.EicherEM300Animations#extraItemNode"), "0>"));
	self.extraItemKeyname = "Eicher_EM_300";
	
	-- Zapfwellenstummel
	self.zapfwelleStummel = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.ZapfwellenStummel#index"));
	self.zapfwelleStummelSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.ZapfwellenStummel#speed"),1);
	
	-- Gaspedal
	self.gasPedal = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.GasPedal#index"));
	self.gasPedalMaxRot = getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.GasPedal#maxRot");
	self.gasPedalMulti = getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.GasPedal#multiplicator");
	
	-- Handgashebel
	self.handgasHebel = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.HandgasHebel#index"));
	self.handgasHebelTemp1Rot = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.HandgasHebel#tempomat1rot"));
	self.handgasHebelTemp2Rot = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.HandgasHebel#tempomat2rot"));
	self.handgasHebelTemp3Rot = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.HandgasHebel#tempomat3rot"));
	self.handgasHebelTemp4Rot = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.HandgasHebel#tempomat4rot"));	
	self.hgHrot = 0;
	
	-- Tachozeiger / Speedometer animation
	self.tachoZeiger = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.TachoZeiger#zeigerIndex"));
	self.tachoZeigerMultiplicator = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.TachoZeiger#multiplicator"), 10);
	self.tachoZeigerMaxRotation = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.TachoZeiger#maxRotation"), 245);

	--Temperaturzeiger / temperature Display animation
	self.temperaturZeiger = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.TemperaturZeiger#zeigerIndex"));
	self.temperaturZeigerMaxRot = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.TemperaturZeiger#maxRotation"));
	self.tempCnt = 0;

	-- Index der Stoßstange 
	self.emStossstangeIndex = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations#emStossstangeIndex"));
	
	-- Sitzbank ein / ausblenden
	self.sitzBank = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.Sitzbank#index"));
	self.sitzBankState = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.EicherEM300Animations.Sitzbank#startState"), true);
	
	-- Animierter Blinkerhebel
	self.blinkerHebel = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.BlinkerHebel#index"));
	self.blinkerHebelLeftRot = getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.BlinkerHebel#linksRot");
	self.blinkerHebelRightRot = getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.BlinkerHebel#rechtsRot");

	-- Zusätzliche Blinkleuchten in den Armaturen bei angehängten Anhängern / additional lights for turninglights at the dashboard if trailers attached
	self.blinkerLeuchte1L = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.BlinkerLeuchten#leuchte1L"));
	self.blinkerLeuchte1R = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.BlinkerLeuchten#leuchte1R"));
	self.blinkerLeuchte2L = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.BlinkerLeuchten#leuchte2L"));
	self.blinkerLeuchte2R = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.BlinkerLeuchten#leuchte2R"));
	self.hasAttachedTrailers = 0;
	setVisibility(self.blinkerLeuchte1L, false);
	setVisibility(self.blinkerLeuchte2L, false);
	setVisibility(self.blinkerLeuchte1R, false);
	setVisibility(self.blinkerLeuchte2R, false);
	
	-- Tankleuchte leuchtet auf sobald im Tank zu wenig drin ist / warning light if fuel level low
	self.tankLeuchte = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.TankLeuchte#index"));
	self.tankMinWarnLevel = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.EicherEM300Animations.TankLeuchte#minWarnLevel"));
	setVisibility(self.tankLeuchte, false);

	-- Ladekontrollleuchte / Batterie load light
	self.ladeLeuchte = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.EicherEM300Animations.LadeKontrollLeuchte#index"));
	setVisibility(self.ladeLeuchte, false);
	self.ladeLeuchteOn = 0;
	self.ladeTimer = 50;
end;
function EicherEM300Animations:readStream(streamId, connection)  
     self:changeSitzBankState(streamReadBool(streamId), true);  
end;
function EicherEM300Animations:writeStream(streamId, connection)  
    streamWriteBool(streamId, self.sitzBankState);  
end;
function EicherEM300Animations:delete()
end;
function EicherEM300Animations:mouseEvent(posX, posY, isDown, isUp, button)
end;
function EicherEM300Animations:keyEvent(unicode, sym, modifier, isDown)
end;
function EicherEM300Animations:changeSitzBankState(state, noEventSend)
	changeSitzBankStateEvent.sendEvent(self, state, noEventSend);
	self.sitzBankState = state;
	setVisibility(self.sitzBank, state);
end;
function EicherEM300Animations:updateTick(dt)
	-- Zusätzliche Blinkleuchten in den Armaturen bei angehängten Anhängern / additional lights for turninglights at the dashboard if trailers attached
	if table.getn(self.attachedImplements) > 0 or self.hasAttachedTrailers > 0 then
		self.hasAttachedTrailers = 0;
		for i=1, table.getn(self.attachedImplements) do  
			if self.attachedImplements[i].object.lastFillDelta ~= nil then -- "catch" all trailers 
				self.hasAttachedTrailers = 	self.hasAttachedTrailers +1;
			elseif self.attachedImplements[i].object.isSprayerFilling ~= nil and self.attachedImplements[i].object.wheels[1] ~= nil then -- "catch" manure and dung spreader with wheels --> "trailers", too
				self.hasAttachedTrailers = 	self.hasAttachedTrailers +1;
			end;
			if table.getn(self.attachedImplements[i].object.attachedImplements) > 0 then -- maybe the trailer has also attached a trailer.. 
				for r=1, table.getn(self.attachedImplements[i].object.attachedImplements) do
					if self.attachedImplements[i].object.attachedImplements[r].object.lastFillDelta ~= nil then -- "catch" attached trailer at the trailer here
						self.hasAttachedTrailers = 	self.hasAttachedTrailers +1;
					end;
				end;
			end;
		end;
		if self.hasAttachedTrailers == 0 then
			setVisibility(self.blinkerLeuchte1L, false);
			setVisibility(self.blinkerLeuchte2L, false);
			setVisibility(self.blinkerLeuchte1R, false);
			setVisibility(self.blinkerLeuchte2R, false);
		elseif self.hasAttachedTrailers == 1 then
			setVisibility(self.blinkerLeuchte1L, true);
			setVisibility(self.blinkerLeuchte2L, false);
			setVisibility(self.blinkerLeuchte1R, true);
			setVisibility(self.blinkerLeuchte2R, false);			
		elseif self.hasAttachedTrailers == 2 then
			setVisibility(self.blinkerLeuchte1L, true);
			setVisibility(self.blinkerLeuchte2L, true);	
			setVisibility(self.blinkerLeuchte1R, true);
			setVisibility(self.blinkerLeuchte2R, true);			
		end;
	end;
	
	-- Animierter Blinkerhebel
	if self.B3.dirLeft[1].a or self.B3.dirRight[1].a or self.B3.wl then
		if self.B3.dirLeft[1].a then
			setRotation(self.blinkerHebel, 0, Utils.degToRad(self.blinkerHebelLeftRot), 0)
		else
			setRotation(self.blinkerHebel, 0, Utils.degToRad(self.blinkerHebelRightRot), 0)
		end;
		if self.B3.wl then
			setRotation(self.blinkerHebel, 0, 0, 0)
		end;
	else
		setRotation(self.blinkerHebel, 0, 0, 0)
	end;
	
end;


function EicherEM300Animations:update(dt)
	if self:getIsActiveForInput() then
		if InputBinding.hasEvent(InputBinding.ToggleSitzbank) then
			self:changeSitzBankState(not self.sitzBankState);
		end;
	end;

	if self:getIsActive() then
		if self.isMotorStarted then
			-- Zapfwellenstummel
			rotate(self.zapfwelleStummel, 0, 0, self.zapfwelleStummelSpeed / 10 * dt);
		
 		    -- Handgashebel
			if self.handgasHebel ~= nil then
				local rot = 0;
				if self.motor.speedLevel == 1 then
					rot = self.handgasHebelTemp1Rot
				elseif self.motor.speedLevel == 2 then
					rot = self.handgasHebelTemp2Rot
				elseif self.motor.speedLevel == 3 then
					rot = self.handgasHebelTemp3Rot
				elseif self.motor.speedLevel == 4 then
					rot = self.handgasHebelTemp4Rot
				end;
				if self.hgHrot < rot then
					self.hgHrot = math.min(rot, self.hgHrot +1);
					setRotation(self.handgasHebel, 0, Utils.degToRad(self.hgHrot), 0)
				elseif self.hgHrot > rot then
					self.hgHrot = math.max(rot, self.hgHrot -1);
					setRotation(self.handgasHebel, 0, Utils.degToRad(self.hgHrot), 0)
				end;
			end;

			-- Ladekontrollleuchte / Batterie load light
			if self.ladeLeuchteOn == 1 then
				setVisibility(self.ladeLeuchte, true);
				if self.movingDirection ~= 0 then
					self.timerTrue = true;
				end;
				if self.timerTrue then
					self.ladeTimer = math.max(self.ladeTimer - 0.1, 0);
				end;
				if self.ladeTimer == 0 then
					setVisibility(self.ladeLeuchte, false);
					self.timerTrue = nil;
					self.ladeLeuchteOn = 0;
					self.ladeTimer = 50;
				end;
			end;
						
			-- Tankleuchte leuchtet auf sobald im Tank zu wenig drin ist / warning light if fuel level low
			local actualTankInhalt = 0;
			if self.fuelCapacity > 0 then
				actualTankInhalt = (self.fuelFillLevel / self.fuelCapacity + 0.0001) * 100;
			end;
			if actualTankInhalt < self.tankMinWarnLevel then
				setVisibility(self.tankLeuchte, true);
			else
				setVisibility(self.tankLeuchte, false);
			end;
				
			--Tachozeiger / speedometer animation
			self.kmhMath = math.min(100, math.max(0, self.lastSpeed*self.speedDisplayScale*3600));
			local zeigerRotation = math.min(self.kmhMath * self.tachoZeigerMultiplicator, self.tachoZeigerMaxRotation);
			setRotation(self.tachoZeiger, 0, Utils.degToRad(zeigerRotation), 0);

			-- Gaspedal
			local gasPedalRotation = math.min(self.kmhMath * self.gasPedalMulti, self.gasPedalMaxRot);
			setRotation(self.gasPedal, Utils.degToRad(gasPedalRotation), 0, 0)

			
			
			-- Temperaturanzeiger / temperature display animation und / and berechnung / calculation
			if self.tempCnt < 3000 then
				setRotation(self.temperaturZeiger, 0, Utils.degToRad(-(self.temperaturZeigerMaxRot/10000)*self.tempCnt), 0);
				self.tempCnt = self.tempCnt + 4;
			elseif self.tempCnt > 3000 and self.tempCnt < 6000 then
				setRotation(self.temperaturZeiger, 0, Utils.degToRad(-(self.temperaturZeigerMaxRot/10000)*self.tempCnt), 0);
				self.tempCnt = math.min(self.tempCnt + 3, 10000);			
			else
				setRotation(self.temperaturZeiger, 0, Utils.degToRad(-(self.temperaturZeigerMaxRot/10000)*self.tempCnt), 0);
				self.tempCnt = math.min(self.tempCnt + 2, 10000);
			end;
		end;
	else
		self.tempCnt = math.max(self.tempCnt - 0.08, 0);
	end;
	
end;
function EicherEM300Animations:draw()
	g_currentMission:addHelpButtonText(g_i18n:getText("ToggleSitzbank"), InputBinding.ToggleSitzbank);
end;
function EicherEM300Animations:onEnter()
	self.ladeLeuchteOn = 1;
end;
function EicherEM300Animations:onLeave()
	self.ladeLeuchteOn = 0;
end;

function EicherEM300Animations:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then
		local state = Utils.getNoNil(getXMLBool(xmlFile, key.."#sitzBankState"));
		self:changeSitzBankState(state);
	end;
	return BaseMission.VEHICLE_LOAD_OK;
end;

function EicherEM300Animations:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'sitzBankState="'..tostring(self.sitzBankState)..'"';
	local nodes = nil;
	return attributes,nodes;
end;



changeSitzBankStateEvent = {};
changeSitzBankStateEvent_mt = Class(changeSitzBankStateEvent, Event);
InitEventClass(changeSitzBankStateEvent, "changeSitzBankStateEvent");

function changeSitzBankStateEvent:emptyNew()  
    local self = Event:new(changeSitzBankStateEvent_mt );
    self.className="changeSitzBankStateEvent";
    return self;
end;
function changeSitzBankStateEvent:new(vehicle, state) 
    self.vehicle = vehicle;
    self.state = state;
    return self;
end;
function changeSitzBankStateEvent:readStream(streamId, connection)  
    local id = streamReadInt32(streamId); 
    self.state = streamReadBool(streamId); 
    self.vehicle = networkGetObject(id); 
    self:run(connection);  
end;
function changeSitzBankStateEvent:writeStream(streamId, connection)   
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));	
    streamWriteBool(streamId, self.state );   
end;
function changeSitzBankStateEvent:run(connection) 
    self.vehicle:changeSitzBankState(self.state, true);
	if not connection:getIsServer() then  
		g_server:broadcastEvent(changeSitzBankStateEvent:new(self.vehicle, self.state), nil, connection, self.object);
	end;
end;
function changeSitzBankStateEvent.sendEvent(vehicle, state, noEventSend)  
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then   
			g_server:broadcastEvent(changeSitzBankStateEvent:new(vehicle, state), nil, nil, vehicle);
		else 
			g_client:getServerConnection():sendEvent(changeSitzBankStateEvent:new(vehicle, state));
		end;
	end;
end;