--
-- AlternativeTippingCombine
--
-- @author:    	Xentro (www.fs-uk.com)(Marcus@Xentro.se)
-- @version:    v1.0
-- @date:       2013-05-12
--
--

AlternativeTippingCombine = {};

function AlternativeTippingCombine:load(xmlFile)
	self.findTipPointToUnload = AlternativeTippingCombine.findTipPointToUnload;
	
	local node = getXMLString(xmlFile, "vehicle.alternativeTipping#triggerPlacement");
	
	if node ~= nil then
		self.triggerPlacement = Utils.indexToObject(self.components, node);
	else
		self.triggerPlacement = self.pipeRaycastNode;
	end;
end;
Combine.load = Utils.appendedFunction(Combine.load, AlternativeTippingCombine.load);

function AlternativeTippingCombine:update(dt)
	if g_currentMission.alternativeTipTrigger ~= nil and self.triggerPlacement ~= nil then
		if self:getIsActive() then
			if self:getIsActiveForInput(false) then
				if self.movingDirection == 0 and not self.pipeIsUnloading and self.grainTankFillLevel > 0 and self.pipeStateIsUnloading[self.currentPipeState] and self:getIsPipeUnloadingAllowed() then
					local grainTankFillType = FruitUtil.fruitTypeToFillType[self.currentGrainTankFruitType];
					
					if g_currentMission.alternativeTipTrigger:isCombineFruitAllowed(grainTankFillType) then
						if g_currentMission.alternativeTipTrigger:getTriggerByFilltype(Fillable.fillTypeIntToName[grainTankFillType]) ~= nil then
							local allowed = true;
							for _, trigger in pairs(g_currentMission.tipTriggers) do
								if trigger.isExtendedTrigger and trigger.currentFillType ~= FruitUtil.fruitTypeToFillType[self.currentGrainTankFruitType] then
									local x1, y1, z1 = getWorldTranslation(self.triggerPlacement);
									local x2, y2, z2 = getWorldTranslation(trigger.triggerId);
									--************************************  DURAL *************************************
									--do not compute y distance because triggerPlacement can be relatively high compare to ground level (especially for combines)
									--local distance = Utils.vector3Length(x2-x1, y2-y1, z2-z1);
									local distance = Utils.vector2Length(x2-x1, z2-z1);
									if distance < g_currentMission.alternativeTipTrigger.minDistanceTriggers then
										allowed = false;
										--************************************  DURAL *************************************
										--no need to continue here ...
										break;
									end;
								end;
							end;
							
							self.isInActiveTipRange = not allowed;
							
							if InputBinding.hasEvent(InputBinding.ALTERNATIVETIPPING_START_TIPPING) then
								if allowed then
									g_currentMission.alternativeTipTrigger:addNewTrigger(self, false, AlternativeTipTrigger.COMBINE, 0, false);
								else
									self.printTriggerError = self.time + 3500;
								end;
							end;
						end;
					end;
				end;
			end;
		end;
	end;
end;
Combine.update = Utils.appendedFunction(Combine.update, AlternativeTippingCombine.update);

function AlternativeTippingCombine:updateTick(dt)
	if self:getIsActive() and not self.isAIThreshing then
		if self.pipeStateIsUnloading[self.currentPipeState] and self:getIsPipeUnloadingAllowed() and self.pipeIsUnloading then
			if self.grainTankFillLevel > 0 then
				if self.heapFound ~= nil then 
					if self.heapFound.isExtendedTrigger ~= nil and self.heapFound.isExtendedTrigger then
						self.heapFound:addCombine(self);
					end;
				end;
			end;
		end;
	end;
end;
Combine.updateTick = Utils.appendedFunction(Combine.updateTick, AlternativeTippingCombine.updateTick);

function AlternativeTippingCombine:draw()
	if self.movingDirection == 0 and g_currentMission.alternativeTipTrigger ~= nil then
		if self:getIsActiveForInput(false) then
			if not self.pipeIsUnloading and self.grainTankFillLevel > 0 and self.pipeStateIsUnloading[self.currentPipeState] and self:getIsPipeUnloadingAllowed() then
				local grainTankFillType = FruitUtil.fruitTypeToFillType[self.currentGrainTankFruitType];
				
				if g_currentMission.alternativeTipTrigger:isCombineFruitAllowed(grainTankFillType) then
					if g_currentMission.alternativeTipTrigger:getTriggerByFilltype(Fillable.fillTypeIntToName[grainTankFillType]) ~= nil then
						if not self.isInActiveTipRange then
							g_currentMission:addHelpButtonText(g_i18n:getText("ALTERNATIVETIPPING_START_TIPPING"), InputBinding.ALTERNATIVETIPPING_START_TIPPING);
						end;
					end;
				end;
			end;
			
			if self.printTriggerError ~= nil then
				if self.time < self.printTriggerError then
					g_currentMission:addWarning(g_i18n:getText("ALTERNATIVETIPPING_TIPPING_NOT_ALLOWED"), 0.018, 0.033);
				end;
			end;
		end;
	end;
end;
Combine.draw = Utils.appendedFunction(Combine.draw, AlternativeTippingCombine.draw);

function AlternativeTippingCombine:findTrailerToUnload(superFunc, fruitType)
	local trailer;
	local trailerDistance;
	
	if superFunc ~= nil then
		trailer, trailerDistance = superFunc(self, fruitType)
	end;
	
	if trailer == nil then
		local x, y, z = getWorldTranslation(self.pipeRaycastNode);
		local dx, dy, dz = localDirectionToWorld(self.pipeRaycastNode, 0,-1,0);
  
		self.heapFound = nil;
		self.heapFoundDistance = 0;
	  
		raycastAll(x, y, z, dx, dy, dz, "findTipPointToUnload", self.pipeRaycastDistance, self);
		
		if self.heapFound ~= nil and self.heapFound.getAllowShovelFillType ~= nil and self.heapFound:getAllowShovelFillType(FruitUtil.fruitTypeToFillType[fruitType]) then
			trailer = self.heapFound;
			trailerDistance = self.heapFoundDistance;
		end;
	end;
	
	return trailer, trailerDistance;
end;
Combine.findTrailerToUnload = Utils.overwrittenFunction(Combine.findTrailerToUnload, AlternativeTippingCombine.findTrailerToUnload);

function AlternativeTippingCombine:findTipPointToUnload(transformId, x, y, z, distance)
	local isValid, trigger = g_currentMission.alternativeTipTrigger:isCallbackValid(transformId);
	
	if not isValid then
		if trigger ~= nil then
			local terrainHeight = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, y, z);
			
			if y > (terrainHeight - g_currentMission.combineTerrainHeapHeightOffset) then	-- only allow unload to heaps above ground level.
				self.heapFound = trigger;
				self.heapFoundDistance = distance;
				return false;
			end;
		end;
	end;
	
	return true;
end;