protected void AddApparel(OptionsApparel options, ThingDef def)
        {
            PawnLayer layer = LayerForApparel(def);

            if (layer != null)
            {
                options.Add(layer, def);
            }
        }
        protected void AddApparel(OptionsApparel options, string defName)
        {
            ThingDef def = DefDatabase <ThingDef> .GetNamedSilentFail(defName);

            if (def != null)
            {
                AddApparel(options, def);
            }
        }
        protected void AddApparel(OptionsApparel options, ThingDef def)
        {
            int?layer = LayerForApparel(def);

            if (layer != null)
            {
                options.Add(layer.Value, def);
            }
        }
        protected OptionsApparel InitializeApparel(ThingDef raceDef)
        {
            AlienRace alienRace = AlienRaceProvider.GetAlienRace(raceDef);

            if (alienRace == null)
            {
                return(HumanlikeApparel);
            }
            // If the alien race does not have a restricted set of apparel, then we'll re-use the
            // humanlike apparel options.
            if (!alienRace.RestrictedApparelOnly && alienRace.RestrictedApparel == null)
            {
                return(HumanlikeApparel);
            }
            OptionsApparel   result       = new OptionsApparel();
            HashSet <string> addedAlready = new HashSet <string>();

            if (alienRace.RestrictedApparel != null)
            {
                foreach (var defName in alienRace.RestrictedApparel)
                {
                    AddApparel(result, defName);
                    addedAlready.Add(defName);
                }
            }
            if (!alienRace.RestrictedApparelOnly)
            {
                OptionsApparel humanApparel = HumanlikeApparel;
                foreach (var def in humanApparel.AllApparel)
                {
                    if (!addedAlready.Contains(def.defName))
                    {
                        AddApparel(result, def);
                        addedAlready.Add(def.defName);
                    }
                }
            }
            result.Sort();
            return(result);
        }
        protected OptionsApparel InitializeHumanlikeApparel()
        {
            HashSet <string>       nonHumanApparel = new HashSet <string>();
            IEnumerable <ThingDef> alienRaces      = DefDatabase <ThingDef> .AllDefs.Where((ThingDef def) => {
                return(def.race != null && ProviderAlienRaces.IsAlienRace(def));
            });

            foreach (var alienRaceDef in alienRaces)
            {
                AlienRace alienRace = AlienRaceProvider.GetAlienRace(alienRaceDef);
                if (alienRace == null)
                {
                    continue;
                }
                if (alienRace.RestrictedApparel != null)
                {
                    foreach (var defName in alienRace.RestrictedApparel)
                    {
                        nonHumanApparel.Add(defName);
                    }
                }
            }
            OptionsApparel result = new OptionsApparel();

            foreach (ThingDef apparelDef in DefDatabase <ThingDef> .AllDefs)
            {
                if (apparelDef.apparel == null)
                {
                    continue;
                }
                if (!nonHumanApparel.Contains(apparelDef.defName))
                {
                    AddApparel(result, apparelDef);
                }
            }
            result.Sort();
            return(result);
        }
        protected override void DrawPanelContent(State state)
        {
            base.DrawPanelContent(state);
            CustomPawn customPawn = state.CurrentPawn;

            string label = PawnLayers.Label(this.selectedPawnLayer);

            if (WidgetDropdown.Button(RectLayerSelector, label, true, false, true))
            {
                List <FloatMenuOption> list = new List <FloatMenuOption>();
                int layerCount = this.pawnLayerActions.Count;
                for (int i = 0; i < layerCount; i++)
                {
                    int pawnLayer = pawnLayers[i];
                    label = PawnLayers.Label(pawnLayers[i]);
                    list.Add(new FloatMenuOption(label, this.pawnLayerActions[i], MenuOptionPriority.Default, null, null, 0, null, null));
                }
                Find.WindowStack.Add(new FloatMenu(list, null, false));
            }
            GUI.DrawTexture(RectPortrait, Textures.TexturePortraitBackground);

            customPawn.UpdatePortrait();
            DrawPawn(customPawn, RectPortrait);

            GUI.color = ColorPortraitBorder;
            Widgets.DrawBox(RectPortrait, 1);
            GUI.color = Color.white;

            // Conflict alert
            if (customPawn.ApparelConflict != null)
            {
                GUI.color = Color.white;
                Rect alertRect = new Rect(RectPortrait.x + 77, RectPortrait.y + 150, 36, 32);
                GUI.DrawTexture(alertRect, Textures.TextureAlert);
                TooltipHandler.TipRegion(alertRect, customPawn.ApparelConflict);
            }

            // Draw selector field.
            Rect   fieldRect = new Rect(RectPortrait.x, RectPortrait.y + RectPortrait.height + 5, RectPortrait.width, 28);
            Action previousSelectionAction = null;
            Action nextSelectionAction     = null;
            Action clickAction             = null;

            OptionsApparel  apparelOptions = null;
            List <ThingDef> apparelList    = null;
            OptionsHair     hairOptions    = null;
            List <HairDef>  hairList       = null;

            if (this.selectedPawnLayer == PawnLayers.Hair)
            {
                hairOptions = PrepareCarefully.Instance.Providers.Hair.GetHairsForRace(customPawn);
                hairList    = hairOptions.GetHairs(customPawn.Gender);
            }
            else if (PawnLayers.IsApparelLayer(this.selectedPawnLayer))
            {
                apparelOptions = PrepareCarefully.Instance.Providers.Apparel.GetApparelForRace(customPawn);
                apparelList    = apparelOptions.GetApparel(this.selectedPawnLayer);
            }

            if (this.selectedPawnLayer == PawnLayers.HeadType)
            {
                int headTypeCount = PrepareCarefully.Instance.Providers.HeadTypes.GetHeadTypes(customPawn).Count();
                if (customPawn.HeadType != null && headTypeCount > 1)
                {
                    previousSelectionAction = () => {
                        SoundDefOf.TickTiny.PlayOneShotOnCamera();
                        SelectNextHead(customPawn, -1);
                    };
                    nextSelectionAction = () => {
                        SoundDefOf.TickTiny.PlayOneShotOnCamera();
                        SelectNextHead(customPawn, 1);
                    };
                }
                if (customPawn.HeadType != null && headTypeCount > 0)
                {
                    clickAction = () => {
                        ShowHeadDialog(customPawn);
                    };
                }
            }
            else if (this.selectedPawnLayer == PawnLayers.BodyType)
            {
                if (PrepareCarefully.Instance.Providers.BodyTypes.GetBodyTypesForPawn(customPawn.Pawn).Count > 1)
                {
                    previousSelectionAction = () => {
                        SoundDefOf.TickTiny.PlayOneShotOnCamera();
                        SelectNextBodyType(customPawn, -1);
                    };
                    nextSelectionAction = () => {
                        SoundDefOf.TickTiny.PlayOneShotOnCamera();
                        SelectNextBodyType(customPawn, 1);
                    };
                }
                clickAction = () => {
                    ShowBodyTypeDialog(customPawn);
                };
            }
            else if (this.selectedPawnLayer == PawnLayers.Hair)
            {
                if (hairList.Count > 1)
                {
                    previousSelectionAction = () => {
                        SoundDefOf.TickTiny.PlayOneShotOnCamera();
                        SelectNextHair(customPawn, -1);
                    };
                    nextSelectionAction = () => {
                        SoundDefOf.TickTiny.PlayOneShotOnCamera();
                        SelectNextHair(customPawn, 1);
                    };
                }
                if (hairList.Count > 0)
                {
                    clickAction = () => {
                        ShowHairDialog(customPawn);
                    };
                }
            }
            else
            {
                if (apparelList.Count > 1)
                {
                    previousSelectionAction = () => {
                        SoundDefOf.TickTiny.PlayOneShotOnCamera();
                        SelectNextApparel(customPawn, -1);
                    };
                    nextSelectionAction = () => {
                        SelectNextApparel(customPawn, 1);
                        SoundDefOf.TickTiny.PlayOneShotOnCamera();
                    };
                }
                if (apparelList.Count > 0)
                {
                    clickAction = () => {
                        ShowApparelDialog(customPawn, this.selectedPawnLayer);
                    };
                }
            }

            string selectorLabel = PawnLayerLabel.CapitalizeFirst();

            if (hairList != null && hairList.Count == 0)
            {
                selectorLabel = "EdB.PC.Common.NoOptionAvailable".Translate();
            }
            if (apparelList != null && apparelList.Count == 0)
            {
                selectorLabel = "EdB.PC.Common.NoOptionAvailable".Translate();
            }
            DrawFieldSelector(fieldRect, selectorLabel, previousSelectionAction, nextSelectionAction, clickAction);

            float cursorY = fieldRect.y + 34;

            // Draw stuff selector for apparel
            if (PawnLayers.IsApparelLayer(this.selectedPawnLayer))
            {
                ThingDef apparelDef = customPawn.GetSelectedApparel(selectedPawnLayer);
                if (apparelDef != null && apparelDef.MadeFromStuff)
                {
                    if (customPawn.GetSelectedStuff(selectedPawnLayer) == null)
                    {
                        Log.Error("Selected stuff for " + PawnLayers.ToApparelLayer(selectedPawnLayer) + " is null");
                    }
                    Rect stuffFieldRect = new Rect(RectPortrait.x, cursorY, RectPortrait.width, 28);
                    DrawFieldSelector(stuffFieldRect, customPawn.GetSelectedStuff(selectedPawnLayer).LabelCap,
                                      () => {
                        ThingDef selected = customPawn.GetSelectedStuff(selectedPawnLayer);
                        int index         = this.apparelStuffLookup[apparelDef].FindIndex((ThingDef d) => { return(selected == d); });
                        index--;
                        if (index < 0)
                        {
                            index = this.apparelStuffLookup[apparelDef].Count - 1;
                        }
                        customPawn.SetSelectedStuff(selectedPawnLayer, apparelStuffLookup[apparelDef][index]);
                    },
                                      () => {
                        ThingDef selected = customPawn.GetSelectedStuff(selectedPawnLayer);
                        int index         = this.apparelStuffLookup[apparelDef].FindIndex((ThingDef d) => { return(selected == d); });
                        index++;
                        if (index >= this.apparelStuffLookup[apparelDef].Count)
                        {
                            index = 0;
                        }
                        customPawn.SetSelectedStuff(selectedPawnLayer, this.apparelStuffLookup[apparelDef][index]);
                    },
                                      () => {
                        ShowApparelStuffDialog(customPawn, this.selectedPawnLayer);
                    }
                                      );

                    cursorY += stuffFieldRect.height;
                }
            }
            cursorY += 8;

            // Draw Color Selector
            if (PawnLayers.IsApparelLayer(selectedPawnLayer))
            {
                if (apparelList != null && apparelList.Count > 0)
                {
                    ThingDef def = customPawn.GetSelectedApparel(selectedPawnLayer);
                    if (def != null && def.HasComp(typeof(CompColorable)))
                    {
                        if (def.MadeFromStuff)
                        {
                            DrawColorSelector(customPawn, cursorY, null);
                        }
                        else
                        {
                            DrawColorSelector(customPawn, cursorY, def.colorGenerator);
                        }
                    }
                }
            }
            else if (selectedPawnLayer == PawnLayers.BodyType || selectedPawnLayer == PawnLayers.HeadType)
            {
                AlienRace alienRace = customPawn.AlienRace;
                if (alienRace == null || alienRace.UseMelaninLevels)
                {
                    DrawHumanlikeColorSelector(customPawn, cursorY);
                }
                else
                {
                    DrawAlienPawnColorSelector(customPawn, cursorY, alienRace.PrimaryColors, true);
                }
            }
            else if (selectedPawnLayer == PawnLayers.Hair)
            {
                if (hairList != null && hairList.Count > 0)
                {
                    DrawColorSelector(customPawn, cursorY, hairOptions.Colors, true);
                }
            }

            // Random button
            if (RectButtonRandomize.Contains(Event.current.mousePosition))
            {
                GUI.color = Style.ColorButtonHighlight;
            }
            else
            {
                GUI.color = Style.ColorButton;
            }
            GUI.DrawTexture(RectButtonRandomize, Textures.TextureButtonRandom);
            if (Widgets.ButtonInvisible(RectButtonRandomize, false))
            {
                SoundDefOf.TickLow.PlayOneShotOnCamera();
                RandomizeAppearance();
            }

            // Gender buttons.
            if (state.CurrentPawn.Pawn.RaceProps != null && state.CurrentPawn.Pawn.RaceProps.hasGenders)
            {
                bool genderFemaleSelected = state.CurrentPawn.Gender == Gender.Female;
                Style.SetGUIColorForButton(RectGenderFemale, genderFemaleSelected);
                GUI.DrawTexture(RectGenderFemale, Textures.TextureButtonGenderFemale);
                if (!genderFemaleSelected && Widgets.ButtonInvisible(RectGenderFemale, false))
                {
                    SoundDefOf.TickTiny.PlayOneShotOnCamera();
                    GenderUpdated(Gender.Female);
                }
                bool genderMaleSelected = state.CurrentPawn.Gender == Gender.Male;
                Style.SetGUIColorForButton(RectGenderMale, genderMaleSelected);
                GUI.DrawTexture(RectGenderMale, Textures.TextureButtonGenderMale);
                if (!genderMaleSelected && Widgets.ButtonInvisible(RectGenderMale, false))
                {
                    SoundDefOf.TickTiny.PlayOneShotOnCamera();
                    GenderUpdated(Gender.Male);
                }
            }
            GUI.color = Color.white;
        }
        public List <ThingDef> GetApparel(ThingDef raceDef, PawnLayer layer)
        {
            OptionsApparel apparel = GetApparelForRace(raceDef);

            return(apparel.GetApparel(layer));
        }