public Experiment DoStudyListing(Rect rect, Building_StudyTable selTable, ref Vector2 scrollPosition, ref float viewHeight)
        {
            for (int i = 0; i < _experiments.Count; i++)
            {
                CheckIfExperimentCompleted(_experiments[i]);
            }

            Experiment result = null;

            GUI.BeginGroup(rect);
            Text.Font = GameFont.Small;
            if (ListCount < 15)
            {
                Rect rect2 = new Rect(rect.width / 4, rect.y, 150f, 29f);
                rect2.x += 10f;
                if (Widgets.ButtonText(rect2, "Study Experiment"))
                {
                    Find.WindowStack.Add(new Dialog_StudyConfig(selTable));
                }
            }
            // draw Experiment Entry In List
            Text.Anchor = TextAnchor.UpperLeft;
            GUI.color   = Color.white;
            Rect outRect  = new Rect(0f, 35f, rect.width, rect.height - 35f);
            Rect viewRect = new Rect(0f, 0f, outRect.width - 16f, viewHeight);

            Widgets.BeginScrollView(outRect, ref scrollPosition, viewRect);
            float num = 5f;

            for (int i = 0; i < ListCount; i++)
            {
                Experiment exp   = _experiments[i];
                Rect       rect3 = exp.DoInterface(0f, num, viewRect.width, i);
                if (!exp.DeletedOrDereferenced && Mouse.IsOver(rect3))
                {
                    result = exp;
                }
                num += rect3.height + 6f;
            }

            if (Event.current.type == EventType.Layout)
            {
                viewHeight = num + 60f;
            }
            Widgets.EndScrollView();
            GUI.EndGroup();
            return(result);
        }
        public Dialog_StudyConfig(Building_StudyTable table)
        {
            _selectedTable = table;

            var pawns = Find.CurrentMap.mapPawns.SpawnedPawnsInFaction(Faction.OfPlayer);

            for (int i = 0; i < pawns.Count; ++i)
            {
                if (pawns[i].IsColonist)
                {
                    // remove non research assigned pawns
                    if (pawns[i].workSettings.WorkIsActive(WorkTypeDefOf.Research) && !pawns[i].WorkTypeIsDisabled(WorkTypeDefOf.Research))
                    {
                        _pawnsInColony.Add(new Tuple <string, Thing>(pawns[i].Name.ToString(), pawns[i]));
                    }
                }
            }



            if (!(from t in DefDatabase <ThingDef> .AllDefs where t.defName == "FinishedExperiment" select t).TryRandomElement(out ThingDef finalDef))
            {
                Log.Error("Unable to locate finished experiment def in DefDatabase.", false);
            }
            else
            {
                var def       = finalDef;
                var req       = ThingRequest.ForDef(def);
                var thingList = Find.CurrentMap.listerThings.ThingsMatching(req);

                if (thingList.Count == 0)
                {
                    // Log.Error("No finished exps in colony.");
                    return;
                }

                foreach (var thing in thingList)
                {
                    var comp = thing.TryGetComp <ResearchThingComp>();

                    _finishedExperimentList.Add(new Tuple <string, Thing>(thing.TryGetComp <ResearchThingComp>().researchDefName, thing));
                }
                // Log.Error("Num of experiments in colony: " + thingList.Count);
            }
        }
        // TODO: figure out different way to call derived notify instead of using toils
        // currently using this since cannot reliably call notify from workgiver
        public static void NotifyExperimentIsCompleted(Bill_Production __instance, ref Pawn billDoer)
        {
            Building_ExperimentBench expBench   = __instance.billStack.billGiver.LabelShort == "Experiment Bench"? expBench = (Building_ExperimentBench)__instance.billStack.billGiver: null;
            Building_StudyTable      studyTable = __instance.billStack.billGiver.LabelShort == "Study Table" ? studyTable = (Building_StudyTable)__instance.billStack.billGiver : null;

            if (expBench != null)
            {
                int        index = expBench.ExpStack.IndexOfBillToExp(__instance);
                Experiment Exp   = expBench.ExpStack.Experiments[index];
                expBench.ExpStack.Delete(Exp);
            }
            if (studyTable != null)
            {
                int        index = studyTable.ExpStack.IndexOfBillToExp(__instance);
                Experiment Exp   = studyTable.ExpStack.Experiments[index];
                studyTable.ExpStack.Delete(Exp);
            }
        }