public static void PlayPauseAnimation()
    {
        SanctuaryPet pet = SanctuaryManager.pCurPetInstance;

        if (pet == null)
        {
            return;
        }

        string         targetAnimation = GetSelectedAnimation();
        AnimationState animState       = pet.animation[targetAnimation];

        if (animState == null)
        {
            return;
        }

        if (animState.speed == 0f)
        {
            animState.speed = 1f;
            ShowPauseIcon();
        }
        else
        {
            animState.speed = 0f;
            ShowPlayIcon();
        }
        PlayAnim(targetAnimation);
    }
    public static void ChangeAnimation(string animationName)
    {
        SanctuaryPet pet = SanctuaryManager.pCurPetInstance;

        if (pet == null)
        {
            return;
        }

        AnimationState animState = pet.animation[animationName];

        if (animState == null)
        {
            return;
        }

        animState.time       = 0f;
        frameSlider.maxValue = animState.length;
        if (configHolder != null && configHolder.config != null && configHolder.config.animPlayerPlayByDefault)
        {
            //if explicitely stated so, play the animation
            animState.speed = 1f;
            ShowPauseIcon();
        }
        else
        {
            //otherwise pause it
            animState.speed = 0f;
            ShowPlayIcon();
        }
        PlayAnim(animationName);
    }
    private static void UpdateAnimUI()
    {
        SanctuaryPet pet             = SanctuaryManager.pCurPetInstance;
        string       targetAnimation = GetSelectedAnimation();

        if (pet == null || targetAnimation == null || pet.animation[targetAnimation] == null)
        {
            return;
        }

        AnimationState animState    = pet.animation[targetAnimation];
        float          animProgress = animState.time;

        if (animProgress > animState.length)
        {
            animProgress = animProgress % animState.length;
        }
        SetSliderValue(animProgress);

        if (frameInputField != null && !frameInputField.isFocused)
        {
            SetFrameInputText(animProgress.ToString());
        }

        if (speedInputField != null && !speedInputField.isFocused)
        {
            SetSpeedInputText(animState.speed.ToString());
        }
    }
    /*============================================================================
     * OnClickListeners */

    private static void FindAnimationsClicked()
    {
        StoreAnimationStates();

        if (animationDropdown == null)
        {
            return;
        }

        SanctuaryPet pet = SanctuaryManager.pCurPetInstance;

        if (pet == null || pet.animation == null)
        {
            return;
        }

        animationDropdown.ClearOptions();
        List <string> animOptions = new List <string>();

        foreach (AnimationState state in pet.animation)
        {
            animOptions.Add(state.name);
        }
        animationDropdown.AddOptions(animOptions);
        ChangeAnimation(animOptions[0]);
    }
    private static void PlayAnim(string name)
    {
        SanctuaryPet pet = SanctuaryManager.pCurPetInstance;

        if (pet == null)
        {
            return;
        }
        if (pet.animation[name] == null)
        {
            return;
        }

        pet.animation[name].wrapMode = WrapMode.Loop;
        pet.animation.Play(name, PlayMode.StopAll);
    }
    private static void RestoreAnimationStates()
    {
        SanctuaryPet pet = SanctuaryManager.pCurPetInstance;

        if (pet == null || pet.animation == null)
        {
            return;
        }

        foreach (KeyValuePair <string, AnimationState> kvp in animationDict)
        {
            AssignAnimationState(kvp.Value, pet.animation[kvp.Key]);
        }

        animationDict.Clear();
    }
    public static void GoToAnimationTimestamp(float time)
    {
        SanctuaryPet pet = SanctuaryManager.pCurPetInstance;

        if (pet == null)
        {
            return;
        }

        string         targetAnimation = GetSelectedAnimation();
        AnimationState animState       = pet.animation[targetAnimation];

        if (animState == null)
        {
            return;
        }

        animState.time = time;
        PlayAnim(targetAnimation);
    }
    /* Update
     * ============================================================================*/

    /*============================================================================
     * Animation Control */

    private static void StoreAnimationStates()
    {
        SanctuaryPet pet = SanctuaryManager.pCurPetInstance;

        if (pet == null || pet.animation == null)
        {
            return;
        }

        if (animationDict.Count != 0)
        {
            RestoreAnimationStates();
        }

        foreach (AnimationState state in pet.animation)
        {
            AnimationState result = new AnimationState();
            AssignAnimationState(state, result);
            animationDict[state.name] = result;
        }
    }
    public static void SetAnimSpeed(float speed)
    {
        SanctuaryPet pet             = SanctuaryManager.pCurPetInstance;
        string       targetAnimation = GetSelectedAnimation();

        if (pet == null || targetAnimation == null || pet.animation[targetAnimation] == null)
        {
            return;
        }

        pet.animation[targetAnimation].speed = speed;
        PlayAnim(targetAnimation);

        if (speed > 0f)
        {
            ShowPauseIcon();
        }
        else
        {
            ShowPlayIcon();
        }
    }