-- author: rafftnix
-- date: 21.02.2015

-- BorderSpreadingControl.lua
-- No modification without the author's permission!
-- note: BSC = BorderSpreadingControl

BorderSpreadingControl = {};

function BorderSpreadingControl.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(AnimatedVehicle, specializations);
end;

function BorderSpreadingControl:load(xmlFile)
	self.setBSCAnimTime = SpecializationUtil.callSpecializationsFunction("setBSCAnimTime");
	
	self.BSCAnimName = getXMLString(xmlFile, "vehicle.borderSpreadingControl#animName");
	self.mouseMovementScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.borderSpreadingControl#mouseMovementScale"), 1);
	self.BSCMouseControlIconFilename = Utils.getFilename(getXMLString(xmlFile, "vehicle.borderSpreadingControl#mouseControlIcon"), self.baseDirectory);
	g_mouseControlsHelp:addIconFilename(self.BSCMouseControlIconFilename);
	self.currentBSCAnimTime = 0.5;
	self.targetBSCAnimTime = 0.5;
	self.BSCMouseXToSend = 0;
	
	-- the physical wheels need to be updated separately, having them in the animation does not work
	local physicalWheelIndices = getXMLString(xmlFile, "vehicle.borderSpreadingControl#physicalWheelIndices");
	if physicalWheelIndices ~= nil and physicalWheelIndices ~= "" then
		local indices = Utils.splitString(" ", physicalWheelIndices);
		local refNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.borderSpreadingControl#physicalWheelRefIndex"));
		for i, index in pairs(indices) do
			if self.wheels[tonumber(index)] ~= nil then
				self.wheels[tonumber(index)].BSCRefNodeIndex = refNode;
			else
				print("BorderSpreadingControl: physical wheel index does not exist");
			end;
		end;
	end;
	
	--self:setAnimationTime(self.BSCAnimName, 0.5, true);
	--self:setBSCAnimTime(0.5, true);
end;

function BorderSpreadingControl:delete()
end;

function BorderSpreadingControl:readStream(streamId, connection)
	local animTime = streamReadFloat32(streamId);
	self:setBSCAnimTime(animTime, true);
end;

function BorderSpreadingControl:writeStream(streamId, connection)
	streamWriteFloat32(streamId, self.currentBSCAnimTime);
end;

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

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

function BorderSpreadingControl:update(dt)
	if self:getIsActiveForInput() and self:getToggledFoldDirection() > 0 and self.foldAnimTime == 0 then 
		if InputBinding.hasEvent(InputBinding.BSCRIGHT) then
			self:setBSCAnimTime(0);
		end;
		if InputBinding.hasEvent(InputBinding.BSCMIDDLE) then
			self:setBSCAnimTime(0.5);
		end;
		if InputBinding.hasEvent(InputBinding.BSCLEFT) then
			self:setBSCAnimTime(1);
		end;
		
		local action = InputBinding["BORDERSPREADINGCONTROL"];
		local move, axisType = InputBinding.getInputAxis(action);
		if move ~= 0 then
			self:setBSCAnimTime(self.currentBSCAnimTime+(move*self.mouseMovementScale), true);
			self.BSCMouseXToSend = move;
		end;
		if not InputBinding.getIsInputMouseAxisTriggered(action) and self.BSCMouseXToSend ~= 0 then
			self:setBSCAnimTime(self.currentBSCAnimTime+(self.BSCMouseXToSend*self.mouseMovementScale));
			self.BSCMouseXToSend = 0;
		end;
		
		if InputBinding.getIsInputMouseAxisTriggered(action) then
			g_mouseControlsHelp:setIconFilename(self.BSCMouseControlIconFilename, "");
		end;
	end;
	
	if self:getIsActive() then
		if self.currentBSCAnimTime ~= self.targetBSCAnimTime then
			local directionFactor = 1;
			if self.targetBSCAnimTime < self.currentBSCAnimTime then
				directionFactor = -1;
			end;
			
			local animTime = self:getRealAnimationTime(self.BSCAnimName) + (dt*directionFactor);
			local targetAnimTime = self.animations[self.BSCAnimName].duration * self.targetBSCAnimTime;
			if directionFactor > 0 then
				animTime = math.min(targetAnimTime, animTime);
			else
				animTime = math.max(targetAnimTime, animTime);
			end;
			self:setRealAnimationTime(self.BSCAnimName, animTime, true);
			
			self.currentBSCAnimTime = self:getAnimationTime(self.BSCAnimName);
		end;
	end;
end;

function BorderSpreadingControl:updateTick(dt)
end;

function BorderSpreadingControl:draw()
	if self:getIsActiveForInput() and self.foldAnimTime == 0 then
		local text = g_i18n:getText("BSCHelpText");
		text = string.gsub(text, "key1" , InputBinding.getKeyNamesOfDigitalAction(InputBinding.BSCLEFT));
		text = string.gsub(text, "key2" , InputBinding.getKeyNamesOfDigitalAction(InputBinding.BSCMIDDLE));
		text = string.gsub(text, "key3" , InputBinding.getKeyNamesOfDigitalAction(InputBinding.BSCRIGHT));
	
		g_currentMission:addExtraPrintText(text);
	end; 
	
	--renderText(0.1, 0.5, 0.025, "self.currentBSCAnimTime: "..tostring(self.currentBSCAnimTime));
	--renderText(0.1, 0.55, 0.025, "self:getRealAnimationTime: "..tostring(self:getRealAnimationTime(self.BSCAnimName)));
end;

function BorderSpreadingControl:setBSCAnimTime(animTime, noEventSend)
	self.targetBSCAnimTime = math.max(0, math.min(1, animTime)); -- min: 0; max: 1;
	
	if not noEventSend then
		BorderSpreadingControlEvent.sendEvent(self, self.targetBSCAnimTime, noEventSend);
	end;
end;

function BorderSpreadingControl:setFoldState(direction, moveToMiddle, noEventSend)
	if direction > 0 then
		if self.isServer then
			self:setBSCAnimTime(0.5);
		end;
	end;
end;

local wheelUtilUpdateWheelSteeringAngle = WheelsUtil.updateWheelSteeringAngle;
WheelsUtil.updateWheelSteeringAngle = function(self, wheel, dt)
	wheelUtilUpdateWheelSteeringAngle(self, wheel, dt);
	if wheel.BSCRefNodeIndex ~= nil then
		local _, angle, _ = getRotation(wheel.BSCRefNodeIndex);
		wheel.steeringAngle = angle;
	end;
end;