--
-- Pilmet
-- author: Burner
-- 

Pilmet = {};

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

function Pilmet:load(xmlFile)
	self.itemInRange = Pilmet.itemInRange;
	self.setTarpaulin = SpecializationUtil.callSpecializationsFunction("setTarpaulin");
	
	self.tarpaulinActive = true;
	self.tarpaulinNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.tarpaulin#index"));
end;

function Pilmet:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'tarpaulin="'.. tostring(self.tarpaulinActive) ..'"';
	return attributes, nil;
end;

function Pilmet:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then
		local tarpaulin = Utils.getNoNil(getXMLBool(xmlFile, key.."#tarpaulin"), true);
		--if tarpaulin == true then
			self:setTarpaulin(tarpaulin);
		--end;
	end;
	return BaseMission.VEHICLE_LOAD_OK;
end;

function Pilmet:delete()
end;

function Pilmet:readStream(streamId, connection)
	self:setTarpaulin(streamReadBool(streamId), true);
end;

function Pilmet:writeStream(streamId, connection)
	streamWriteBool(streamId, self.tarpaulinActive);
end;
	
function Pilmet:delete()
end;

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

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

function Pilmet:update(dt)
	if self:itemInRange(self.tarpaulinNode) then
		if self.animationParts[1].clipStartTime and self.animationParts[2].clipStartTime then
			if InputBinding.hasEvent(InputBinding.Pilmet_MountTarpaulin) then
				self:setTarpaulin(not self.tarpaulinActive);
			end;
			if self.tarpaulinActive then
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("Pilmet_UnmountTarpaulin")), InputBinding.Pilmet_MountTarpaulin);
			else
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("Pilmet_MountTarpaulin")), InputBinding.Pilmet_MountTarpaulin);
			end;
		else
			g_currentMission:addExtraPrintText(g_i18n:getText("Pilmet_TarpaulinInfo"));
		end;
	end;
	
	if self:itemInRange(self.animationParts[1].rootNode) then
		if self.tarpaulinActive then
			g_currentMission:addExtraPrintText(g_i18n:getText("Pilmet_TarpaulinInfo2"));
		else
			if self.animationParts[2].clipStartTime or (self.animationParts[1].clipStartTime and self.animationParts[2].clipEndTime) then
				if self.animationParts[1].clipStartTime then
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("Pilmet_UnfoldArm")), InputBinding.Pilmet_FoldArm);
				else
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("Pilmet_FoldArm")), InputBinding.Pilmet_FoldArm);
				end;
			end;
			if self.animationParts[2].clipStartTime or (self.animationParts[1].clipStartTime and self.animationParts[2].clipEndTime) then
				if InputBinding.hasEvent(InputBinding.Pilmet_FoldArm) then
					if self.animationParts[1].clipEndTime then
						self:setAnimationTime(1, self.animationParts[1].startPosition);
						self:setAnimationTime(4, self.animationParts[4].startPosition);
					elseif self.animationParts[1].clipStartTime then
						self:setAnimationTime(1, self.animationParts[1].animDuration);
					end;
				end;
			end;
		end;
	elseif self:itemInRange(self.animationParts[2].rootNode) then
		if self.tarpaulinActive then
			g_currentMission:addExtraPrintText(g_i18n:getText("Pilmet_TarpaulinInfo2"));
		else
			if self.animationParts[1].clipEndTime or (self.animationParts[1].clipEndTime and self.animationParts[2].clipStartTime) then
				if self.animationParts[2].clipStartTime then
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("Pilmet_UnfoldArm")), InputBinding.Pilmet_FoldArm);
				else
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("Pilmet_FoldArm")), InputBinding.Pilmet_FoldArm);
				end;
			end;
		
			if self.animationParts[1].clipEndTime or (self.animationParts[1].clipEndTime and self.animationParts[2].clipStartTime) then
				if InputBinding.hasEvent(InputBinding.Pilmet_FoldArm) then
					if self.animationParts[2].clipEndTime then
						self:setAnimationTime(2, self.animationParts[2].startPosition);
						self:setAnimationTime(5, self.animationParts[5].startPosition);
					elseif self.animationParts[2].clipStartTime then
						self:setAnimationTime(2, self.animationParts[2].animDuration);
					end;
				end;
			end;
		end;
	elseif self:itemInRange(self.animationParts[4].rootNode) then
		if self.animationParts[1].clipEndTime then
			if self.animationParts[4].clipStartTime then
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("Pilmet_UnfoldArm")), InputBinding.Pilmet_FoldArm);
			else
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("Pilmet_FoldArm")), InputBinding.Pilmet_FoldArm);
			end;
			if InputBinding.hasEvent(InputBinding.Pilmet_FoldArm) then
				if self.animationParts[4].clipEndTime then
					self:setAnimationTime(4, self.animationParts[4].startPosition);
				elseif self.animationParts[4].clipStartTime then
					self:setAnimationTime(4, self.animationParts[4].animDuration);
				end;
			end;
		end;
	elseif self:itemInRange(self.animationParts[5].rootNode) then
		 if self.animationParts[2].clipEndTime then
			if self.animationParts[5].clipStartTime then
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("Pilmet_UnfoldArm")), InputBinding.Pilmet_FoldArm);
			else
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("Pilmet_FoldArm")), InputBinding.Pilmet_FoldArm);
			end;
			if InputBinding.hasEvent(InputBinding.Pilmet_FoldArm) then
				if self.animationParts[5].clipEndTime then
					self:setAnimationTime(5, self.animationParts[5].startPosition);
				elseif self.animationParts[5].clipStartTime then
					self:setAnimationTime(5, self.animationParts[5].animDuration);
				end;
			end;
		end;
	end;
	
	if self:itemInRange(self.animationParts[6].rootNode) then
		if self.tarpaulinActive == false then
			if InputBinding.isPressed(InputBinding.Pilmet_ArmUp) then
				self:setAnimationTime(6, self.animationParts[6].currentPosition+(self.animationParts[6].offSet+dt), false);
			elseif InputBinding.isPressed(InputBinding.Pilmet_ArmDown) then
				self:setAnimationTime(6, self.animationParts[6].currentPosition-(self.animationParts[6].offSet+dt), false);
			end;
			g_currentMission:addExtraPrintText(string.format(""..InputBinding.getKeyNamesOfDigitalAction(InputBinding.Pilmet_ArmUp) .. "/" .. InputBinding.getKeyNamesOfDigitalAction(InputBinding.Pilmet_ArmDown)..": "..g_i18n:getText("Pilmet_ArmUp")..""));
		end;
	end;

	if self.setAnimationTime ~= nil then
		if self.isTurnedOn then
			self:setAnimationTime(3, 1);
		else
			self:setAnimationTime(3, 0);
		end;
	end;
end;

function Pilmet:updateTick(dt)
	if self.tarpaulinNode ~= nil then
		setVisibility(self.tarpaulinNode, self.tarpaulinActive);
	end;
end;
	
function Pilmet:draw()
end;

function Pilmet:onAttach(attacherVehicle)
	self:setTarpaulin(false);
end;

function Pilmet:onDetach()
end;

function Pilmet:onLeave() 
end;

function Pilmet:onDeactivate()
end;

function Pilmet:itemInRange(object)
	if g_currentMission.player ~= nil and object ~= nil then
		local nearestDistance = 2;
		local vx, vy, vz = getWorldTranslation(g_currentMission.player.rootNode);
		local px, py, pz = getWorldTranslation(object); 
		local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);	
		if distance < nearestDistance then
			return true;
		else
			return false;
		end;
	else
		return false;
	end;
end;

function Pilmet:setTarpaulin(tarpaulinActive,noEventSend)
	SetTarpaulinStateEvent.sendEvent(self, tarpaulinActive, noEventSend);
	self.tarpaulinActive = tarpaulinActive;
end;

SetTarpaulinStateEvent = {};
SetTarpaulinStateEvent_mt = Class(SetTarpaulinStateEvent, Event);

InitEventClass(SetTarpaulinStateEvent, "SetTarpaulinStateEvent");

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

function SetTarpaulinStateEvent:new(vehicle, tarpaulinState)
    local self = SetTarpaulinStateEvent:emptyNew()
    self.vehicle = vehicle;
	self.tarpaulinState = tarpaulinState;
    return self;
end;

function SetTarpaulinStateEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
	self.tarpaulinState = streamReadBool(streamId);
    self.vehicle = networkGetObject(id);
    self:run(connection);
end;

function SetTarpaulinStateEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteBool(streamId, self.tarpaulinState);
end;

function SetTarpaulinStateEvent:run(connection)   
	self.vehicle:setTarpaulin(self.tarpaulinState, true);
    if not connection:getIsServer() then
        g_server:broadcastEvent(SetTarpaulinStateEvent:new(self.vehicle, self.tarpaulinState), nil, connection, self.vehicle);
    end;
end;

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