g_xmlManager:addInitSchemaFunction(function()
	Placeable.xmlSchemaSavegame:register(XMLValueType.INT, "placeables#loadKeys", "load total of the own/mod placeables", 0);
	Placeable.xmlSchema:register(XMLValueType.STRING, "placeable.sellingStation.unloadTrigger(?)#missionType", "load of the placeable trigger fillTypes by missionType");
	Placeable.xmlSchema:register(XMLValueType.STRING, "placeable.sellingStation.baleTrigger(?)#missionType", "load of the placeable trigger fillTypes by missionType");
	Placeable.xmlSchema:register(XMLValueType.STRING, "placeable.sellingStation.palletTrigger(?)#missionType", "load of the placeable trigger fillTypes by missionType");
	Placeable.xmlSchema:register(XMLValueType.STRING, "placeable.sellingStation.woodTrigger(?)#missionType", "load of the placeable trigger fillTypes by missionType");	
end);

AdditionalContractPlaceableManager = {};

local AdditionalContractPlaceableManager_mt = Class(AdditionalContractPlaceableManager, AbstractManager);

function AdditionalContractPlaceableManager:debugPrint(text, ...)
	if self.printDebug then		
		Logging.info(text,...);		
	end;
end;

function AdditionalContractPlaceableManager.new()	
	local self = AbstractManager.new(AdditionalContractPlaceableManager_mt)
	self.isServer = g_server ~= nil;	
	self:initDataStructures();	
	return self;
end;

function AdditionalContractPlaceableManager:initDataStructures()
	self.printDebug = false;	
	self.isLoadRunning = false;
	self.placeables = {};
	self.placeablesByUniqueId = {};	
	self.loadedPlaceables = false;	
end;

function AdditionalContractPlaceableManager:loadMapData(xmlFile, missionInfo)
	AdditionalContractPlaceableManager:superClass().loadMapData(self);	
	if self.isServer then self:load();end;
	return true;
end;

function AdditionalContractPlaceableManager:unloadMapData()
	AdditionalContractPlaceableManager:superClass().unloadMapData(self);	
end;

function AdditionalContractPlaceableManager:load(xmlFilename, callbackFunction, callbackArguments, modDir)
	if self.loadedPlaceables and xmlFilename == nil then self:setDebugPrint(false);return nil;end;
	if self.isLoadRunning then self:debugPrint("** not loaded placeables from %s (load running is active) **", xmlFilename);self:setDebugPrint(false);return false;end;
	self.isLoadRunning = true;
		
	self.callbackFunction = callbackFunction;
	self.callbackArguments = callbackArguments;
	local xmlFilename = xmlFilename or Utils.getFilename("config/placeables.xml", AdditionalContracts.modDir);
	if not fileExists(xmlFilename) then 
		self:debugPrint("** not loaded map placeables from %s (not file exists)**", xmlFilename);
		self:setDebugPrint(false);
		return false;
	end;	
	self.placeableXMLFile = XMLFile.load("placeablesXML", xmlFilename, Placeable.xmlSchemaSavegame);
	self.loadKeys = self.placeableXMLFile:getValue("placeables#loadKeys", 0);
	self.deleteKeys = 0;
	for _, key in self.placeableXMLFile:iterator("placeables.placeable") do
		local filename = self.placeableXMLFile:getValue(key.. "#filename");
		local convertFilename = g_additionalContractUtils:getConvertFilename(filename, modDir or AdditionalContracts.modDir);			
		self.placeableXMLFile:setValue(key.. "#filename", convertFilename);
		local uniqueId = self.placeableXMLFile:getValue(key.. "#uniqueId");
		if uniqueId ~= nil then
			local preplaced = g_currentMission.placeableSystem:getPlaceableByUniqueId(uniqueId);
			if preplaced ~= nil then				
				self:addPlaceable(preplaced);				
				self.deleteKeys = self.deleteKeys + 1;
				self.placeableXMLFile:removeProperty(key);				
			end;
		end;
	end;	
	if self.loadKeys ~= 0 and self.deleteKeys < self.loadKeys then
		g_asyncTaskManager:addTask(function()
			self:loadPlaceablesXML();
		end);
	else
		self:debugPrint("** not loaded map placeables from ../config/placeables.xml: deleteKeys %s >= loadKeys %s **", self.deleteKeys, self.loadKeys);
		if self.callbackFunction ~= nil then self.callbackFunction(nil, false, self.callbackArguments);self.callbackFunction = nil;self.callbackArguments = nil;end;
		if self.placeableXMLFile ~= nil then self.placeableXMLFile:delete();self.placeableXMLFile = nil;end;
		self.loadKeys = nil;
		self.delteKeys = nil;
		self.isLoadRunning = false;
		self:setDebugPrint(false);
	end;
		
	self.loadedPlaceables = true;	
end;

function AdditionalContractPlaceableManager:loadPlaceablesXML()	
	self:debugPrint("** load map placeables from %s **", self.placeableXMLFile);
	g_currentMission.placeableSystem:loadFromXMLFile(self.placeableXMLFile, self.loadingPlaceables, self);	
end;

function AdditionalContractPlaceableManager:loadingPlaceables(placeables, placeableLoadState)	
	if self.callbackFunction ~= nil then self.callbackFunction(placeables, placeableLoadState, self.callbackArguments);self.callbackFunction = nil;self.callbackArguments = nil;end;
	if placeables ~= nil and #placeables > 0 and placeableLoadState == PlaceableLoadingState.OK then
		self:debugPrint("** loadingPlaceables() addPlaceable() length %s, state true **", #placeables);	
		for _, placeable in ipairs(placeables) do			
			self:addPlaceable(placeable);			
		end;
	end;
	self:debugPrint("** loadingPlaceables() on Server %s, g_client: %s **", placeables ~= nil and #placeables > 0 and placeableLoadState == PlaceableLoadingState.OK, g_client);	
	if self.placeableXMLFile ~= nil then self.placeableXMLFile:delete();self.placeableXMLFile = nil;end;
	self.loadKeys = nil;
	self.delteKeys = nil;
	self.isLoadRunning = false;
	self:setDebugPrint(false);
end;

function AdditionalContractPlaceableManager:getPlaceableByUniqueId(uniqueId)
	return self.placeablesByUniqueId[uniqueId] or g_currentMission.placeableSystem:getPlaceableByUniqueId(uniqueId);
end;

function AdditionalContractPlaceableManager:addPlaceable(placeable)
	if placeable ~= nil and placeable.getUniqueId ~= nil then
		local uniqueId = placeable:getUniqueId();
		if uniqueId == nil or self.placeablesByUniqueId[uniqueId] ~= nil then 
			self:debugPrint("** not addPlaceable() on Server, uniqueId: %s or already available **", uniqueId);
			return;
		end;
		self.placeablesByUniqueId[uniqueId] = placeable;
		self:debugPrint("** addPlaceable() on Server, uniqueId: %s **", uniqueId);
	else
		self:debugPrint("** not addPlaceable() on Server, uniqueId: %s or placeable nil **", uniqueId);
	end;
end;

function AdditionalContractPlaceableManager:removePlaceable(placeable)
	if placeable ~= nil and placeable.getUniqueId ~= nil then
		local uniqueId = placeable:getUniqueId();
		if uniqueId == nil or self.placeablesByUniqueId[uniqueId] == nil then 
			self:debugPrint("** not removePlaceable() on Server, uniqueId: %s or not available **", uniqueId);
			return;
		end;
		self.placeablesByUniqueId[uniqueId] = nil;
		self:debugPrint("** removePlaceable() on Server, uniqueId: %s **", uniqueId);
	else
		self:debugPrint("** not removePlaceable() on Server, uniqueId: %s or placeable nil **", uniqueId);
	end;
end;

function AdditionalContractPlaceableManager:setDebugPrint(state)
	self.printDebug = state or false;
end;

function AdditionalContractPlaceableManager:getDebugPrint()
	return self.printDebug;
end;

g_additionalContractPlaceableManager = AdditionalContractPlaceableManager.new();