setup.generateNPC = function(dict:NPCsDict,purpose:string,flags:NPCGenerateOptions):NPC{
	const npcId = dict.create(purpose);
	const npc = dict.npc(npcId);

	const generators =  flags.generators ?? ['default'];

	for(const generatorId of generators){
		if(!setup.npcGenerators[generatorId]){
			console.warn('Generator missing in setup.generateNPC:',generatorId);
			continue;
		}
		const generator = setup.npcGenerators[generatorId];
		flags = generator(flags);
	}

	for(const [fieldKey,fieldValue] of Object.entries(flags.fields ?? {}))
		npc[fieldKey] = fieldValue;
	return npc;
}

setup.npcGenerators = {};

setup.npcGenerators.default = function(flags:NPCGenerateOptions){
	flags.fields.age ??= rand(18,60);
	
	if(flags.fields.gender == EGender.FEMALE)
		flags = setup.npcGenerators.female(flags);
	else
		flags = setup.npcGenerators.male(flags);

	flags.fields.lastname ??= setup.randomName('sur');

	

	flags.fields.rel ??= 50;
	flags.fields.fam ??= 0;
	flags.fields.desc = '';

	return flags;
}

setup.npcGenerators.female = function(flags:NPCGenerateOptions){
	flags.fields.firstname ??= setup.randomName('female');

	flags.fields.image ??= setup.getRandomNpcImage({gender:EGender.FEMALE,age:NPCsDict.ageToAgeBracket(flags.fields.age ?? 18)}).path;

	flags.fields.height ??= Math.gaussianRandom(166,6.5);	//https://gitnux.org/average-russian-height/

	return flags;
};

setup.npcGenerators.male = function(flags:NPCGenerateOptions){
	flags.fields.firstname ??= setup.randomName('male');

	flags.fields.image ??= setup.getRandomNpcImage({gender:EGender.MALE,age:NPCsDict.ageToAgeBracket(flags.fields.age ?? 18)}).path;

	flags.fields.height ??= Math.gaussianRandom(178,8.1);	//https://gitnux.org/average-russian-height/

	flags.fields.dick ??= Math.clamp(Math.round(Math.gaussianRandom(0,1)),-3,3);

	return flags;
};

const enum EAgeBracket{
	UNKNOWN=-1,
	/**
	 * 0-0.5
	 */
	Newborn,
	/**
	 * 0.5-1
	 */
	Infant,
	/**
	 * 2-4
	 */
	Toddler,
	/**
	 * 5-12
	 */
	Kid,
	/**
	 * 13-17
	 */
	Teen,
	/**
	 * 18-29
	 */
	YoungAdult,
	/**
	 * 30-44
	 */
	Adult,
	/**
	 * 45-64
	 */
	MiddleAged,
	/**
	 * 65-79
	 */
	Old,
	/**
	 * 80+
	 */
	Ancient,

}

setup.getRandomNpcImage = function(filters:{[key:string]:any}):NPCImageDefinition{
	
	const filterFunction = function(npcImage:NPCImageDefinition){		
		for(const [filterKey,filterValue] of Object.entries(filters)){
			if(npcImage[filterKey] !== filterValue)
				return false;
		}
		return true;
	}
	
	const allImagesAsArray = Object.entries(setup.npcImages).map(entry=>Object.assign({id:entry[0]},entry[1]));
	const allImagesFiltered = allImagesAsArray.filter(filterFunction);
	if(allImagesFiltered.length)
		return allImagesFiltered.random();
	console.error('Failed to retrieve random image in getRandomNpcImage with filters:',filters);
	return {path:'characters/random/null.webp', gender: EGender.UNKNOWN,age:EAgeBracket.UNKNOWN};
}

setup.npcImages = {};
setup.npcImages.i10 = {
	path:'characters/random/10.jpg',
	gender: EGender.FEMALE,
	age: EAgeBracket.Teen
}

setup.npcImages.i9 = {
	path:'characters/random/9.jpg',
	gender: EGender.MALE,
	age: EAgeBracket.Adult
}