--
-- CrawlerFix
--
-- @author:    	Xentro (Marcus@Xentro.se)
-- @website:	www.Xentro.se
-- @history:	v1.0 - 2015-02-14 - Initial implementation
-- 

CrawlerFix = {};

function CrawlerFix.prerequisitesPresent(specializations)
    return true;
end;

function CrawlerFix:load(xmlFile)
	local i = 0;
	while true do
		local key = string.format("vehicle.crawlers.crawler(%d)", i);
		if not hasXMLProperty(xmlFile, key) then break; end;
		
		local wheelId = getXMLInt(xmlFile, key .. "#wheelId");
		if wheelId ~= nil and self.wheels[wheelId] ~= nil then
			self.crawlerHasWheelId = true;
			
			self.crawlers[i + 1].wheelId = wheelId;
			self.crawlers[i + 1].traveledDistance = 0;
			self.crawlers[i + 1].lastTraveledDistance = 0;
			self.crawlers[i + 1].sentScrollPosition = 0;
			self.crawlers[i + 1].rotSpeed = 0;
			self.crawlers[i + 1].sentRotSpeed = 0;
		end;
		
		i = i + 1;
	end;
	
	self.CrawlerFixDirtyFlag = self:getNextDirtyFlag();
end;

function CrawlerFix:delete()
end;

function CrawlerFix:readStream(streamId, connection)
end;

function CrawlerFix:writeStream(streamId, connection)
end;

function CrawlerFix:readUpdateStream(streamId, timestamp, connection)
	if connection:getIsServer() then -- client
		if streamReadBool(streamId) then
			for i = 1, table.getn(self.crawlers) do
				local speed = streamReadFloat32(streamId);
				local rotSpeed = streamReadFloat32(streamId);
				local crawler = self.crawlers[i];
				
				crawler.scrollPosition = speed;
				crawler.rotSpeed = rotSpeed / 1000;
				
				if crawler.shaderParameterComponent == 1 then
					setShaderParameter(crawler.node, crawler.shaderParameterName, crawler.scrollPosition,0,0,0, false);
				else
					setShaderParameter(crawler.node, crawler.shaderParameterName, 0,crawler.scrollPosition,0,0, false);
				end;
	
				for _, rotatingPart in pairs(crawler.rotatingParts) do
					rotate(rotatingPart.node, (rotatingPart.speedScale / 185) * (crawler.rotSpeed * 2), 0, 0);
				end;
			end;
		end;
	end;
end;

function CrawlerFix:writeUpdateStream(streamId, connection, dirtyMask)
	if not connection:getIsServer() then -- server
		if streamWriteBool(streamId, bitAND(dirtyMask, self.CrawlerFixDirtyFlag) ~= 0) then
			for _, crawler in ipairs(self.crawlers) do
				streamWriteFloat32(streamId, crawler.scrollPosition);
				streamWriteFloat32(streamId, crawler.rotSpeed * 1000);
			end;
		end;
	end;
end;

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

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

function CrawlerFix:update(dt)
	if self:getIsActive() and self.isServer then
		if self.crawlerHasWheelId ~= nil and self.crawlerHasWheelId then
			for _, crawler in pairs(self.crawlers) do
				if crawler.wheelId ~= nil then
					local wheel = self.wheels[crawler.wheelId];
					local axleSpeed = getWheelShapeAxleSpeed(wheel.node, wheel.wheelShape);
					
					local movingSpeed = axleSpeed * (wheel.radius * math.pi);
					crawler.traveledDistance = crawler.traveledDistance + (movingSpeed / 100);
					crawler.movingSpeed = math.abs(movingSpeed);
					
					local movingDirection = 0;
					if crawler.traveledDistance > crawler.lastTraveledDistance then
						movingDirection = 1;
					elseif crawler.traveledDistance < crawler.lastTraveledDistance then
						movingDirection = -1;
					else
						crawler.traveledDistance = 0;
					end;
					
					crawler.lastTraveledDistance = crawler.traveledDistance;
					crawler.scrollPosition = (crawler.scrollPosition + crawler.movingSpeed * movingDirection * (crawler.scrollSpeed / 185)) % crawler.scrollLength;
					crawler.rotSpeed = crawler.movingSpeed * movingDirection;
					
					if crawler.shaderParameterComponent == 1 then
						setShaderParameter(crawler.node, crawler.shaderParameterName, crawler.scrollPosition,0,0,0, false);
					else
						setShaderParameter(crawler.node, crawler.shaderParameterName, 0,crawler.scrollPosition,0,0, false);
					end;
		
					for _, rotatingPart in pairs(crawler.rotatingParts) do
						rotate(rotatingPart.node, (rotatingPart.speedScale / 185) * crawler.rotSpeed, 0, 0);
					end;
					
					if crawler.scrollPosition ~= crawler.sentScrollPosition and crawler.rotSpeed ~= crawler.sentRotSpeed then
						crawler.sentScrollPosition = crawler.scrollPosition;
						crawler.sentRotSpeed = crawler.rotSpeed;
						
						self:raiseDirtyFlags(self.CrawlerFixDirtyFlag);
					end;
				end;
			end;
		end;
	end;
end;

function CrawlerFix:updateTick(dt)
end;

function CrawlerFix:draw()
end;



if not Utils.crawlerFixApplied20150214 then
	Utils.crawlerFixApplied20150214 = true;
	
	local oldCrawlerFunc = Crawler.update;
	Crawler.update = function(self, dt)
		if not self.crawlerHasWheelId then
			oldCrawlerFunc(self, dt);
		end;
	end;
end;