-- Specialisation which sets the visibility of hydraulics
-- @ author: rafftnix
-- @ date: 29.07.2013

SetHydraulicsVisibility = {};

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

function SetHydraulicsVisibility:load(xmlFile)
--print("function SetHydraulicsVisibility:load(xmlFile)");
	self.setHydState = SpecializationUtil.callSpecializationsFunction("setHydState");
	self.getIsHydTaken = SetHydraulicsVisibility.getIsHydTaken;

	self.frontHydActive = true;
	self.rearHydActive = true;
	
	self.frontAttacherDescIndex = getXMLInt(xmlFile, "vehicle.attachableHydraulics.frontHydraulic#attacherJointDescIndex");
	self.rearAttacherDescIndex = getXMLInt(xmlFile, "vehicle.attachableHydraulics.rearHydraulic#attacherJointDescIndex");
	
	self.frontTrailerDescIndex = getXMLInt(xmlFile, "vehicle.attachableHydraulics.frontHydraulic#trailerDescIndex");
	self.frontTrailerLowDescIndex = getXMLInt(xmlFile, "vehicle.attachableHydraulics.frontHydraulic#trailerLowDescIndex");
	
	self.frontTrailerDesc = self.attacherJoints[self.frontTrailerDescIndex];
	self.frontTrailerLowDesc = self.attacherJoints[self.frontTrailerLowDescIndex];
	
	self.frontTrailerDesc.oldPos = { getTranslation(self.frontTrailerDesc.jointTransform) }
	self.frontTrailerLowDesc.oldPos = { getTranslation(self.frontTrailerLowDesc.jointTransform) }
	
	self.frontHydDesc = self.attacherJoints[self.frontAttacherDescIndex];
	self.rearHydDesc = self.attacherJoints[self.rearAttacherDescIndex];
	
	self.frontHydDesc.oldPos = { getTranslation(self.frontHydDesc.jointTransform) }
	self.rearHydDesc.oldPos = { getTranslation(self.rearHydDesc.jointTransform) }
	
	self.frontHyd = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attachableHydraulics.frontHydraulic#index"));
	self.rearHyd = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attachableHydraulics.rearHydraulic#index"));
	
	self.showFillWarnTime = 0;
	self.showHydraulicWarnTime = 0;
end;

function SetHydraulicsVisibility:readStream(streamId, connection)
	local frontHydActive = streamReadBool(streamId);
	local rearHydActive = streamReadBool(streamId);
	self:setHydState(frontHydActive, rearHydActive, true);
end;

function SetHydraulicsVisibility:writeStream(streamId, connection)
	streamWriteBool(streamId, self.frontHydActive);
	streamWriteBool(streamId, self.rearHydActive);
end;

function SetHydraulicsVisibility:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	--if not resetVehicles then
		local frontHydActive = getXMLBool(xmlFile, key.."#frontHydActive");
		local rearHydActive = getXMLBool(xmlFile, key.."#rearHydActive");
		self:setHydState(frontHydActive, rearHydActive, true);
	--end;

	return BaseMission.VEHICLE_LOAD_OK;
end;

function SetHydraulicsVisibility:getSaveAttributesAndNodes(nodeIdent)	
	local attributes = 'frontHydActive="' .. tostring(self.frontHydActive) .. '" ';
	attributes = attributes .. 'rearHydActive="' .. tostring(self.rearHydActive) .. '"';
	return attributes, "";
end;

function SetHydraulicsVisibility:delete()
  
end;

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

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

function SetHydraulicsVisibility:update(dt)
	if not self:getIsActive() or self:getIsActive() then
        if self.playerInRangeFrontHyd then
		    if InputBinding.hasEvent(InputBinding.FRONTHYDRAULIC) and table.getn(self.attachedImplements) == 0 then
			    self:setHydState(not self.frontHydActive, self.rearHydActive);
		    end;
		    if InputBinding.hasEvent(InputBinding.FRONTHYDRAULIC) and table.getn(self.attachedImplements) > 0 then
                self.showHydraulicWarnTime = g_currentMission.time + 3000;
            end;
        
            if self.frontHydActive then
			    g_currentMission:addHelpButtonText(g_i18n:getText("detachFrontHydraulic"), InputBinding.FRONTHYDRAULIC);
		    else
			    g_currentMission:addHelpButtonText(g_i18n:getText("attachFrontHydraulic"), InputBinding.FRONTHYDRAULIC);
		    end;
        end;
        
        if self.playerInRangeRearHyd then
		    if InputBinding.hasEvent(InputBinding.REARHYDRAULIC) and self.fillLevel == 0 and table.getn(self.attachedImplements) == 0 then
			    self:setHydState(self.frontHydActive, not self.rearHydActive);
		    end;
		    if InputBinding.hasEvent(InputBinding.REARHYDRAULIC) and self.fillLevel > 0 then
                self.showFillWarnTime = g_currentMission.time + 3000;
                --g_currentMission.inGameMessage:showMessage(g_i18n:getText("attention"), g_i18n:getText("warning_fillLevel"), 5000, false);
            end;
        
            if InputBinding.hasEvent(InputBinding.REARHYDRAULIC) and table.getn(self.attachedImplements) > 0 then
                self.showHydraulicWarnTime = g_currentMission.time + 3000;
            end;
            if self.rearHydActive then
			    g_currentMission:addHelpButtonText(g_i18n:getText("detachRearHydraulic"), InputBinding.REARHYDRAULIC);
		    else
			    g_currentMission:addHelpButtonText(g_i18n:getText("attachRearHydraulic"), InputBinding.REARHYDRAULIC);
		    end;
		end;
		
        if self.showFillWarnTime > g_currentMission.time then
		    g_currentMission:addWarning(g_i18n:getText("warning_fillLevel"), 0, 0.03);
	    end;

	    if self.showHydraulicWarnTime > g_currentMission.time then
		    g_currentMission:addWarning(g_i18n:getText("detachAllVehicles"), 0, 0.03);
	    end;
	end;
end;

function SetHydraulicsVisibility:updateTick(dt)
	if g_currentMission.player ~= nil and self.frontHyd ~= nil then
		local nearestDistance = 2.0;
		local fx1,fy1,fz1 = getWorldTranslation(self.frontHyd);
		local x2,y2,z2 = getWorldTranslation(g_currentMission.player.rootNode);
		local distanceFront = Utils.vector3Length(fx1-x2,fy1-y2,fz1-z2);
		if distanceFront < nearestDistance then
			self.playerInRangeFrontHyd = true;
		else
			self.playerInRangeFrontHyd = false;
		end;
	end;
	
	if g_currentMission.player ~= nil and self.rearHyd ~= nil then
		local nearestDistance = 2.0;
		local rx1,ry1,rz1 = getWorldTranslation(self.rearHyd);
		local x2,y2,z2 = getWorldTranslation(g_currentMission.player.rootNode);
		local distanceRear = Utils.vector3Length(rx1-x2,ry1-y2,rz1-z2);
		if distanceRear < nearestDistance then
			self.playerInRangeRearHyd = true;
		else
			self.playerInRangeRearHyd = false;
		end;
	end;
end;

function SetHydraulicsVisibility:draw()
end;

function SetHydraulicsVisibility:setHydState(frontHydActive, rearHydActive, noEventSend)
	setVisibility(self.frontHyd, frontHydActive);
	setVisibility(self.rearHyd, rearHydActive);
	
	if self.frontHydActive ~= frontHydActive then
		if frontHydActive then
			setTranslation(self.frontHydDesc.jointTransform, unpack(self.frontHydDesc.oldPos));
			setTranslation(self.frontTrailerDesc.jointTransform, 20000, 20000, 20000);
			setTranslation(self.frontTrailerLowDesc.jointTransform, 20000, 20000, 20000);
		else
			setTranslation(self.frontHydDesc.jointTransform, 20000, 20000, 20000);
			setTranslation(self.frontTrailerDesc.jointTransform, unpack(self.frontTrailerDesc.oldPos));
			setTranslation(self.frontTrailerLowDesc.jointTransform, unpack(self.frontTrailerLowDesc.oldPos));
		end;
	end;
	
	if self.rearHydActive ~= rearHydActive then
		if rearHydActive then
			setTranslation(self.rearHydDesc.jointTransform, unpack(self.rearHydDesc.oldPos));
		else
			setTranslation(self.rearHydDesc.jointTransform, 20000, 20000, 20000);
		end;
	end;
	
	self.frontHydActive = frontHydActive;
	self.rearHydActive = rearHydActive;

	if not noEventSend then
		SetHydraulicsVisibilityEvent.sendEvent(self, frontHydActive, rearHydActive);
	end;
end;

SetHydraulicsVisibilityEvent = {};
SetHydraulicsVisibilityEvent_mt = Class(SetHydraulicsVisibilityEvent, Event);
InitEventClass(SetHydraulicsVisibilityEvent, "SetHydraulicsVisibilityEvent");
function SetHydraulicsVisibilityEvent:emptyNew()
    local self = Event:new(SetHydraulicsVisibilityEvent_mt);
    self.className="SetHydraulicsVisibilityEvent";
    return self;
end;

function SetHydraulicsVisibilityEvent:new(object, frontHydActive, rearHydActive)
    local self = SetHydraulicsVisibilityEvent:emptyNew(); 
    self.object = object; 
	self.frontHydActive = frontHydActive;
	self.rearHydActive = rearHydActive;
    return self;
end;

function SetHydraulicsVisibilityEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.object));
    streamWriteBool(streamId, self.frontHydActive);
	streamWriteBool(streamId, self.rearHydActive);
end;

function SetHydraulicsVisibilityEvent:readStream(streamId, connection)
    self.object = networkGetObject(streamReadInt32(streamId));
    self.frontHydActive = streamReadBool(streamId);
	self.rearHydActive = streamReadBool(streamId);
    self:run(connection);
end;

function SetHydraulicsVisibilityEvent:run(connection)
	self.object:setHydState(self.frontHydActive, self.rearHydActive, true);
	if not connection:getIsServer() then
		g_server:broadcastEvent(SetHydraulicsVisibilityEvent:new(self.object, self.frontHydActive, self.rearHydActive), nil, connection, self.object);
	end; 
end;

function SetHydraulicsVisibilityEvent.sendEvent(object, frontHydActive, rearHydActive)
	if g_server ~= nil then   
		g_server:broadcastEvent(SetHydraulicsVisibilityEvent:new(object, frontHydActive, rearHydActive), nil, nil, object); 
	else  
		g_client:getServerConnection():sendEvent(SetHydraulicsVisibilityEvent:new(object, frontHydActive, rearHydActive)); 
	end;
end;