--
-- manualPipe Specialization for Combines
-- This Specialization lets you choose if you want to unload or not. It also enables the beaconlights a 80%.
--
-- @author  Knagsted
-- @date  16/07/10
-- @edit and almost completely rewritten  Michi77 FS13 ready, bugfixes
-- @date  27/08/13
-- @date  27/08/13 MP-Ready
--


manualPipe = {};

function manualPipe.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Combine, specializations);
end;

function manualPipe:load(xmlFile)

	self.setPipeRaycastDistance = SpecializationUtil.callSpecializationsFunction("setPipeRaycastDistance");
	self.setManualUnloading = SpecializationUtil.callSpecializationsFunction("setManualUnloading");
    self.myPipe = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.myPipe#index"));
	self.pipeMaxX = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipe#maxRotX"), 10);
	self.pipeMaxY = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipe#maxRotY"), -90);
	self.pipeRotationSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipe#pipeRotationSpeed"), 0.0006);
    self.pipeFlapLid = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pipeFlapLid#index"));
	
	self.pipeOutLight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pipeOutLight#index"));
	self.showPipeOutLight = false;

	self.pipeOnLight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pipeOnLight#index"));
	self.showPipeOnLight = false;
	
	self.tankFullLight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.tankFullLight#index"));
	self.showTankFullLight = false;
	
	--Sounds
	UnloadSoundFile = Utils.getFilename("unload.wav", self.baseDirectory);
    self.UnloadSoundId = createSample("unload");
    loadSample(self.UnloadSoundId, UnloadSoundFile, false);
    self.UnloadPlaying = false;
	self.UnloadSoundOffset = getSampleDuration(self.UnloadSoundId);
	
	GrainTankFullSoundFile = Utils.getFilename("actionSound.wav", self.baseDirectory);
    self.GrainTankFullSoundId = createSample("actionSound");
    loadSample(self.GrainTankFullSoundId, GrainTankFullSoundFile, false);
    self.GrainTankFullPlaying = false;
	self.GrainTankFullSoundOffset = getSampleDuration(self.GrainTankFullSoundId);
	self.playGrainTankFull = false;
	
	self.manualUnloading = false;
	self.wasThreshing = false;
	self.pipeRaycastDistance = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipe#raycastDistance"));
	self.pipeRaycastDistanceOrig = self.pipeRaycastDistance;
	self.pipeRaycastDistance = 0.1;
	-- {}
	self.beacon = false;
end;

function manualPipe:delete()
	if self.UnloadPlaying ~= nil then
		stopSample(self.UnloadSoundId);
	end;
	
	if self.GrainTankFullPlaying ~= nil then
		stopSample(self.GrainTankFullSoundId);
	end;
end;

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

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

function manualPipe:readStream(streamId, connection)
     local manualUnloading = streamReadBool(streamId)
	 self:setManualUnloading(manualUnloading, true);
end;

function manualPipe:writeStream(streamId, connection)   
	streamWriteBool(streamId, self.manualUnloading);
end;

function manualPipe:update(dt)
	if self.isEntered then
		if self.pipeOpen and self.getIsPipeUnloadingAllowed then
			if not self.isAIThreshing and self.pipeOpen and self.grainTankFillLevel > 0 then
				if self:getIsActive() and self:getIsActiveForInput(false) and not self:hasInputConflictWithSelection() and InputBinding.hasEvent(InputBinding.ACTIVATE_UNLOADING) then
					self:setManualUnloading()
					if self.UnloadSoundId ~= nil then
						playSample(self.UnloadSoundId, 1, 0.7, 0);
					end;
				end;
			end;
		end;
		
		if self.grainTankFillLevel >= self.grainTankCapacity * 0.8 then
			if not self.GrainTankFullPlaying then
				self.playGrainTankFull = true;
			elseif not self.wasThreshing and self.isThreshing then
				self.GrainTankFullPlaying = false;
				self.playGrainTankFull = true;
			end;
			self.showTankFullLight = true;
		else
			self.GrainTankFullPlaying = false;
			self.playGrainTankFull = false;
			self.showTankFullLight = false;
		end;
	end;
	if self.isAIThreshing and not self.manualUnloading then
		self:setManualUnloading()
	end;
	
	if self.isEntered then
		local trailer, trailerDistance = self:findTrailerToUnload(self.currentGrainTankFruitType);
		if trailer == nil and self.manualUnloading then
			self:setManualUnloading()
		end;
	end;
	
	if self.grainTankFillLevel > self.grainTankCapacity * 0.8 and not self.beaconLightsActive then
		self.beacon = true
		self:setBeaconLightsVisibility(true);
	end;
	if self.grainTankFillLevel < self.grainTankCapacity * 0.8 and self.beacon then
		self:setBeaconLightsVisibility(false);
		self.beacon = false
	end;
	
	if self.tankFullLight ~= nil then
		setVisibility(self.tankFullLight, self.showTankFullLight);
	end;
	
	if self.playGrainTankFull then
		if self.GrainTankFullSoundId ~= nil and not self.GrainTankFullPlaying then
			playSample(self.GrainTankFullSoundId, 1, 0.9, 0);
			self.GrainTankFullPlaying = true;
			self.playGrainTankFull = false;
		end;
	end;
	
	if self.manualUnloading then
		self.showPipeOnLight = true;
	else
		self.showPipeOnLight = false;
	end;
	if self.pipeOnLight ~= nil then
		setVisibility(self.pipeOnLight, self.showPipeOnLight);
	end;
	
--[[	if self.manualUnloading then
		self.pipeRaycastDistance = pipeDistance;
	end
	if not self.manualUnloading then
		self.pipeRaycastDistance = 0.1;
	end
--]]

	if not self.isAIThreshing then
		if self.pipeOpen then
			if self.grainTankFillLevel > 0 then
				if self.grainTankFillLevel <= 0.0 then
				   self.grainTankFillLevel = 0.0;
				end;
			else
				self.myPipeParticleActivated = false;
			end;
		end;
		
		if self.currentGrainTankFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
			if self.currentManualPipeParticleSystem ~= nil then
				Utils.setEmittingState(self.currentManualPipeParticleSystem, false);
			end;
			if self.myPipeParticleActivated and self.currentGrainTankFruitType ~= nil then
				self.currentManualPipeParticleSystem = self.pipeParticleSystems[self.currentGrainTankFruitType];
				if self.currentManualPipeParticleSystem == nil then
					self.currentManualPipeParticleSystem = self.defaultPipeParticleSystem;
				end;
				Utils.setEmittingState(self.currentManualPipeParticleSystem, true);
			end;
		else
			if self.currentManualPipeParticleSystem ~= nil then
				Utils.setEmittingState(self.currentManualPipeParticleSystem, false);
			end;
		end;
	end;
		
	local x,y,z = getRotation(self.myPipe);
	if y < 0 and y > Utils.degToRad(-89) then
		self.pipeOpening = true;
	elseif y < Utils.degToRad(-89) then
		self.pipeOpen = true;
	else
		self.pipeOpen = false
		self.pipeOpening = false;
	end;
	
	if not self.pipeOpening then
		self.showPipeOutLight = false;
	else
		self.showPipeOutLight = true;
	end;
	if self.pipeOutLight ~= nil then
		setVisibility(self.pipeOutLight, self.showPipeOutLight);
	end;
	
	self.wasThreshing = self.isThreshing;
--[[if self:getIsActive() and self:getIsActiveForInput(false) and not self:hasInputConflictWithSelection() and InputBinding.hasEvent(InputBinding.DEBUG) then
		print(self.pipeRaycastDistance);
		print(self.manualUnloading);
	end; --]]
end;

function manualPipe:setManualUnloading(manualUnloading, noEventSend)
	if manualUnload == nil then
		self.manualUnloading = not self.manualUnloading
	else
		self.manualUnloading = manualUnload
	end;
	
	if self.manualUnloading then
		self.pipeRaycastDistance = self.pipeRaycastDistanceOrig; 
	else
		self.pipeRaycastDistance = 0.1;
	end;
	manualPipeEvent.sendEvent(self, self.manualUnloading, noEventSend);
end;

function manualPipe:draw()
	if self.pipeOpen and self.manualUnloading then
        g_currentMission:addHelpButtonText(g_i18n:getText("Stopdumpinggrain"), InputBinding.ACTIVATE_UNLOADING);
    elseif self.pipeOpen and not self.manualUnloading then
        g_currentMission:addHelpButtonText(g_i18n:getText("Startdumpinggrain"), InputBinding.ACTIVATE_UNLOADING);
    end;
end;

-- Event


manualPipeEvent = {};
manualPipeEvent_mt = Class(manualPipeEvent, Event);

InitEventClass(manualPipeEvent, "manualPipeEvent");

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

function manualPipeEvent:new(vehicle, manualUnloading, streamId)
	local self = manualPipeEvent:emptyNew()
	self.vehicle = vehicle;
	self.manualUnloading = manualUnloading;
	return self;
end;

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

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

function manualPipeEvent:run(connection)
	self.vehicle:setManualUnloading(self.manualUnloading, true);
	if not connection:getIsServer() then
		g_server:broadcastEvent(manualPipeEvent:new(self.vehicle, self.manualUnloading), nil, connection, self.vehicle);
	end;
end;

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