AnimalDealerAbstractFunction = {};

function AnimalDealerAbstractFunction:getIsMissionOnFarmId(farmId, typVariant)
	if farmId == nil then return true;end;
	for _, mission in ipairs(g_missionManager:getMissions()) do
		if mission.farmId ~= nil and mission.farmId == farmId and mission.typVariant ~= nil and mission.typVariant == typVariant and mission.status == MissionStatus.RUNNING then
			return true, mission;
		end;
	end;
	return false;
end;

function AnimalDealerAbstractFunction:getActiveMissionOnVariant(typVariant)
	for _, mission in ipairs(g_missionManager:getMissions()) do
		if mission.farmId ~= nil and mission.typVariant ~= nil and mission.typVariant == typVariant and mission.status == MissionStatus.RUNNING then
			return mission;
		end;
	end;
	return nil;
end;

function AnimalDealerAbstractFunction:getIsMultiplayer()
	return g_currentMission ~= nil and g_currentMission.missionDynamicInfo ~= nil and g_currentMission.missionDynamicInfo.isMultiplayer;
end;

function AnimalDealerAbstractFunction:hasActiveMission(typVariants, clusterSystem)
	local data = g_missionManager:getMissionTypeDataByName(AnimalDealerMission.NAME);
	if data ~= nil and data.activeTypVariant ~= nil then		
		local activeTypVariant = {};		
		local hasActiveMission = false;
		for variant, running in pairs(data.activeTypVariant) do
			if running then			
				local isMultiplayer = AnimalDealerAbstractFunction:getIsMultiplayer();
				local farmId = nil; 
				if isMultiplayer and clusterSystem ~= nil and clusterSystem.owner ~= nil then 
					farmId = clusterSystem.owner.ownerFarmId;					
				end;				
				if typVariants == nil or type(typVariants) ~= "table" then 
					return true;
				elseif typVariants[variant] ~= nil and typVariants[variant] == true and (not isMultiplayer or AnimalDealerAbstractFunction:getIsMissionOnFarmId(farmId, variant)) then 
					hasActiveMission = true;
					activeTypVariant[variant] = true;
				end;
			end;		
		end;
		return hasActiveMission, activeTypVariant;
	end;
	return false;
end;

function AnimalDealerAbstractFunction.setName(self, superFunc, name)
	if self.name ~= nil and string.find(self.name, "ADC-") then return;end;
	superFunc(self, name);
end;
AnimalClusterHorse.setName = Utils.overwrittenFunction(AnimalClusterHorse.setName, AnimalDealerAbstractFunction.setName);

function AnimalDealerAbstractFunction:getCanBeSold(superFunc)	
	if self.name ~= nil and string.find(self.name, "ADC-") and AnimalDealerAbstractFunction:hasActiveMission({RIDINGTRANSPORT=true,RIDING=true}, self.clusterSystem) then return false;end;
	return superFunc(self);
end;
--AnimalCluster.getCanBeSold = Utils.overwrittenFunction(AnimalCluster.getCanBeSold, AnimalDealerAbstractFunction.getCanBeSold);

local orgAdcGetCanBeSoldAnimalCluster = AnimalCluster.getCanBeSold;
AnimalCluster.getCanBeSold = function(self)
	local isOkay, result = pcall(orgAdcGetCanBeSoldAnimalCluster, self)
	if isOkay and self ~= nil and result then			
		if self.name ~= nil and string.find(self.name, "ADC-") and AnimalDealerAbstractFunction:hasActiveMission({RIDINGTRANSPORT=true,RIDING=true}, self.clusterSystem) then return false;end;		
	end;
	return result;
end;

function AnimalDealerAbstractFunction:applyTarget(animalTypeIndex, itemIndex, numItems)
	local clusterId = self.targetItems[itemIndex]:getClusterId();
	local isErrorCode = AnimalSellEvent.validate(self.trailer, clusterId, numItems, 0, 0);	
	if isErrorCode == nil then
		if self.trailer ~= nil and numItems > 0 then
			local farmId = self.trailer:getOwnerFarmId();
			local isActive, activeMission = AnimalDealerAbstractFunction:getIsMissionOnFarmId(farmId, "DELIVERYANIMALS");
			if isActive and activeMission ~= nil and activeMission.setDeliveryAnimals ~= nil then
				if not AnimalDealerAbstractFunction:getIsMultiplayer() or g_currentMission:getHasPlayerPermission("tradeAnimals", self.trailer:getOwnerConnection()) then
					local cluster = self.trailer:getClusterById(clusterId);					
					activeMission:setDeliveryAnimals(cluster, animalTypeIndex, numItems);
				end;
			end;
		end;	
	end;	
end;
AnimalScreenDealerTrailer.applyTarget = Utils.prependedFunction(AnimalScreenDealerTrailer.applyTarget, AnimalDealerAbstractFunction.applyTarget);

-- function AnimalDealerAbstractFunction:applyTarget(superFunc, animalTypeIndex, itemIndex, numItems)
	-- local clusterId = self.targetItems[itemIndex]:getClusterId();
	-- local isErrorCode = AnimalSellEvent.validate(self.trailer, clusterId, numItems, 0, 0);	
	-- if isErrorCode == nil then
		-- if self.trailer ~= nil and numItems > 0 then
			-- local farmId = self.trailer:getOwnerFarmId();
			-- local isActive, activeMission = AnimalDealerAbstractFunction:getIsMissionOnFarmId(farmId, "DELIVERYANIMALS");
			-- if isActive and activeMission ~= nil and activeMission.setDeliveryAnimals ~= nil then
				-- if not AnimalDealerAbstractFunction:getIsMultiplayer() or g_currentMission:getHasPlayerPermission("tradeAnimals", self.trailer:getOwnerConnection()) then
					-- local cluster = self.trailer:getClusterById(clusterId);					
					-- activeMission:setDeliveryAnimals(cluster, animalTypeIndex, numItems);
				-- end;
			-- end;
		-- end;	
	-- end;	
	-- return superFunc(self, animalTypeIndex, itemIndex, numItems);
-- end;
-- AnimalScreenDealerTrailer.applyTarget = Utils.overwrittenFunction(AnimalScreenDealerTrailer.applyTarget, AnimalDealerAbstractFunction.applyTarget);

local orgAdcLoadAnimalLoadingTrigger = AnimalLoadingTrigger.load;
AnimalLoadingTrigger.load = function(self, node, husbandry)
	local isOkay, result = pcall(orgAdcLoadAnimalLoadingTrigger, self, node, husbandry)
	if isOkay and self ~= nil then			
		if self.isDealer then
			local isLoaded = g_additionalContractMapData:insertTypeObject("animalDealer", self, true, "trigger");			
			if isLoaded then 
				self.triggerCallback = Utils.appendedFunction(self.triggerCallback, AnimalDealerAbstractFunction.triggerCallback);
				self.mission = nil;
				self.setMission = function(mission) self.mission = mission;end;				
			end;			
		end;
	end;
	return result;
end;

local orgAdcAnimalLoadingTriggerXML = AnimalLoadingTrigger.loadFromXML;
AnimalLoadingTrigger.loadFromXML = function(self, xmlFile, key, components, i3dMappings)
	local isOkay, result = pcall(orgAdcAnimalLoadingTriggerXML, self, xmlFile, key, components, i3dMappings)
	if isOkay and self ~= nil then			
		if self.isDealer then
			local isLoaded = g_additionalContractMapData:insertTypeObject("animalDealer", self, true, "trigger");			
			if isLoaded then 
				self.triggerCallback = Utils.appendedFunction(self.triggerCallback, AnimalDealerAbstractFunction.triggerCallback);
				self.mission = nil;
				self.setMission = function(mission) self.mission = mission;end;				
			end;			
		end;
	end;
	return result;
end;

function AnimalDealerAbstractFunction:triggerCallback(triggerId, otherId, onEnter, onLeave, onStay)
	if self.isEnabled and self.mission ~= nil and (onEnter or onLeave) then
		if onEnter then
			if self.mission.objectEnteredTrigger ~= nil then self.mission:objectEnteredTrigger(self, triggerId, otherId);end;			
			return;
		elseif onLeave then
			if self.mission.objectLeaveTrigger ~= nil then self.mission:objectLeaveTrigger(self, triggerId, otherId);end;			
		end;		
	end;
end;

----
function AnimalDealerAbstractFunction:consoleGenerateMission(typVariant, animalType, numAnimals, setMaxNumSeason)
	if typVariant == nil or (typVariant:upper() ~= "RANDOM" and AnimalDealerMission.ACCEPTS_VARIANT[typVariant:upper()] == nil) then
		printError("Error: Given typVarian not found, accepts: random, riding, ridingtransport, transport, deliveryanimals, deliveryfilltype");
		return;
	end;
	local typVariant = typVariant:upper();	
	local animalName;
	local animalTypeIndex;
	if animalType ~= nil then
		animalName = animalType:upper();
		if animalName ~= "RANDOM" and animalName ~= "ALL" then
			if not g_additionalContractMapData:isAcceptsAnimal(animalName) then
				printError("Error: Given animalName (".. tostring(animalName).. ") not possible");
				return;
			else
				local typIndex = g_currentMission.animalSystem:getTypeIndexByName(animalName);
				if typIndex == nil then
					printError("Error: Given animalName (".. tostring(animalName).. ") not possible at Map, accepts: register animals ... or random or all");
					return;
				end;
				animalTypeIndex = typeIndex;
			end;	
		end;		
	end;
		
	local numAnimals = numAnimals or 2;		
	local setMaxNumSeason = setMaxNumSeason or false;
	
	local success = false;
	local missionType = g_missionManager:getMissionType(AnimalDealerMission.NAME);
	if missionType == nil then
		printError(string.format("Error: Given missionType %q not found", AnimalDealerMission.NAME));
		print(string.format("Available mission types: %s", table.concatKeys(g_missionManager.nameToMissionType, ", ")))
	else			
		local classObject = missionType.classObject;
		if classObject.tryGenerateMission ~= nil then				
			local mission = classObject.tryGenerateMission(true, typVariant, nil, setMaxNumSeason);
			if mission ~= nil then
				g_missionManager:registerMission(mission, missionType);
				success = true;
			end;
		end;
		
		if success then
			return "Mission created";
		end;
		printError("Error: Failed to create mission");
	end;	
end;

