--
-- Cabsuspension
-- Specialization for Cabsuspension
--
-- @author  JoXXer
-- @date  17/09/11
-- @version 1.0 - JoXXer
--			2.0	- rework by fruktor
--

Cabsuspension = {};

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

function Cabsuspension:load(xmlFile)
	-- Cabsuspension animation
	self.maxTranslationPrCycleCabin 	= 0.00008;
	self.maxTranslationPrCycleCabin2 	= 0.00004;
	self.cab = {};
	self.cab.rotNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.cab#rotNode"));

	if self.cab.rotNode~=nil then
		local x,y,z = getTranslation(self.cab.rotNode);
		self.startCabXTranslation = x;
		self.startCabYTranslation = y;
		self.startCabZTranslation = z;

		local xRot,yRot,zRot = getRotation(self.cab.rotNode);
		self.cabXRot = xRot;
		self.cabZrot = zRot;
	end;

	if self.wheels[3].repr ~= nil and self.wheels[4].repr ~= nil and self.wheels[1].repr ~= nil and self.wheels[2].repr ~= nil then
		local x1,y1,z1 = getTranslation(self.wheels[1].repr);	-- FRONT left
		local x2,y2,z2 = getTranslation(self.wheels[2].repr);	-- FRONT right
		local x3,y3,z3 = getTranslation(self.wheels[3].repr);	-- BACK left
		local x4,y4,z4 = getTranslation(self.wheels[4].repr);	-- BACK right
		
		-- ! manual offsets after measurement, see deubg string in update
		self.fl = y1 - 0.00;
		self.fr = y2 - 0.00;
		self.bl = y3 - 0.00;
		self.br = y4 - 0.00;
		
		self.fl_d = 0;
		self.fr_d = 0;
		self.bl_d = 0;
		self.br_d = 0;
		
		self.fl_m = 0;
		self.fr_m = 0;
		self.bl_m = 0;
		self.br_m = 0;
		
		self.fl_cur = 0;
		self.fr_cur = 0;
		self.bl_cur = 0;
		self.br_cur = 0;		

		self.fl_last = 0;
		self.fr_last = 0;
		self.bl_last = 0;
		self.br_last = 0;		

		self.fl_t = getXMLFloat(xmlFile, "vehicle.wheels.wheel(0)#suspTravel")/2; -- /2 or /3 or ??
		self.fr_t = getXMLFloat(xmlFile, "vehicle.wheels.wheel(1)#suspTravel")/2;
		self.bl_t = getXMLFloat(xmlFile, "vehicle.wheels.wheel(2)#suspTravel")/2;
		self.br_t = getXMLFloat(xmlFile, "vehicle.wheels.wheel(3)#suspTravel")/2;
		self.normVal = math.max( math.abs(self.fl_t), math.max( math.abs(self.fr_t), 
			math.max( math.abs(self.bl_t), math.max( math.abs(self.br_t) ) ) ) );
	end;

	self.cabTranslation = self.averageYTranslationCab;
	self.cabTranslationStart = self.cabTranslation;
	
	if self.wheels[3].repr ~= nil and self.wheels[4].repr ~= nil then
		local x,y,z = getTranslation(self.wheels[3].repr);
		local x2,y2,z2 = getTranslation(self.wheels[4].repr);
		local x3,y3,z3 = getTranslation(self.wheels[1].repr);
		local x3,y4,z4 = getTranslation(self.wheels[2].repr);
		self.averageYTranslation = (y + y2 + y3 + y4)/4;
	end;

	self.maxSeatTranslationPrCycle = 0.00008;
	self.seatTranslation = self.averageYTranslation;
	self.defaultPosition = self.averageYTranslation;	

	self.time2 = 0;
end;

function Cabsuspension:delete()
end;

function Cabsuspension:readStream(streamId, connection)
end;

function Cabsuspension:writeStream(streamId, connection)
end;

function Cabsuspension:readUpdateStream(streamId, timestamp, connection)
end;

function Cabsuspension:writeUpdateStream(streamId, connection, dirtyMask)
end;

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

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

function Cabsuspension:update(dt)

	self.time2 = self.time2 + dt;

	-- Cabsuspension animation
	if self.isClient then
		if self.cab.rotNode ~= nil and self.wheels[3].repr ~= nil and self.wheels[4].repr ~= nil then
		
			local x1,y1,z1 = getTranslation(self.wheels[1].repr);
			local x2,y2,z2 = getTranslation(self.wheels[2].repr);
			local x3,y3,z3 = getTranslation(self.wheels[3].repr);
			local x4,y4,z4 = getTranslation(self.wheels[4].repr);

			
			self.fl_cur = y1 - self.fl;
			self.fr_cur = y2 - self.fr;
			self.bl_cur = y3 - self.bl;
			self.br_cur = y4 - self.br;

			--self.fl_d = self.fl_cur;
			
			self.fl_d = 0.1*self.fl_d + 0.9*(self.fl_cur - self.fl_last); --
			self.fr_d = 0.1*self.fr_d + 0.9*(self.fr_cur - self.fr_last); --
			self.bl_d = 0.1*self.bl_d + 0.9*(self.bl_cur - self.bl_last); --0.1
			self.br_d = 0.1*self.br_d + 0.9*(self.br_cur - self.br_last); --0.1
			
			self.fl_d = (self.fl_cur - self.fl_last); 
			self.fr_d = (self.fr_cur - self.fr_last); 
			self.bl_d = (self.bl_cur - self.bl_last); 
			self.br_d = (self.br_cur - self.br_last); 
			
			local max_d = self.fl_d/self.fl_t;
			if math.abs(self.fr_d/self.fr_t) > math.abs(max_d) then
				max_d = self.fr_d/self.fr_t;
			end;
			if math.abs(self.bl_d/self.bl_t) > math.abs(max_d) then
				max_d = self.bl_d/self.bl_t;
			end;
			if math.abs(self.br_d/self.br_t) > math.abs(max_d) then
				max_d = self.br_d/self.br_t;
			end;

			self.fl_last = self.fl_cur;
			self.fr_last = self.fr_cur;
			self.bl_last = self.bl_cur;
			self.br_last = self.br_cur;

			-- 1.
			if self.fl_m > self.fl_d then
				self.fl_m = self.fl_m - self.maxTranslationPrCycleCabin * dt;
				if self.fl_m < self.fl_d then
					self.fl_m = self.fl_d;
				end;
			end;
			if self.fr_m > self.fr_d then
				self.fr_m = self.fr_m - self.maxTranslationPrCycleCabin * dt;
				if self.fr_m < self.fr_d then
					self.fr_m = self.fr_d;
				end;
			end;		
			if self.bl_m > self.bl_d then
				self.bl_m = self.bl_m - self.maxTranslationPrCycleCabin * dt;
				if self.bl_m < self.bl_d then
					self.bl_m = self.bl_d;
				end;
			end;		
			if self.br_m > self.br_d then
				self.br_m = self.br_m - self.maxTranslationPrCycleCabin * dt;
				if self.br_m < self.br_d then
					self.br_m = self.br_d;
				end;
			end;		
			
			-- 2.
			if self.fl_m < self.fl_d then
				self.fl_m = self.fl_m + self.maxTranslationPrCycleCabin * dt;
				if self.fl_m > self.fl_d then
					self.fl_m = self.fl_d;
				end;
			end;
			if self.fr_m < self.fr_d then
				self.fr_m = self.fr_m + self.maxTranslationPrCycleCabin * dt;
				if self.fr_m > self.fr_d then
					self.fr_m = self.fr_d;
				end;
			end;		
			if self.bl_m < self.bl_d then
				self.bl_m = self.bl_m + self.maxTranslationPrCycleCabin * dt;
				if self.bl_m > self.bl_d then
					self.bl_m = self.bl_d;
				end;
			end;		
			if self.br_m < self.br_d then
				self.br_m = self.br_m + self.maxTranslationPrCycleCabin * dt;
				if self.br_m > self.br_d then
					self.br_m = self.br_d;
				end;
			end;		

			--
			local w = {0,0};
			local maxVal = 1;
			
			w[1] = w[1] +  1*math.max(-maxVal,math.min(maxVal,self.fl_d/self.fl_t));
			w[2] = w[2] +  1*math.max(-maxVal,math.min(maxVal,self.fl_d/self.fl_t));
		
			w[1] = w[1] + -1*math.max(-maxVal,math.min(maxVal,self.fr_d/self.fr_t));
			w[2] = w[2] +  1*math.max(-maxVal,math.min(maxVal,self.fr_d/self.fr_t));
			
			w[1] = w[1] +  1*math.max(-maxVal,math.min(maxVal,self.bl_d/self.bl_t));
			w[2] = w[2] + -1*math.max(-maxVal,math.min(maxVal,self.bl_d/self.bl_t));

			w[1] = w[1] + -1*math.max(-maxVal,math.min(maxVal,self.br_d/self.br_t));
			w[2] = w[2] + -1*math.max(-maxVal,math.min(maxVal,self.br_d/self.br_t));
			

			w[1] = math.max(math.min(1,w[1]),-1);
			w[2] = math.max(math.min(1,w[2]),-1);
				
			if self.cab.rotNode ~= nil then
								
				-- 1.				
				local t = -w[2]*Utils.degToRad(6);
				if self.cabXRot > t + self.maxTranslationPrCycleCabin2 * dt then
					self.cabXRot = self.cabXRot - self.maxTranslationPrCycleCabin2*dt; --math.max(0.01, math.abs(w[2])) * dt;
					if self.cabXRot < t then
						self.cabXRot = t;
					end;
				end;		
				-- 2.
				if self.cabXRot < t - self.maxTranslationPrCycleCabin2 * dt then
					self.cabXRot = self.cabXRot + self.maxTranslationPrCycleCabin2*dt; --*math.max(0.01, math.abs(w[2])) * dt;
					if self.cabXRot > t then
						self.cabXRot = t;
					end;
				end;
				--self.cabXRot = -w[2]*Utils.degToRad(6);

				-- 1.
				local t = -w[1]*Utils.degToRad(6);
				if self.cabZrot > t + self.maxTranslationPrCycleCabin2 * dt then
					self.cabZrot = self.cabZrot - self.maxTranslationPrCycleCabin2*dt; --*math.max(0.01, math.abs(w[1])) * dt;
					if self.cabZrot < t then
						self.cabZrot = t;
					end;
				end;		
				-- 2.
				if self.cabZrot < t - self.maxTranslationPrCycleCabin2 * dt then
					self.cabZrot = self.cabZrot + self.maxTranslationPrCycleCabin2*dt; --*math.max(0.01, math.abs(w[1])) * dt;
					if self.cabZrot > t then
						self.cabZrot = t;
					end;
				end;
		
				setRotation(self.cab.rotNode, self.cabXRot, 0, self.cabZrot);
				
				--print("self.cabXRot="..tostring(math.deg(self.cabXRot)).."   self.cabZrot="..tostring(math.deg(self.cabZrot)));
			end;
			
			--max_d
			
			-- local t = self.startSeatYTranslation + max_d*0.25;
			
			-- if self.seatTranslation > t then -- + self.maxSeatTranslationPrCycle * dt then
				-- self.seatTranslation = self.seatTranslation - self.maxSeatTranslationPrCycle * dt;
				-- if self.seatTranslation < t then
					-- self.seatTranslation = t;
				-- end;
			-- elseif self.seatTranslation < t then -- - self.maxSeatTranslationPrCycle * dt then
				-- self.seatTranslation = self.seatTranslation + self.maxSeatTranslationPrCycle * dt;
				-- if self.seatTranslation > t then
					-- self.seatTranslation = t;
				-- end;
			-- end;			
			-- setTranslation(self.seatNode, self.startSeatXTranslation, self.seatTranslation, self.startSeatZTranslation);
			
		end;
		
		
	
	end;
	
end;

function Cabsuspension:updateTick(dt)

end;

function Cabsuspension:draw()
end;

function Cabsuspension:onLeave()

end;

function Cabsuspension:onEnter()

end;
