--
-- ManualHydraulics
-- Specialization for manual hydraulic dependent on movingTool
--
-- @author  Stefan Maurus	
-- @date  2015-04-04

-- Copyright © Stefan Maurus, www.stefanmaurus.de

ManualHydraulics = {};

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

function ManualHydraulics:load(xmlFile)
	self.manualHydraulics = {};
	self.manualHydraulics.mt = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.manualHydraulics#movingTool"));
	self.manualHydraulics.min = getXMLFloat(xmlFile, "vehicle.manualHydraulics#minDistance");
	self.manualHydraulics.max = getXMLFloat(xmlFile, "vehicle.manualHydraulics#maxDistance");	
	self.manualHydraulics.uAA = false;
	
	self.setAlphas = SpecializationUtil.callSpecializationsFunction("setAlphas");
	
	self.currentLowerAlpha = 0;
	self.currentUpperAlpha = 0;
end;

function ManualHydraulics:delete()
end;

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

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

function ManualHydraulics:readStream(streamId, connection)
	self:setAlphas(streamReadFloat32(streamId), streamReadFloat32(streamId), true);
end;

function ManualHydraulics:writeStream(streamId, connection) 	
	streamWriteFloat32(streamId, self.currentLowerAlpha); 
	streamWriteFloat32(streamId, self.currentUpperAlpha); 
end;

function ManualHydraulics:setAlphas(lower, upper, noEventSend)
	local jointdesc;
	
	if self.attacherVehicle ~= nil then
		for _, implement in pairs(self.attacherVehicle.attachedImplements) do
			if implement.object == self then
				jointDesc = self.attacherVehicle.attacherJoints[implement.jointDescIndex];
			end;
		end;
	end;
	
	if jointDesc ~= nil then
		jointDesc.lowerAlpha = lower;
		jointDesc.upperAlpha = upper;
		
		self.currentLowerAlpha = lower;
		self.currentUpperAlpha = upper;
	end;
	
	SetAlphasEvent.sendEvent(self, lower, upper, noEventSend);	
end;

function ManualHydraulics:update(dt)
end;

function ManualHydraulics:updateTick(dt)
	if self.nodesToMovingTools[self.manualHydraulics.mt].lastRotSpeed ~= 0 or self.manualHydraulics.uAA then
		local x, y, z = getRotation(self.nodesToMovingTools[self.manualHydraulics.mt].node);
		local t = 1-math.abs(math.max(math.min((x-self.nodesToMovingTools[self.manualHydraulics.mt].rotMin)/(self.nodesToMovingTools[self.manualHydraulics.mt].rotMax-self.nodesToMovingTools[self.manualHydraulics.mt].rotMin), 1), 0));
		if self.attacherVehicle ~= nil then
			for _, implement in pairs(self.attacherVehicle.attachedImplements) do
				if implement.object == self then
					local smax = self.manualHydraulics.max;
					local smin = self.manualHydraulics.min;
					self:setAlphas((smax-smin)*t+smin, (smax-smin)*t+smin);
					if self.manualHydraulics.uAA then
						self.manualHydraulics.uAA = false;
					end;
				end;
			end;
		end;
	end;
end;

function ManualHydraulics:draw()
	g_currentMission:addExtraPrintText(g_i18n:getText("HYDRAULICS_VIA_MOUSECONTROL"));
end;

function ManualHydraulics:onAttach()
	self.manualHydraulics.uAA = true;
end;

SetAlphasEvent = {};
SetAlphasEvent_mt = Class(SetAlphasEvent, Event);

InitEventClass(SetAlphasEvent, "SetAlphasEvent");

function SetAlphasEvent:emptyNew()
    local self = Event:new(SetAlphasEvent_mt);
    self.className="SetAlphasEvent";
    return self;
end;

function SetAlphasEvent:new(vehicle, upper, lower)
    local self = SetAlphasEvent:emptyNew()
    self.vehicle = vehicle;
	self.upper = upper;
	self.lower = lower;	
    return self;
end;

function SetAlphasEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
    self.vehicle = networkGetObject(id);

	self.upper = streamReadFloat32(streamId);
	self.lower = streamReadFloat32(streamId);

	if self.vehicle ~= nil then
		self.vehicle:setAlphas(self.upper, self.lower, true);
	end;
	
	if not connection:getIsServer() then
        g_server:broadcastEvent(SetAlphasEvent:new(self.vehicle, self.upper, self.lower), nil, connection, self.vehicle);
    end;
end;

function SetAlphasEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteFloat32(streamId, self.upper); 
	streamWriteFloat32(streamId, self.lower); 	
end;

function SetAlphasEvent.sendEvent(vehicle, upper, lower, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then
			g_server:broadcastEvent(SetAlphasEvent:new(vehicle, upper, lower), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(SetAlphasEvent:new(vehicle, upper, lower));
		end;
	end;
end;