UniversalMission = {};
UniversalMission.NAME = "universalMission";
UniversalMission.UI_SETTINGS = true;
UniversalMission.MAX_NUM_INSTANCE = 2;
UniversalMission.DEFAULT_NUM_INSTANCE = 1;

UniversalMission.CONTRACT_DURATION = 115200000;
UniversalMission.CONTRACT_DURATION_VAR = 57600000;

UniversalMission.uiData = {
	settings = {		
		universalMission_minMax = UniversalMission.DEFAULT_NUM_INSTANCE;		
	};
	controls = {
		{ typName="universalMission", name="universalMission_minMax", autoBind=true, min=0, max=UniversalMission.MAX_NUM_INSTANCE, step=1, unit="/ ".. tostring(UniversalMission.MAX_NUM_INSTANCE), nillable=false }; --min 0 = off
	};
};

UniversalMission.data = {	
	jobTypName = g_i18n:getText("contract_universal_title");	
};

UniversalMission.metadata = {
	interface = "FS25 ...", --new
	title = "Universal Contracts",
	notes = "Dieser Mod generiert Aufträge für verschiedene Branchen – beispielsweise Transport und mehr.",
	author = "(by HappyLooser)",		
	build = 3,
	datum = "10.07.2025",
	update = "19.09.2025",
	debugPrint = false, 
	discord = "HappyLooser Modding",
	info = " Link Freigabe,Änderungen,Kopien oder Code Benutzung ist ohne meine Zustimmung nicht erlaubt",
	"##Orginal Link Freigabe:"
};

source(AdditionalContracts.modDir.. "missions/universalMission/UniversalMissionFakeTrigger.lua");
source(AdditionalContracts.modDir.. "missions/universalMission/UniversalChangeSettingsEvent.lua");
source(AdditionalContracts.modDir.. "missions/universalMission/UniversalLoadSettingsEvent.lua");

InitObjectClass(UniversalMission, "UniversalMission");

function UniversalMission.new(isServer, isClient, typClass)	
	
	if typClass == nil then typClass = g_additionalContractTypes:getTypClass(true);end;
	local self = typClass.new(isServer, isClient);
	
	return self;
end;

function UniversalMission.registerSavegameXMLPaths(schema, key)
	schema:register(XMLValueType.STRING, key .. "#typName", "typName by AdditionalContractTypes")
		
	g_additionalContractTypes:registerSavegameXMLPaths(schema, key);
	
end;

function UniversalMission:getMissionTypeName()
    return UniversalMission.NAME;
end;

function UniversalMission.tryGenerateMission(balanceTyp, randomTyp, typName)
	if UniversalMission.canRun() then		
		local typClass = g_additionalContractTypes:getMissionTyp(balanceTyp or true, randomTyp or false, typName); --supplyDeliveryBulkMission, vehicleTransportMission
		if typClass == nil or typClass.canRun == nil or not typClass.canRun() then return nil;end;
		local mission = UniversalMission.new(true, g_client ~= nil, typClass);
		if mission:init() then					
			g_additionalContractTypes:setNumNextDayTyp(mission.NAME);
			g_additionalContractTypes:setBalanceTyp(mission.NAME);
			mission:setDefaultEndDate();
			return mission;
		end;
		mission:delete();
	end;
	return nil;
end;

function UniversalMission.canRun(addConsole)
	if not UniversalMission:getOnOff() then return false;end;
	if addConsole then return true;end;
	local data = g_missionManager:getMissionTypeDataByName(UniversalMission.NAME);	
	if data.numInstances >= data.maxNumInstances or data.numInstances >= g_additionalContractTypes.settings[UniversalMission.NAME.. "_minMax"] then
		return false;
	else		
		return true;	
	end;
end;

function UniversalMission:setMaxNumInstance(maxNumInstance)
	self.uiData.settings[UniversalMission.NAME.. "_minMax"] = maxNumInstance;
	g_additionalContractTypes:replaceUISettings(UniversalMission.NAME.. "_minMax", maxNumInstance);
	local data = g_missionManager:getMissionTypeDataByName(UniversalMission.NAME);
	if data ~= nil then data.maxNumInstances = maxNumInstance;end;
end;

function UniversalMission:getMaxNumInstance()
	local data = g_missionManager:getMissionTypeDataByName(UniversalMission.NAME);
	if data == nil then 
		return g_additionalContractTypes.settings[UniversalMission.NAME.. "_minMax"];
	end;
	return data.maxNumInstances;
end;

function UniversalMission:getOnOff()	
	return g_additionalContractTypes.settings[UniversalMission.NAME.. "_minMax"] > 0;
end;

function UniversalMission:setOnOff(state)	
	
end;

function UniversalMission:onStartMap(args)
	
end;

function UniversalMission:isOnStartMap(args)
	if not args.isDetiServer and g_currentMission.hlUtils.modLoaded ~= nil and g_currentMission.hlUtils.modLoaded["FS25_MissionsDisplay"] ~= nil then
		if g_currentMission.hlUtils.globalFunction["FS25_MissionsDisplay"].getBuildVersion == nil or g_currentMission.hlUtils.globalFunction["FS25_MissionsDisplay"].getBuildVersion() <= 28 then
			local isAlReadyType = false;
			local isUnknownAlReadyType = false;
			local mdMod = getfenv(0)["FS25_MissionsDisplay"];
			if mdMod ~= nil and mdMod.Missions_Display ~= nil and mdMod.Missions_Display.values ~= nil and mdMod.Missions_Display.values.missionsTypes ~= nil then
				local missionData = g_missionManager:getMissionType(UniversalMission.NAME);
				for missionId, missionsType in pairs(mdMod.Missions_Display.values.missionsTypes) do
					if missionsType.name == "universalMission" and missionsType.modName == "FS25_AdditionalContracts" then isAlReadyType = true;break;end;
					if missionData ~= nil and missionData.typeId ~= nil and missionData.typeId == missionsType.typId then isUnknownAlReadyType = true;break;end;					
				end;				
				if isUnknownAlReadyType or not isAlReadyType then								
					local isActive = function(args)return missionData.classObject:getOnOff(args);end;
					local changeMaxNumInstance = function(args)return missionData.classObject:getMaxNumInstance(args);end;
					local universalMissionData = {name="universalMission",jobTypName=UniversalMission.data.jobTypName,typId=missionData.typeId,isActive=isActive,changeMaxNumInstance=changeMaxNumInstance, overlay="unknownContract", modName="FS25_AdditionalContracts", view=true, total=0};
					if isUnknownAlReadyType then
						universalMissionData.view = mdMod.Missions_Display.values.missionsTypes[missionData.typeId].view;				
					end;
					mdMod.Missions_Display.values.missionsTypes[missionData.typeId] = universalMissionData;
				end;
			end;			
		end;
	end;
end;

function UniversalMission:loadInit()	
	if UniversalMission.UI_SETTINGS then		
		local isReady = false;
		for key, value in pairs(UniversalMission.uiData.settings) do			
			isReady = g_additionalContractTypes:setUISettings(key, value);
			if not isReady then break;end; 
		end;
		if isReady then
			for _, control in ipairs(UniversalMission.uiData.controls) do
				g_additionalContractTypes:setUIControls(control);			
			end;
		else
			for key, value in pairs(UniversalMission.uiData.settings) do
				g_additionalContractTypes:delUISettings(key);				 
			end;
		end;		
	end;	
end;

function UniversalMission:loadSettingsEvent(mission, connection, x, y, z, viewDistanceCoeff)
	if g_currentMission ~= nil and g_currentMission.missionDynamicInfo ~= nil and g_currentMission.missionDynamicInfo.isMultiplayer then
		g_client:getServerConnection():sendEvent(UniversalLoadSettingsEvent.new());
	end;
end;

function UniversalMission:changeSettingsEvent(settingsId, state)
	if g_currentMission ~= nil and g_currentMission.missionDynamicInfo ~= nil and g_currentMission.missionDynamicInfo.isMultiplayer then
		g_client:getServerConnection():sendEvent(UniversalChangeSettingsEvent.new(settingsId, state));
	else
		self:onChangeSettings(settingsId, state);
	end;
end;

function UniversalMission:onChangeSettings(settingsId, state)		
	if settingsId == "universalMission_minMax" then		
		self:setMaxNumInstance(state);		
	end;	
end;

function UniversalMission:loadSettingsXML(xmlFile, prefix)
	if not xmlFile:hasProperty(prefix.. ".".. UniversalMission.NAME.. ".minMax") then return;end;	--first start
	local minMax = xmlFile:getInt(prefix.. ".".. UniversalMission.NAME.. ".minMax");
	local control = g_additionalContractTypes:getUIControls(UniversalMission.NAME.. "_minMax");
	if minMax > control.max then minMax = control.max;elseif minMax < control.min then minMax = control.min;end;	
	self:setMaxNumInstance(minMax);	
end;

function UniversalMission:saveSettingsXML(xmlFile, prefix)
	xmlFile:setInt(prefix.. ".".. UniversalMission.NAME.. ".minMax", g_additionalContractTypes.settings[UniversalMission.NAME.. "_minMax"]);	
end;

function UniversalMission:getMissionTypes()
	local missionData = g_missionManager:getMissionType(UniversalMission.NAME);
	local isActive = function(args)return missionData.classObject:getOnOff(args);end;
	local changeMaxNumInstance = function(args)return missionData.classObject:getMaxNumInstance(args);end;
	local universalMissionData = {name="universalMission",jobTypName=UniversalMission.data.jobTypName,typId=missionData.typeId,isActive=isActive,changeMaxNumInstance=changeMaxNumInstance, overlay="unknownContract", modName="FS25_AdditionalContracts", view=true};
	return universalMissionData;
end;

g_additionalContractTypes:registerTyp(UniversalMission, UniversalMission.NAME, true);
