// Manages the fade and slide animation
        private static async Task ManageXAMLTransformFadeSlideAnimationAsync(this UIElement element,
                                                                             double?startOp, double?endOp,
                                                                             TranslationAxis axis, double?startXY, double?endXY,
                                                                             int msOp, int?msSlide, int?msDelay, EasingFunctionNames easingFunction, bool reverse)
        {
            // Delay if necessary
            if (msDelay.HasValue)
            {
                await Task.Delay(msDelay.Value);
            }

            // Try to get the original starting value if necessary
            if (startXY == null && element.RenderTransform is TranslateTransform)
            {
                startXY = axis == TranslationAxis.X ? element.RenderTransform.To <TranslateTransform>().X : element.RenderTransform.To <TranslateTransform>().Y;
            }

            // Start and wait the animation
            DoubleAnimation opacity = XAMLTransformToolkit.CreateDoubleAnimation(element, "Opacity", startOp ?? element.Opacity, endOp, msOp, easingFunction);
            DoubleAnimation slide   = XAMLTransformToolkit.CreateDoubleAnimation(element.GetRenderTransform <TranslateTransform>(),
                                                                                 axis.ToPropertyString(), startXY, endXY,
                                                                                 msSlide ?? msOp, easingFunction);
            Storyboard storyboard = XAMLTransformToolkit.PrepareStory(opacity, slide);

            storyboard.AutoReverse = reverse;
            await storyboard.WaitAsync();
        }
        // Manages the scale animation
        private static async Task ManageXAMLTransformFadeScaleAnimationAsync(this UIElement element,
                                                                             double?startScale, double?endScale,
                                                                             int ms, int?msDelay, EasingFunctionNames easingFunction, bool reverse)
        {
            // Delay if necessary
            if (msDelay.HasValue)
            {
                await Task.Delay(msDelay.Value);
            }

            // Try to get the original starting values if necessary
            if (startScale == null && element.RenderTransform is ScaleTransform)
            {
                ScaleTransform scale = element.RenderTransform.To <ScaleTransform>();
                startScale = (scale.ScaleX + scale.ScaleY) / 2;
            }

            // Start and wait the animation
            DoubleAnimation scaleX = XAMLTransformToolkit.CreateDoubleAnimation(element.GetRenderTransform <ScaleTransform>(), "ScaleX",
                                                                                startScale, endScale, ms, easingFunction);
            DoubleAnimation scaleY = XAMLTransformToolkit.CreateDoubleAnimation(element.GetRenderTransform <ScaleTransform>(), "ScaleY",
                                                                                startScale, endScale, ms, easingFunction);
            Storyboard storyboard = XAMLTransformToolkit.PrepareStory(scaleX, scaleY);

            storyboard.AutoReverse = reverse;
            await storyboard.WaitAsync();
        }
        // Manages the fade animation
        private static async Task ManageXAMLTransformFadeAnimationAsync(this UIElement element,
                                                                        double?startOp, double?endOp,
                                                                        int ms, int?msDelay, EasingFunctionNames easingFunction, bool reverse)
        {
            // Delay if necessary
            if (msDelay.HasValue)
            {
                await Task.Delay(msDelay.Value);
            }

            // Start and wait the animation
            DoubleAnimation animation  = XAMLTransformToolkit.CreateDoubleAnimation(element, "Opacity", startOp ?? element.Opacity, endOp, ms, easingFunction);
            Storyboard      storyboard = XAMLTransformToolkit.PrepareStory(animation);

            storyboard.AutoReverse = reverse;
            await storyboard.WaitAsync();
        }
        /// <summary>
        /// Gets a looped storyboard that makes the opacity of the element go from to 0 to 1 and vice versa
        /// </summary>
        /// <param name="element">The element to animate</param>
        /// <param name="ms">The loop duration</param>
        public static Storyboard GetLoopedFadeStoryboard(this UIElement element, int ms)
        {
            DoubleAnimation backgroundAnimation = new DoubleAnimation
            {
                From           = 0,
                To             = 1,
                Duration       = new Duration(TimeSpan.FromMilliseconds(ms)),
                EasingFunction = new CircleEase {
                    EasingMode = EasingMode.EaseInOut
                },
                RepeatBehavior = RepeatBehavior.Forever,
                AutoReverse    = true
            };

            Storyboard.SetTarget(backgroundAnimation, element);
            Storyboard.SetTargetProperty(backgroundAnimation, "Opacity");
            return(XAMLTransformToolkit.PrepareStory(backgroundAnimation));
        }
        /// <summary>
        /// Slides a target element over a given axis
        /// </summary>
        /// <param name="element">The element to animate</param>
        /// <param name="axis">A String that indicates which axis to use with the TranslateTransform animation</param>
        /// <param name="startXY">The initial axis value</param>
        /// <param name="endXY">The final axis value</param>
        /// <param name="ms">The duration of the animation in milliseconds</param>
        /// <param name="easing">The easing function to use in the animation</param>
        public static Storyboard GetXAMLTransformSlideStoryboard(this UIElement element,
                                                                 TranslationAxis axis, double?startXY, double?endXY, int ms, EasingFunctionNames easing)
        {
            // Try to get the original starting value if necessary
            TranslateTransform translate = element.RenderTransform as TranslateTransform;
            bool cleanAnimation          = startXY != null;

            if (startXY == null && translate != null)
            {
                startXY = axis == TranslationAxis.X ? element.RenderTransform.To <TranslateTransform>().X : element.RenderTransform.To <TranslateTransform>().Y;
            }

            // Prepare and run the animation
            if (translate == null || cleanAnimation)
            {
                translate = new TranslateTransform();
                element.RenderTransform = translate;
            }
            return(XAMLTransformToolkit.PrepareStory(XAMLTransformToolkit.CreateDoubleAnimation(translate, axis.ToPropertyString(), startXY, endXY, ms, easing)));
        }