/// <summary>
    /// [HACK TRICK]
    /// use reflection to take out the data
    /// </summary>
    private bool _IsAnimEventPopupOpen()
    {
        Type t = RCall.GetTypeFromString("UnityEditor.AnimationEventPopup");

        UnityEngine.Object[] array = Resources.FindObjectsOfTypeAll(t);
        return(array.Length > 0);
    }
        private static void _LoadPrefs()
        {
            m_IKConMarkerSize           = LoadPrefFloat(Pref_IKConMarkerSize, 0.6f);
            m_IKAngleConstraintArcColor = LoadPrefColor(Pref_IKConArcColor, new Color(0.2f, 0.2f, 0.8f, 0.4f));
            m_IKConeConstraintColor     = LoadPrefColor(Pref_IKConeConColor, new Color(0.2f, 0.2f, 0.8f, 1f));
            m_IKBoneLinkColor           = LoadPrefColor(Pref_IKBoneLinkColor, new Color32(255, 31, 173, 255));
            m_showInitInfos             = LoadPrefBool(Pref_ShowInitInfos, false);

            m_hasCAT        = (RCall.GetTypeFromString("MH.SMREditor", true) != null);
            m_hasIMMConsole = (RCall.GetTypeFromString("MH.MonoCSConsole", true) != null);

            m_isLoaded = true;
        }
    /// <summary>
    /// make the AnimEvent and EventGO to be matched
    /// maybe not one-one match, multiple animEvent could match same EventGO
    /// </summary>
    private void _MatchEventGOAndAnimEvent()
    {
        //////////////////////////////////////////////////
        //  1. for each AnimEvent, if there is not a corresponding eventGO, create it;
        //  2. for each eventGO, if there is not a corresponding AnimEvent, the delete the eventGO
        //////////////////////////////////////////////////

        //if( _IsAnimEventPopupOpen() )
        //{
        //    return; //don't execute matching if the AnimEventPopup is open
        //}

        // create a Dictionary for eventGO
        for (int idx = 0; idx < m_evtGoRoot.childCount; ++idx)
        {
            Transform ctr = m_evtGoRoot.GetChild(idx);
            m_evtGORefDict[ctr] = false;
        }

        // get the AnimEvent list
        AnimationEvent[] events = AnimationUtility.GetAnimationEvents(m_CurClip);

        // step 1
        for (int idx = 0; idx < events.Length; ++idx)
        {
            AnimationEvent evt      = events[idx];
            string         goName   = evt.stringParameter;
            string         funcName = evt.functionName;

            if (goName == null)
            {
                Dbg.LogWarn("CCEditor._MatchEventGOAndAnimEvent: found an event not specifying the GOName, at time: {0}", evt.time);
                ArrayUtility.RemoveAt(ref events, idx);
                --idx;
            }

            Transform oneTr = m_evtGoRoot.Find(goName);
            if (null == oneTr)
            {
                //create the go
                GameObject newEvtGO = new GameObject(goName);
                Misc.AddChild(m_evtGoRoot, newEvtGO);
                Dbg.Log("Sync AnimEvent with EventGO: create EventGO for: {0}", goName);

                //add component according to the funcName, the init-work should be executed by the MB's awake() or start()
                //CC_EvtActions newAct = newEvtGO.AddComponent("CC_" + funcName) as CC_EvtActions;
                //Dbg.Assert(m_CC != null, "CCEditor._MatchEventGOAndAnimEvent: failed to get CutsceneController");
                //newAct.CC = m_CC;

                string tpName = "MH.CC_" + funcName;
                Type   tp     = RCall.GetTypeFromString(tpName);
                Dbg.Assert(tp != null, "CCEditor._MatchEventGOAndAnimEvent: failed to get type from string: {0}", tpName);
                CC_EvtActions newAct = newEvtGO.AddComponent(tp) as CC_EvtActions;
                Dbg.Assert(m_CC != null, "CCEditor._MatchEventGOAndAnimEvent: failed to get CutsceneController");
                newAct.CC = m_CC;
            }
            else
            {
                m_evtGORefDict[oneTr] = true; //this event go is ref-ed, don't delete it
            }
        }

        // step 2
        for (var ie = m_evtGORefDict.GetEnumerator(); ie.MoveNext();)
        {
            var  pr    = ie.Current;
            bool inUse = pr.Value;
            if (!inUse)
            {
                Transform tr = pr.Key;
                Dbg.Log("Sync AnimEvent with EventGO: delete EventGO: {0}", tr.name);
                GameObject.DestroyImmediate(tr.gameObject);
            }
        }

        m_evtGORefDict.Clear(); //clear the tmp data
    }