public static void RenderEditor(VRCSDK2.VRC_EventHandler myTarget)
        {
            bool first            = true;
            int  deleteEventIndex = -1;

            for (int i = 0; i < myTarget.Events.Count; ++i)
            {
                if (!first)
                {
                    EditorGUILayout.Separator();
                }
                first = false;

                if (RenderEventHeader(myTarget, myTarget.Events[i]))
                {
                    deleteEventIndex = i;
                }

                RenderEventHeader(myTarget, myTarget.Events[i]);

                if (myTarget.Events[i].ParameterObject == null)
                {
                    myTarget.Events[i].ParameterObject = myTarget.gameObject;
                }
            }

            if (deleteEventIndex != -1)
            {
                myTarget.Events.RemoveAt(deleteEventIndex);
            }
        }
        public override void OnInspectorGUI()
        {
            VRCSDK2.VRC_EventHandler myTarget = (VRCSDK2.VRC_EventHandler)target;

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("ID:");
            EditorGUILayout.EndHorizontal();

            if (myTarget.GetComponent <VRCSDK2.VRC_Trigger>() != null)
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Add Events via the VRC_Trigger on this object.");
                EditorGUILayout.EndHorizontal();
            }
            else
            {
                EditorGUI.BeginChangeCheck();

                RenderOldEditor(myTarget);

                if (EditorGUI.EndChangeCheck())
                {
                    EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
                }
            }

            if (myTarget.deferredEvents.Count > 0)
            {
                showDeferredEvents = EditorGUILayout.Foldout(showDeferredEvents, "Deferred Events");
                if (showDeferredEvents)
                {
                    RenderEvents(myTarget.deferredEvents);
                }
            }
        }
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        if(handler != null)
            SetStationEventHandlerEvents();
        else
            handler = myTarget.gameObject.GetComponent<VRCSDK2.VRC_EventHandler>();
    }
        public static bool RenderEventHeader(VRCSDK2.VRC_EventHandler myTarget, VRCSDK2.VRC_EventHandler.VrcEvent evt)
        {
            EditorGUILayout.BeginHorizontal();
            evt.EventType = VRC_EditorTools.FilteredEnumPopup("New Event Type", evt.EventType, (v) => v != VRC_EventHandler.VrcEventType.SpawnObject && v != VRC_EventHandler.VrcEventType.SendMessage);
            bool delete = GUILayout.Button("Remove");

            EditorGUILayout.EndHorizontal();

            return(delete);
        }
        public override void OnInspectorGUI()
        {
            if(handler != null)
            {
                if(myTarget.isRoomPlayerMods)
                    handler.enabled = false;
                else
                    handler.enabled = true;
            }
            else
            {
                handler = myTarget.gameObject.GetComponent<VRCSDK2.VRC_EventHandler>();
            }

            myTarget.isRoomPlayerMods = EditorGUILayout.Toggle("isRoomPlayerMods", myTarget.isRoomPlayerMods);

            if(GUILayout.Button("Add Remove Mods Event"))
            {
                SetRemovePlayerModsEventHandlerEvent();
            }

            if(GUILayout.Button("Add Mod"))
            {
                SetAddPlayerModsEventHandlerEvent();
                VRCPlayerModEditorWindow.Init(myTarget, delegate()
                {
                    Repaint();
                });
            }

            List<VRCPlayerMod> playerMods = myTarget.playerMods;
            for(int i=0; i<playerMods.Count; ++i)
            {
                VRCSDK2.VRCPlayerMod mod = playerMods[i];
                EditorGUILayout.BeginVertical("box");
                EditorGUILayout.LabelField(mod.name, EditorStyles.boldLabel);
                if( mod.allowNameEdit )
                    mod.name = EditorGUILayout.TextField( "Mod Name: ", mod.name );
                for(int j=0; j<mod.properties.Count; ++j)
                {
                    VRCSDK2.VRCPlayerModProperty prop = mod.properties[j];
                    myTarget.playerMods[i].properties[j] = DrawFieldForProp(prop);
                }
                if(GUILayout.Button ("Remove Mod"))
                {
                    myTarget.RemoveMod(mod);
                    break;
                }
                EditorGUILayout.EndVertical();
            }
        }
        public static VRCSDK2.VRC_EventHandler.VrcEvent RenderAddEvent(VRCSDK2.VRC_EventHandler myTarget)
        {
            VRCSDK2.VRC_EventHandler.VrcEvent newEvent = null;

            EditorGUILayout.BeginHorizontal();
            lastAddedEventType = VRC_EditorTools.FilteredEnumPopup("New Event Type", lastAddedEventType, (v) => v != VRC_EventHandler.VrcEventType.SpawnObject && v != VRC_EventHandler.VrcEventType.SendMessage);
            if (GUILayout.Button("Add"))
            {
                newEvent = new VRCSDK2.VRC_EventHandler.VrcEvent
                {
                    EventType       = lastAddedEventType,
                    ParameterObject = myTarget.gameObject
                };
                myTarget.Events.Add(newEvent);
                EditorUtility.SetDirty(myTarget);
            }
            EditorGUILayout.EndHorizontal();

            return(newEvent);
        }
        private void RenderOldEditor(VRCSDK2.VRC_EventHandler myTarget)
        {
            EditorGUILayout.HelpBox("Please use a VRC_Trigger in the future.", MessageType.Error);

            if (GUILayout.Button("Add Event Handler"))
            {
                myTarget.Events.Add(new VRCSDK2.VRC_EventHandler.VrcEvent());
            }

            bool first            = true;
            int  deleteEventIndex = -1;

            if (sendMessageMethodIndicies == null || sendMessageMethodIndicies.Length != myTarget.Events.Count)
            {
                sendMessageMethodIndicies = new int[myTarget.Events.Count + 1];
            }

            for (int i = 0; i < myTarget.Events.Count; ++i)
            {
                if (!first)
                {
                    EditorGUILayout.Separator();
                }
                first = false;

                EditorGUILayout.LabelField("Event " + (i + 1).ToString());

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Event Name");
                myTarget.Events[i].Name = EditorGUILayout.TextField(myTarget.Events[i].Name);
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Event Type");
                myTarget.Events[i].EventType = (VRCSDK2.VRC_EventHandler.VrcEventType)EditorGUILayout.EnumPopup(myTarget.Events[i].EventType);
                EditorGUILayout.EndHorizontal();

                switch (myTarget.Events[i].EventType)
                {
                case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationBool:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Variable");
                    myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Operation");
                    myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
                    EditorGUILayout.EndHorizontal();
                    break;

                case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationFloat:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Variable");
                    myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Value");
                    myTarget.Events[i].ParameterFloat = EditorGUILayout.FloatField(myTarget.Events[i].ParameterFloat);
                    EditorGUILayout.EndHorizontal();
                    break;

                case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationTrigger:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Trigger");
                    myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
                    EditorGUILayout.EndHorizontal();
                    break;

                case VRCSDK2.VRC_EventHandler.VrcEventType.AudioTrigger:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("AudioSource");
                    myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
                    EditorGUILayout.EndHorizontal();
                    break;

                case VRCSDK2.VRC_EventHandler.VrcEventType.MeshVisibility:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Mesh");
                    myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Operation");
                    myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
                    EditorGUILayout.EndHorizontal();
                    break;

                case VRCSDK2.VRC_EventHandler.VrcEventType.PlayAnimation:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Target");
                    myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Animation");
                    myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
                    EditorGUILayout.EndHorizontal();
                    break;

                case VRCSDK2.VRC_EventHandler.VrcEventType.RunConsoleCommand:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Command");
                    myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
                    EditorGUILayout.EndHorizontal();
                    break;

                case VRCSDK2.VRC_EventHandler.VrcEventType.SendMessage:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Receiver");
                    myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Message");

                    // sorry for this shit show. Below allows us to show a list of public methods, but also allow custom messages
                    var           methods    = VRC_EditorTools.GetPublicMethodsOnGameObject(myTarget.Events[i].ParameterObject);
                    List <string> methodList = methods.Values.Aggregate(new List <string>(), (acc, lst) => { acc.AddRange(lst.Select(mi => mi.Name)); return(acc); });
                    methodList.Add("Custom Message");

                    string[] _choices = methodList.ToArray();

                    int currentIndex = methodList.Count - 1;

                    if (methodList.Contains(myTarget.Events[i].ParameterString))
                    {
                        currentIndex = methodList.IndexOf(myTarget.Events[i].ParameterString);
                    }

                    sendMessageMethodIndicies[i] = EditorGUILayout.Popup(currentIndex, _choices);

                    if (sendMessageMethodIndicies[i] != methodList.Count - 1)
                    {
                        myTarget.Events[i].ParameterString = _choices[sendMessageMethodIndicies[i]];
                    }
                    else
                    {
                        if (methodList.Contains(myTarget.Events[i].ParameterString))
                        {
                            myTarget.Events[i].ParameterString = "";
                        }

                        myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
                    }

                    EditorGUILayout.EndHorizontal();
                    break;

                case VRCSDK2.VRC_EventHandler.VrcEventType.SetGameObjectActive:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("GameObject");
                    myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Operation");
                    myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
                    EditorGUILayout.EndHorizontal();
                    break;

                case VRCSDK2.VRC_EventHandler.VrcEventType.SetParticlePlaying:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Target");
                    myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Operation");
                    myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
                    EditorGUILayout.EndHorizontal();
                    break;

                case VRCSDK2.VRC_EventHandler.VrcEventType.TeleportPlayer:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Location");
                    myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
                    EditorGUILayout.EndHorizontal();
                    break;

                case VRCSDK2.VRC_EventHandler.VrcEventType.SetWebPanelURI:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("URI");
                    myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Panel");
                    myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
                    EditorGUILayout.EndHorizontal();
                    break;

                case VRCSDK2.VRC_EventHandler.VrcEventType.SetWebPanelVolume:
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Volume");
                    myTarget.Events[i].ParameterFloat = EditorGUILayout.FloatField(myTarget.Events[i].ParameterFloat);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("Panel");
                    myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
                    EditorGUILayout.EndHorizontal();
                    break;

                default:
                    EditorGUILayout.BeginHorizontal();
                    GUIStyle redText = new GUIStyle();
                    redText.normal.textColor = Color.red;
                    EditorGUILayout.LabelField("Unsupported event type", redText);
                    EditorGUILayout.EndHorizontal();
                    break;
                }

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Delete " + myTarget.Events[i].Name + "?");
                if (GUILayout.Button("delete"))
                {
                    deleteEventIndex = i;
                }
                EditorGUILayout.EndHorizontal();

                if (myTarget.Events[i].ParameterObject == null)
                {
                    myTarget.Events[i].ParameterObject = myTarget.gameObject;
                }
            }


            if (deleteEventIndex != -1)
            {
                myTarget.Events.RemoveAt(deleteEventIndex);
            }
        }