/// <summary>
        /// Adds missing flakes on canvas
        /// </summary>
        /// <param name="top">true if flakes appear on top of canvas, false if random Y position</param>
        private void SetFlakes(bool top = false)
        {
            int      halfCanvasWidth = (int)canvas.ActualWidth / 2;
            Random   rand            = new Random();
            Image    flake;
            SnowInfo info;

            for (int i = flakes.Count; i < maxFlakes; i++)
            {
                flake = new Image();

                flake.Source  = CreateImage(flakeImages[rand.Next(0, flakeImages.Count)]);
                flake.Stretch = Stretch.Uniform;

                info = new SnowInfo(flake, VerticalSpeedRatio * rand.Next(minStartingSpeed, maxStartingSpeed),
                                    rand.Next(minRadius, MaxRadius));

                Canvas.SetLeft(flake, halfCanvasWidth + rand.Next(-halfCanvasWidth, halfCanvasWidth));
                if (!top)
                {
                    Canvas.SetTop(flake, rand.Next(0, (int)canvas.ActualHeight));
                }
                else
                {
                    Canvas.SetTop(flake, -info.Radius * 2);
                }
                canvas.Children.Add(flake);

                info.VelocityX = rand.Next(minHorizontalSpeed, maxHorizontalSpeed);
                flakes.Add(info);
            }
        }
        /// <summary>
        /// Render snow
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            Random   random = new Random();
            SnowInfo info   = null;
            double   left   = 0;
            double   top    = 0;

            if (!IsWorking)
            {
                return;
            }

            if (flakes.Count < maxFlakes)
            {
                SetFlakes(true);
                return;
            }

            for (int i = flakes.Count - 1; i >= 0; i--)
            {
                info = flakes[i];
                left = Canvas.GetLeft(info.Flake);
                top  = Canvas.GetTop(info.Flake);

                flakes[i].VelocityX += .5 * HorizontalSpeedRatio;

                Canvas.SetLeft(flakes[i].Flake, left + Math.Cos(flakes[i].VelocityX));
                Canvas.SetTop(info.Flake, top + 1 * info.VelocityY);

                if (top >= (canvas.ActualHeight + info.Radius * 2))
                {
                    flakes.Remove(info);
                    canvas.Children.Remove(info.Flake);
                }
            }
        }