--
-- LeverAnimation
-- Specialization for animating weidemann levers (rotation)
--
-- @author    PES 4ever
-- @date      29/07/11
-- @version   1.0
--
-- For support and documentation visit www.modding-society.de
-- Copyright (C) PES 4ever, All Rights Reserved.
--

LeverAnimation = {};

function LeverAnimation.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Cylindered, specializations);
end;

function LeverAnimation:load(xmlFile)

	-- Multiplayer function
	self.supportMP = Utils.getNoNil(getXMLBool(xmlFile, "levers#supportMP"), true);
	if self.supportMP then
		self.moveDirDirtyFlag = self:getNextDirtyFlag();
	end;
	
	-- Levers
	self.levers = {};
	local i = 0;
	while true do
		local baseName = string.format("vehicle.levers.lever(%d)", i);
		if not hasXMLProperty(xmlFile, baseName) then
			break;
		end;
		
		local node = Utils.indexToObject(self.components, getXMLString(xmlFile, baseName .. "#index"));		
		if node ~= nil then
		
			local axis = Utils.getNoNil(getXMLInt(xmlFile, baseName .. "#axis"), 1);
			local rot = {getRotation(node)};
		
			if math.abs(rot[axis]) < 0.01 then			
				local entry = {};
				entry.node = node;
				entry.axis = axis;
				entry.moveRot = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, baseName .. "#rot"), 0));
				entry.rotTime = Utils.getNoNil(getXMLFloat(xmlFile, baseName .. "#rotTime"), 2) * 1000;	
				entry.invert = Utils.getNoNil(getXMLBool(xmlFile, baseName .. "#invert"), false);
				entry.moveDir = 0;
				
				local number = getXMLInt(xmlFile, baseName.. "#movingToolNumber");
				if number ~= nil then
					if number >= 1 or number <= table.getn(self.movingTools) then
						entry.movingTool = self.movingTools[number];				
					else
						print("Warning: index number of moving tool in lever ".. i+1 .." does not exist in '".. self.configFileName .."'");
					end;
				end;
				
				table.insert(self.levers, entry);	
			else
				print("Error: rotation (axis " .. entry.axis .. ") of lever ".. i+1 .." is not zero in '".. self.configFileName .."'");
			end;
		end;
		
		i = i + 1;
	end;
	
end;

function LeverAnimation:delete()
end;

function LeverAnimation:readStream(streamId, connection)

	if self.supportMP then
		for _, lever in pairs(self.levers) do	
			lever.moveDir = streamReadInt8(streamId);
		end;
	end;
	
end;

function LeverAnimation:writeStream(streamId, connection)

	if self.supportMP then
		for _, lever in pairs(self.levers) do	
			streamWriteInt8(streamId, lever.moveDir);
		end;
	end;
	
end;

function LeverAnimation:readUpdateStream(streamId, connection, dirtyMask)
	
	if self.supportMP then
		local hasUpdate = streamReadBool(streamId);
		if hasUpdate then		
			for _, lever in pairs(self.levers) do	
				lever.moveDir = streamReadInt8(streamId);
			end;
			--if not connection:getIsServer() then
				-- we are on the server, write the data to the clients
				--self:raiseDirtyFlags(self.moveDirDirtyFlag);
			--end;
		end;
	end;
	
end;
   
function LeverAnimation:writeUpdateStream(streamId, connection, dirtyMask)

	if self.supportMP then
		if bitAND(dirtyMask, self.moveDirDirtyFlag) ~= 0 and (connection:getIsServer() or connection ~= self.owner) then
			-- either we are on the client, or the target connection is not the owner
			streamWriteBool(streamId, true);		
			for _, lever in pairs(self.levers) do
				streamWriteInt8(streamId, lever.moveDir);
			end;
		else
			streamWriteBool(streamId, false);
		end;
	end;
	
end;

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

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

function LeverAnimation:update(dt)	
end;

function LeverAnimation:updateTick(dt)

	if self:getIsActive() and self.isClient then
	
		for _, lever in pairs(self.levers) do
		
			-- Check moving tools
			if self:getIsActive() then				
				local tool = lever.movingTool;
				if tool ~= nil then
					if tool.lastRotSpeed ~= 0 or tool.lastTransSpeed ~= 0 then
						if tool.lastRotSpeed > 0 or tool.lastTransSpeed > 0 then
							lever.moveDir = 1;
						elseif tool.lastRotSpeed < 0 or tool.lastTransSpeed < 0 then
							lever.moveDir = -1;
						end;	
					else
						lever.moveDir = 0;
					end;
				end;
			end;
			
			-- Lever animation
			local x, y, z = getRotation(lever.node);
			local rot = {x, y, z};
			local rotMin = {x, y, z};
			local rotMax = {x, y, z};
			local moveToMax;			
			
			-- Move to max or min
			if lever.moveDir == 1 or lever.moveDir == -1 then
				if lever.moveDir == 1 then
					moveToMax = true;
				else
					moveToMax = false;
				end;
				moveToMax = not moveToMax and lever.invert or moveToMax and not lever.invert;
				rotMin[lever.axis] = -lever.moveRot;
				rotMax[lever.axis] = lever.moveRot;
				
			-- Move to zero position
			elseif lever.moveDir == 0 then
				if rot[lever.axis] > 0 then					
					rotMin[lever.axis] = 0;
					rotMax[lever.axis] = lever.moveRot;
					moveToMax = false;
				else
					rotMin[lever.axis] = -lever.moveRot;
					rotMax[lever.axis] = 0;
					moveToMax = true;
				end;
			end;			
			
			-- Move lever
			local newRot = Utils.getMovedLimitedValues(rot, rotMax, rotMin, 3, lever.rotTime, dt, not moveToMax);
			setRotation(lever.node, unpack(newRot));
			
			-- Multiplayer
			if self.supportMP then
				if lever.moveDir ~= lever.sentMoveDir then
					self:raiseDirtyFlags(self.moveDirDirtyFlag);
					lever.sentMoveDir = lever.moveDir;
				end;
			end;
			
        end;
	end;
	
end;

function LeverAnimation:draw()
end;