//-------------------------------------------------
        // Food

        public static void SelectFoodSacrifice(Building_BaseAltar altar, Building_BaseAltar.CongregationParms parms)
        {
            List <FloatMenuOption>       options = new List <FloatMenuOption>();
            List <CongregationRecipeDef> recipes = DefDatabase <CongregationRecipeDef> .AllDefs.Where(r => r.requiredChoice == "Food").ToList();

            if (parms.preacher == null)
            {
                return;                        // TODO: warning message?
            }
            foreach (CongregationRecipeDef r in recipes)
            {
                List <ThingCount> chosen = new List <ThingCount>();
                if (IngredientFinder.TryFindBestBillIngredients(new Bill_Production(r), parms.preacher, altar, chosen))
                {
                    if (!chosen.NullOrEmpty())
                    {
                        ThingDef  def = chosen.First().Thing.def;
                        Texture2D tex;

                        if (def.graphic is Graphic_StackCount)
                        {
                            Graphic graphic = (def.graphic as Graphic_StackCount).SubGraphicForStackCount(r.isWorthy? def.stackLimit : 3, def);
                            tex = graphic.MatSingle.GetTexture("_MainTex") as Texture2D;
                        }
                        else
                        {
                            tex = def.graphic.MatSingle.GetTexture("_MainTex") as Texture2D;
                        }

                        options.Add(new FloatMenuOption(
                                        r.label,
                                        delegate {  },// parms.sacrifice = thing;
                                        tex,
                                        new Color(1f, 1f, 1f, 1f),
                                        MenuOptionPriority.Default
                                        ));
                    }
                }
                ;
            }

            if (options.NullOrEmpty())
            {
                Messages.Message("No suitable amount of food is available", null, MessageTypeDefOf.RejectInput);
                return;
            }
            Find.WindowStack.Add(new FloatMenu(options));
        }
        //------------------------------------------------------------------------------
        // Other

        private void FoodCongregation(Pawn pawn)
        {
            // get required things based on bill's recipe
            List <ThingCount> chosen_things = new List <ThingCount>();
            Bill_Spell        bill          = new Bill_Spell(CultsDefOf.Cults_OfferMeatRaw_Worthy);

            if (!IngredientFinder.TryFindBestBillIngredients(bill, pawn, this, chosen_things))
            {
                Messages.Message("Ingredients not available", null, MessageTypeDefOf.RejectInput, null);
                return;
            }
            ;

            // prepare bill
            this.billStack.Clear();
            this.billStack.AddBill(bill);
            bill.billStack = this.billStack;
            bill.ingredientSearchRadius = 5f;

            // prepare job
            Job job = JobMaker.MakeJob(CultsDefOf.Cults_DoBill); // JobDefOf.DoBill); //
            List <LocalTargetInfo> target_list = new List <LocalTargetInfo>();
            List <int>             thing_count = new List <int>();

            job.targetQueueB = new List <LocalTargetInfo>(chosen_things.Count);
            job.countQueue   = new List <int>(chosen_things.Count);

            for (int i = 0; i < chosen_things.Count; i++)
            {
                job.targetQueueB.Add(chosen_things[i].Thing);
                job.countQueue.Add(chosen_things[i].Count);
            }

            job.playerForced      = true;
            job.targetA           = this;
            job.targetC           = PositionHeld;
            job.haulMode          = HaulMode.ToCellNonStorage;
            job.locomotionUrgency = LocomotionUrgency.Sprint;
            job.bill = this.billStack.FirstShouldDoNow;

            // start job
            pawn.jobs.TryTakeOrderedJob(job);
        }