--
-- Specialisation for Unimog 406 cabrio
-- 
-- Author: CebuljCek

Vehicle.registerJointType("attachableFrontloader");

Unimog406cabrio = {};

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

function Unimog406cabrio:load(xmlFile)

    self.backHydraulic = {};
	self.backHydraulic.rootArm = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.backHydraulic#rootArm"));
	self.backHydraulic.bottomArm = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.backHydraulic#bottomArm"));
	self.frontAttacherJoint = {};
	self.frontAttacherJoint.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.trailerAttacherJoints#front"));
	
	local scheibenwischerAnimRootNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.scheibenwischer#rootNode"));
    self.scheibenwischerAnimCharSet = 0;
    if scheibenwischerAnimRootNode ~= nil and scheibenwischerAnimRootNode ~= 0 then
        self.scheibenwischerAnimCharSet = getAnimCharacterSet(scheibenwischerAnimRootNode);
        if self.scheibenwischerAnimCharSet ~= 0 then
            local clip = getAnimClipIndex(self.scheibenwischerAnimCharSet, getXMLString(xmlFile, "vehicle.scheibenwischer#clip"));
            assignAnimTrackClip(self.scheibenwischerAnimCharSet, 0, clip);
            setAnimTrackLoopState(self.scheibenwischerAnimCharSet, 0, true);
            local scheibenwischerAnimSpeedScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.scheibenwischer#speedScale"), 1);
			setAnimTrackSpeedScale(self.scheibenwischerAnimCharSet, 0, scheibenwischerAnimSpeedScale);
            self.scheibenwischerAnimDuration = getAnimClipDuration(self.scheibenwischerAnimCharSet, clip);
        end;
    end;
	self.isscheibenwischerActive = false;
	self.finishscheibenwischer = true;
	
	self.showFillLevelWarning = false;
    self.showFillLevelTime = 5;
	
	local gaspedalNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.gaspedal#index"));
    if gaspedalNode ~= nil then
        self.gaspedal = {};
        self.gaspedal.node = gaspedalNode;    
		self.gaspedal.maxSpeed = getXMLInt(xmlFile, "vehicle.gaspedal#maxSpeed");
		local x1,y1,z1 = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.gaspedal#minRot"));
		local x2,y2,z2 = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.gaspedal#maxRot"));		
		self.gaspedal.rotMin = {math.rad(Utils.getNoNil(x1,0)),math.rad(Utils.getNoNil(y1,0)),math.rad(Utils.getNoNil(z1,0))};
		self.gaspedal.rotMax = {math.rad(Utils.getNoNil(x2,0)),math.rad(Utils.getNoNil(y2,0)),math.rad(Utils.getNoNil(z2,0))};
    end;
	
    local bremspedalNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.bremspedal#index"));
    if bremspedalNode ~= nil then
        self.bremspedal = {};
        self.bremspedal.node = bremspedalNode;
		local x1,y1,z1 = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.gaspedal#minRot"));
		local x2,y2,z2 = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.gaspedal#maxRot"));
		self.bremspedal.rotMin = {math.rad(Utils.getNoNil(x1,0)),math.rad(Utils.getNoNil(y1,0)),math.rad(Utils.getNoNil(z1,0))};			
		self.bremspedal.rotMax = {math.rad(Utils.getNoNil(x2,0)),math.rad(Utils.getNoNil(y2,0)),math.rad(Utils.getNoNil(z2,0))};
        self.bremspedal.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.bremspedal#rotTime"), 1)*1000;
        self.bremspedalIsActive = false;
    end;	
	
    local blinkerhebelNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.blinkerhebel#index"));
    if blinkerhebelNode ~= nil then
        self.blinkerhebel = {};
        self.blinkerhebel.node = blinkerhebelNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.blinkerhebel#minRot"));
        self.blinkerhebel.minRot = {};
        self.blinkerhebel.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.blinkerhebel.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.blinkerhebel.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.blinkerhebel#rotLeft"));
        self.blinkerhebel.leftRot = {};
        self.blinkerhebel.leftRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.blinkerhebel.leftRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.blinkerhebel.leftRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.blinkerhebel#rotRight"));
        self.blinkerhebel.rightRot = {};
        self.blinkerhebel.rightRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.blinkerhebel.rightRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.blinkerhebel.rightRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.blinkerhebel.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.blinkerhebel#rotTime"), 1)/1000;
		self.blinkerhebel.lastDir = 1;
    end;
	
	self.drehzahlnadel = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.drehzahlnadel#index"));
	self.tanknadel = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.tanknadel#index"));
	self.drehzahlnadelLight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.drehzahlnadel#light"));
	self.tanknadelLight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.tanknadel#light"));
	self.tankicon = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.tankicon#index"));
	self.batterieicon = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.batterieicon#index"));
	
	self.controlPanel1 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.controlPanels.controlPanel1#index" ));
	self.controlPanel2 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.controlPanels.controlPanel2#index" ));
	
	self.updateJoint = false;
	
	self.Allrad = true;
	self.hudallrad_yesPosX = 0.7543;
    self.hudallrad_yesWidth = 0.234;
    self.hudallrad_yesPosY = 0.2545;
    self.hudallrad_yesHeight = 0.04;
	self.infoPanelAllradPath = Utils.getFilename("textures/allrad_symb_yes.png", self.baseDirectory);
	self.hudallrad_yesOverlay = Overlay:new("textures/allrad_symb_yes", self.infoPanelAllradPath, self.hudallrad_yesPosX, self.hudallrad_yesPosY, self.hudallrad_yesWidth, self.hudallrad_yesHeight);
	self.infoPanelAllradPath1 = Utils.getFilename("textures/allrad_symb_no.png", self.baseDirectory);
	self.hudallrad_noOverlay = Overlay:new("textures/allrad_symb_no", self.infoPanelAllradPath1, self.hudallrad_yesPosX, self.hudallrad_yesPosY, self.hudallrad_yesWidth, self.hudallrad_yesHeight);
	self.showHudallrad_yes = true;
end;

function Unimog406cabrio:delete()
	if self.hudallradyesOverlay ~= nil then
		self.hudallrad_yesOverlay:delete();
	end;
	if self.hudallradyesOverlay ~= nil then
		self.hudallrad_noOverlay:delete();
	end;
end;

function Unimog406cabrio:readStream(streamId, connection)
end;

function Unimog406cabrio:writeStream(streamId, connection)
end;

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

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

function Unimog406cabrio:update(dt)
    if self:getIsActive() then
		Cylindered.updateMovingPart(self, self.movingParts[1]);
        
        if self.backHydraulic ~= nil then
			local bHx,bHy,bHz = getRotation(self.backHydraulic.bottomArm);
			local bHBAx,_,_ = getRotation(self.backHydraulic.bottomArm);
			setRotation(self.backHydraulic.rootArm, bHBAx*2.2, bHy, bHz);
		end;
		
        for _, part in pairs(self.movingParts) do
			part.isDirty = true;
		end;
		
		if InputBinding.hasEvent(InputBinding.Unimog406Allrad) then
		   	if self.Allrad == false then
				self.Allrad = true;
		   	else
		   		self.Allrad = false;
		   	end;
		end;

   		if self.Allrad == true then
			self.showHudallrad_yes = true;
			self.showHudallrad_no = false;
		else
			self.showHudallrad_yes = false;
			self.showHudallrad_no = true;
		end;

		if self.steeringlocked == false then
			self.autoRotateBackSpeed = 2.5;
		end;
		if self.steeringlocked == true then
			self.autoRotateBackSpeed = 0.0;
		end;

		if self.Allrad == true then
		 	self.wheels[1].driveMode = 2;
		 	self.wheels[2].driveMode = 2;
			self.motor.forwardTorqueCurve = AnimCurve:new(linearInterpolator1);
			self.motor.forwardTorqueCurve:addKeyframe({v = 11*3, time = 2400});
		else
		 	self.wheels[1].driveMode = 0;
		 	self.wheels[2].driveMode = 0;
		 	self.motor.forwardTorqueCurve = AnimCurve:new(linearInterpolator1);
			self.motor.forwardTorqueCurve:addKeyframe({v = 9.5*3, time = 2400});
		end;
		
	end;
end;

function Unimog406cabrio:updateTick(dt)

    if self:getIsActive() then	
		if not self.finishscheibenwischer then
			if getAnimTrackTime(self.scheibenwischerAnimCharSet, 0) % self.scheibenwischerAnimDuration <= 100 then
				setAnimTrackTime(self.scheibenwischerAnimCharSet, 0, 0.0);
				disableAnimTrack(self.scheibenwischerAnimCharSet, 0);
				self.finishscheibenwischer = true;
			end;
		end;
		
		if g_currentMission.environment.lastRainScale > 0.1 and g_currentMission.environment.timeSinceLastRain < 30 then
			if not self.isscheibenwischerActive then
				enableAnimTrack(self.scheibenwischerAnimCharSet, 0);
				self.isscheibenwischerActive = true;
			end;
		else
			if self.isscheibenwischerActive then
				self.isscheibenwischerActive = false;
				self.finishscheibenwischer = false;
			end;
		end;
		
		if self.camIndex == 2 then
		
			if self.gaspedal ~= nil then		
				local percent = (self.lastSpeed*self.speedDisplayScale*3600) / self.gaspedal.maxSpeed;
				local minRot = self.gaspedal.rotMin;
				local maxRot = self.gaspedal.rotMax;
					
				local x = minRot[1] + (maxRot[1] - minRot[1]) * percent;
				local y = minRot[2] + (maxRot[2] - minRot[2]) * percent;
				local z = minRot[3] + (maxRot[3] - minRot[3]) * percent;
				setRotation(self.gaspedal.node, x, y, z);
			end;
			
			if self.bremspedal ~= nil then
				local x, y, z = getRotation(self.bremspedal.node);
				local rot = {x,y,z};
				local direction = 1;
				if self.invertedDrivingDirection then
				    direction = -1;
				else
				    direction = 1;
				end;
				local braking = math.abs(Utils.sign(self.lastAcceleration)+ (-self.movingDirection * direction)) == 2;
				local newRot = Utils.getMovedLimitedValues(rot, self.bremspedal.rotMax, self.bremspedal.rotMin, 3, self.bremspedal.rotTime, dt, braking);
				setRotation(self.bremspedal.node, unpack(newRot));
			end;
			
			if self.blinkerhebel ~= nil then
				local dir = 1;
				local hasRotChanged = false;
				local destRot = self.blinkerhebel.minRot;
				if not (self.B3.dirRight[1].a and self.B3.dirLeft[1].a) then
					if self.B3.dirLeft[1].a then
						destRot = self.blinkerhebel.leftRot;
						self.blinkerhebel.lastDir = 1;		
					elseif self.B3.dirRight[1].a then
						destRot = self.blinkerhebel.rightRot;
						self.blinkerhebel.lastDir = -1;
						dir = -1;
					else
						if not self.B3.dirRight[1].a and not self.B3.dirLeft[1].a then
							if self.blinkerhebel.lastDir ~= -1 then
								dir = -1;
								if self.blinkerhebel.lastDir ~= 1 then
								    dir = 1;
								end;
							end;
						end;
					end;
				else
					local x,y,z = getRotation(self.blinkerhebel.node);
					if y > 0 then
						dir = -1;
					end;
				end;
				
				local rot = {getRotation(self.blinkerhebel.node)};
				for i=1, 3 do
					
					local newRot = AnimatedVehicle.getMovedLimitedValue(rot[i], destRot[i], self.blinkerhebel.rotTime*dir, dt);
					if rot[i] ~= newRot then
						hasRotChanged = true;
						rot[i] = newRot;
					end;
				end;
				if hasRotChanged then
					setRotation(self.blinkerhebel.node, unpack(rot));
				end;
			end;			
		else
			setRotation(self.gaspedal.node, unpack(self.gaspedal.rotMin));
			setRotation(self.bremspedal.node, unpack(self.bremspedal.rotMin));
		end;
		
		if self.isMotorStarted then
			local kmh = math.min(100, math.max(0, self.lastSpeed*self.speedDisplayScale*3600));
			local rotateDrehzahlnadel = (((kmh / 25)*100) +10);
			local currentFuelPercentage = 0;
			local fuelWarnPercentage = 20;
			if self.fuelCapacity > 0 then
				currentFuelPercentage = (self.fuelFillLevel / self.fuelCapacity + 0.0001) * 100;
			end;
			if currentFuelPercentage < fuelWarnPercentage then
				setVisibility(self.tankicon, true);
			else
				setVisibility(self.tankicon, false);
			end;
			setVisibility(self.batterieicon, false);
			local rotateTanknadel = ((currentFuelPercentage / 111) * 100);
			if self.currentLight > 0 then
				setVisibility(self.drehzahlnadel, false);
				setVisibility(self.tanknadel, false);
				setVisibility(self.drehzahlnadelLight, true);
				setVisibility(self.tanknadelLight, true);    
				setRotation(self.drehzahlnadelLight, 0, Utils.degToRad( - rotateDrehzahlnadel), 0);
				setRotation(self.tanknadelLight, 0, Utils.degToRad(rotateTanknadel), 0);
			else
				setVisibility(self.drehzahlnadel, true);
				setVisibility(self.tanknadel, true);
				setVisibility(self.drehzahlnadelLight, false);
				setVisibility(self.tanknadelLight, false);
				setRotation(self.drehzahlnadel, 0, Utils.degToRad( - rotateDrehzahlnadel), 0);
				setRotation(self.tanknadel, 0, Utils.degToRad(rotateTanknadel), 0);
			end;
		else
			setRotation(self.drehzahlnadel, 0, 0, 0);
			setRotation(self.tanknadel, 0, 0, 0);
			setRotation(self.drehzahlnadelLight, 0, 0, 0);
			setRotation(self.tanknadelLight, 0, 0, 0);
			setVisibility(self.batterieicon, true);
			setVisibility(self.tankicon, false);
		end;
	end;
end;

function Unimog406cabrio:draw()

	if self.showHudallrad_yes and self.isEntered then
		self.hudallrad_yesOverlay:render();
	end;
	if self.showHudallrad_no and self.isEntered then
		self.hudallrad_noOverlay:render();
	end;
	
	if self.showFillLevelWarning then
		if self.showFillLevelCur < self.showFillLevelTime then
			self.showFillLevelCur = self.showFillLevelCur + 0.04
			g_currentMission:addWarning(g_i18n:getText("implement_Warning"), 0.018, 0.033);
		else
			self.showFillLevelCur = nil;
			self.showFillLevelWarning = false;
		end;
	end;
end;

function Unimog406cabrio:attachImplement(implement)

	local jointType = implement.object.attacherJoint.jointType;
	local jointIndex = implement.jointDescIndex;

	if jointType == Vehicle.JOINTTYPE_IMPLEMENT then
		if jointIndex == 2 then
			setVisibility(self.attacherJoints[jointIndex].topArm.rotationNode, true);
		end;
	end;
	
	if jointType == Vehicle.JOINTTYPE_IMPLEMENT then
		if jointIndex == 1 then
			if self.fillLevel == 0 then
				self.showFillLevelWarning = false;
				self.showFillLevelCur = nil;
				self:changeVariableBody(4, 1);
				setVisibility(self.attacherJoints[jointIndex].topArm.rotationNode, true);
			else
				self.showFillLevelWarning = true;
				self.showFillLevelCur = 0;
				self:detachImplement(table.getn(self.attachedImplements));
			end;
		end;
	end;
	self.updateJoint = true;
end;

function Unimog406cabrio:detachImplement(implementIndex)

	local implement = self.attachedImplements[implementIndex];
	local jointIndex = implement.jointDescIndex;

	if jointIndex == 2 then
		setVisibility(self.attacherJoints[jointIndex].topArm.rotationNode, false);
	end;
	
	if jointIndex == 1 then
		self:changeVariableBody(1, 1);
		setVisibility(self.attacherJoints[jointIndex].topArm.rotationNode, false);
	end;
end;

function Unimog406cabrio:validateAttacherJoint(implement, jointDesc, dt)
    if self.updateJoint then
        self.updateJoint = false;
        return true;
    end;
    return false;
end;

function Unimog406cabrio:onLeave()

	if self.isscheibenwischerActive then
		disableAnimTrack(self.scheibenwischerAnimCharSet, 0);
	end;
	
	if self.isMotorStarted then
	   setVisibility(self.batterieicon, false);
	else
	   setVisibility(self.batterieicon, true);
	end;
	
	self.motor.brakeForce = 600;
end;

function Unimog406cabrio:onEnter()
	if self.isscheibenwischerActive then
		enableAnimTrack(self.scheibenwischerAnimCharSet, 0);
	end;
	
	if self.isMotorStarted then
	   setVisibility(self.batterieicon, false);
	else
	   setVisibility(self.batterieicon, true);
	end;
	
	self.motor.brakeForce = 20;
end;