/// <summary>
    /// Adds a new motion
    /// </summary>
    /// <param name="rLayerIndex">Layer index to add the motion to</param>
    /// <returns>Index of the new motion</returns>
    private void AddMotor(Type rMotorType)
    {
        BoneControllerMotor lMotor = Activator.CreateInstance(rMotorType) as BoneControllerMotor;

        //BoneControllerMotor lMotor = ScriptableObject.CreateInstance(rMotorType) as BoneControllerMotor;

        lMotor.Skeleton = mSkeleton;
        mSkeleton.Motors.Add(lMotor);

        mSelectedMotorIndex = mSkeleton.Motors.Count - 1;
    }
    /// <summary>
    /// Renders the properties of the motion so they can be changed here
    /// </summary>
    /// <param name="rLayerIndex">Layer the motion belongs to</param>
    /// <param name="rMotorIndex">Motors whose properites are to be listed</param>
    private bool RenderMotorProperties(int rMotorIndex)
    {
        bool lExit = false;

        if (!lExit && rMotorIndex < 0)
        {
            lExit = true;
        }
        if (!lExit && rMotorIndex >= mSkeleton.Motors.Count)
        {
            lExit = true;
        }

        // If we don't have items in the list, display some help
        if (lExit)
        {
            EditorGUILayout.HelpBox(mPropertyHelp, MessageType.Info, true);
            return(false);
        }

        // Tracks if we change the motion values
        bool lIsDirty = false;

        // Grab the motion
        BoneControllerMotor lMotor = mSkeleton.Motors[rMotorIndex];

        if (lMotor == null)
        {
            return(false);
        }

        object[] lMotorAttributes = lMotor.GetType().GetCustomAttributes(typeof(IKDescriptionAttribute), true);
        foreach (IKDescriptionAttribute lAttribute in lMotorAttributes)
        {
            EditorGUILayout.HelpBox(lAttribute.Description, MessageType.None, true);
        }

        EditorGUILayout.LabelField(new GUIContent("Type", "Identifies the type of motor."), new GUIContent(lMotor.GetType().Name));
        EditorGUILayout.LabelField(new GUIContent("Namespace", "Specifies the container the motor belongs to."), new GUIContent(lMotor.GetType().Namespace));

        // Force the name at the top
        string lNewName = EditorGUILayout.TextField(new GUIContent("Name", "Friendly name of the motor that can be searched for."), lMotor.Name);

        if (lNewName != lMotor.Name)
        {
            lIsDirty    = true;
            lMotor.Name = lNewName;
        }

        float lNewWeight = EditorGUILayout.FloatField(new GUIContent("Weight", "Determines how much strength this motor has relative to the other motors (0 to 1)."), lMotor.Weight);

        if (lNewWeight != lMotor.Weight)
        {
            lIsDirty      = true;
            lMotor.Weight = lNewWeight;
        }

        EditorGUILayout.BeginHorizontal();

        // Determines if the motor will run
        bool lNewIsEnabled = EditorGUILayout.Toggle(new GUIContent("Is Enabled", "Determines if the motor will run or not."), lMotor.IsEnabled);

        if (lNewIsEnabled != lMotor.IsEnabled)
        {
            lIsDirty          = true;
            lMotor._IsEnabled = lNewIsEnabled;
        }

        // Determines if we'll run in the scene editor
        GUILayout.Space(20);
        EditorGUILayout.LabelField(new GUIContent("Run In Editor", "Determines if the motor runs in the scene editor."), GUILayout.Width(80));
        bool lNewIsEditorEnabled = EditorGUILayout.Toggle(lMotor.IsEditorEnabled, GUILayout.Width(16));

        if (lNewIsEditorEnabled != lMotor.IsEditorEnabled)
        {
            lIsDirty = true;
            lMotor.IsEditorEnabled = lNewIsEditorEnabled;
        }

        GUILayout.FlexibleSpace();

        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();

        // Determines if we'll run in the scene editor
        bool lNewIsFixedUpdateEnabled = EditorGUILayout.Toggle(new GUIContent("Use Fixed Update", "Determines if we attempt to keep a stable update schedule. This is useful for physics simulations."), lMotor.IsFixedUpdateEnabled);

        if (lNewIsFixedUpdateEnabled != lMotor.IsFixedUpdateEnabled)
        {
            lIsDirty = true;
            lMotor.IsFixedUpdateEnabled = lNewIsFixedUpdateEnabled;
        }

        GUILayout.Space(20);
        EditorGUILayout.LabelField(new GUIContent("FPS", "Determines the frame rate we're targeting for fixed updates."), GUILayout.Width(30));
        int lNewFixedUpdateFPS = EditorGUILayout.IntField((int)lMotor.FixedUpdateFPS, GUILayout.Width(65));

        if (lNewFixedUpdateFPS != lMotor.FixedUpdateFPS)
        {
            lIsDirty = true;
            lMotor.FixedUpdateFPS = lNewFixedUpdateFPS;
        }

        GUILayout.FlexibleSpace();

        EditorGUILayout.EndHorizontal();

        // Determines if we'll run in the scene editor
        bool lNewShowDebug = EditorGUILayout.Toggle(new GUIContent("Is Debug Enabled", "Determines if we show debug information while running."), lMotor.IsDebugEnabled);

        if (lNewShowDebug != lMotor.IsDebugEnabled)
        {
            lIsDirty = true;
            lMotor.IsDebugEnabled = lNewShowDebug;
        }

        // Determine if we use the custom inspectior. We pass in the selected bones
        // and they may be edited by the motor's inspector
        bool lIsMotorDirty = lMotor.OnInspectorGUI(mSelectedBones);

        lIsDirty = lIsDirty || lIsMotorDirty;

        // Ensure we still have the right selected bones
        if (mSelectedBones.Count > 0 && mSelectedBone != mSelectedBones[0])
        {
            mSelectedBone = mSelectedBones[0];
        }

        return(lIsDirty);
    }
    /// <summary>
    /// Renders the motions for the specified list's index
    /// </summary>
    /// <param name="rName"></param>
    /// <param name="rLayerIndex"></param>
    private bool RenderMotorList()
    {
        bool lIsDirty = false;

        // If we don't have items in the list, display some help
        if (mSkeleton.Motors.Count == 0)
        {
            EditorGUILayout.HelpBox(mMotorHelp, MessageType.Info, true);
            return(false);
        }

        // Add a row for titles
        EditorGUILayout.BeginHorizontal();
        GUILayout.Space(24);
        EditorGUILayout.LabelField("Type", GUILayout.MinWidth(50));
        EditorGUILayout.LabelField("Name", GUILayout.MinWidth(50));
        EditorGUILayout.LabelField("Ena", GUILayout.Width(24));
        EditorGUILayout.LabelField("", GUILayout.Width(2));
        EditorGUILayout.EndHorizontal();

        // Cycle through the motions
        for (int i = 0; i < mSkeleton.Motors.Count; i++)
        {
            BoneControllerMotor lMotor = mSkeleton.Motors[i];
            if (lMotor == null)
            {
                continue;
            }

            GUIStyle lRowStyle = (mSelectedMotorIndex == i ? mSelectedRowStyle : mRowStyle);
            EditorGUILayout.BeginHorizontal(lRowStyle);

            if (GUILayout.Button(new GUIContent(mItemSelector), GUI.skin.label, GUILayout.Width(16)))
            {
                mSelectedMotorIndex = i;
            }

            Type lMotorType = lMotor.GetType();

            string   lMotorTypeName = lMotorType.Name;
            object[] lAttributes    = lMotorType.GetCustomAttributes(typeof(IKNameAttribute), true);
            foreach (IKNameAttribute lAttribute in lAttributes)
            {
                lMotorTypeName = lAttribute.Name;
            }

            EditorGUILayout.LabelField(lMotorTypeName, GUILayout.MinWidth(50));

            string lMotorName = EditorGUILayout.TextField(lMotor.Name, GUILayout.MinWidth(50));
            if (lMotorName != lMotor.Name)
            {
                lMotor.Name = lMotorName;
                lIsDirty    = true;
            }

            bool lMotorIsEnabled = EditorGUILayout.Toggle(lMotor.IsEnabled, GUILayout.Width(20));
            if (lMotorIsEnabled != lMotor.IsEnabled)
            {
                lMotor.IsEnabled = lMotorIsEnabled;
                lIsDirty         = true;
            }

            EditorGUILayout.EndHorizontal();
        }

        return(lIsDirty);
    }