public Task <Point> DragAsync(TutorialControl control, PointerRoutedEventArgs origE, IDragAndDropProgress progress = null)
        {
            TaskCompletionSource <Point> taskCompletionSource = new TaskCompletionSource <Point>();
            UIElement mousePositionWindow = Window.Current.Content;
            Point     pointMouseDown      = origE.GetCurrentPoint(mousePositionWindow).Position;

            PointerEventHandler pointerMovedHandler    = null;
            PointerEventHandler pointerReleasedHandler = null;

            pointerMovedHandler = (Object s, PointerRoutedEventArgs e) =>
            {
                Point pt    = e.GetCurrentPoint(mousePositionWindow).Position;
                Point delta = new Point();
                delta.X = pt.X - pointMouseDown.X;
                delta.Y = pt.Y - pointMouseDown.Y;



                if (progress != null)
                {
                    progress.Report(pt);
                }


                this.TranlateReletive(delta);
                pointMouseDown = pt;
            };

            pointerReleasedHandler = (Object s, PointerRoutedEventArgs e) =>
            {
                TutorialControl localControl = (TutorialControl)s;
                localControl.PointerMoved    -= pointerMovedHandler;
                localControl.PointerReleased -= pointerReleasedHandler;
                localControl.ReleasePointerCapture(origE.Pointer);
                Point exitPoint = e.GetCurrentPoint(mousePositionWindow).Position;

                if (progress != null)
                {
                    progress.PointerUp(exitPoint);
                }

                taskCompletionSource.SetResult(exitPoint);
            };

            control.CapturePointer(origE.Pointer);
            control.PointerMoved    += pointerMovedHandler;
            control.PointerReleased += pointerReleasedHandler;
            return(taskCompletionSource.Task);
        }
        public Task <Point> DragAsync(CardContainer container, CardView card, PointerRoutedEventArgs origE, DragList dragList, IDragAndDropProgress progress = null)
        {
            TaskCompletionSource <Point> taskCompletionSource = new TaskCompletionSource <Point>();
            UIElement mousePositionWindow = Window.Current.Content;
            Point     pointMouseDown      = origE.GetCurrentPoint(mousePositionWindow).Position;

            card.PushCard(true);
            bool dragging = false;

            if (dragList.Contains(card) == false)
            {
                dragList.Insert(0, card); // card you clicked is always the first one
            }
            PointerEventHandler pointerMovedHandler    = null;
            PointerEventHandler pointerReleasedHandler = null;

            pointerMovedHandler = (Object s, PointerRoutedEventArgs e) =>
            {
                Point pt    = e.GetCurrentPoint(mousePositionWindow).Position;
                Point delta = new Point();
                delta.X = pt.X - pointMouseDown.X;
                delta.Y = pt.Y - pointMouseDown.Y;

                CardView localCard    = (CardView)s;
                bool     reorderCards = false;
                //
                //  fixup our lists
                foreach (var c in this.SelectedCards)
                {
                    if (dragList.Contains(c) == false)
                    {
                        dragList.Add(c);
                    }
                }

                if (dragList.Contains(localCard) == false)
                {
                    dragList.Add(localCard);
                }

                if (dragList.Count > _maxSelected)
                {
                    CardView c = this.FirstSelectedCard;
                    c.Selected = false;
                    dragList.Remove(c);
                    c.UpdateLayout();
                }



                if (Math.Abs(delta.X - MOUSE_MOVE_SENSITIVITY) > 0 || Math.Abs(delta.Y - MOUSE_MOVE_SENSITIVITY) > 0)
                {
                    dragging = true;
                }

                //
                //  check to see if we have moved out of the container in the Y direction
                if (container.HitTest(pt))
                {
                    reorderCards = true;
                }

                if (dragList.Count > 1)
                {
                    reorderCards = false;
                    CardView otherCard = dragList[0];
                    double   cardWidth = card.CardWidth;
                    if (card.Index == otherCard.Index)
                    {
                        otherCard = dragList[1];
                    }

                    //
                    //  this moves the card to make space for reordering
                    int left = (int)(card.AnimationPosition.X - otherCard.AnimationPosition.X);

                    if (left > cardWidth)
                    {
                        otherCard.AnimateToReletiveAsync(new Point(left - cardWidth, 0), 0);
                        return;
                    }
                    else if (left < -card.CardWidth)
                    {
                        otherCard.AnimateToReletiveAsync(new Point(left + cardWidth, 0), 0);
                        return;
                    }
                }

                if (progress != null)
                {
                    progress.Report(pt);
                }

                foreach (CardView c in dragList)
                {
                    c.AnimateToReletiveAsync(delta);
                }

                if (reorderCards)
                {
                    int indexOfDraggedCard = container.Items.IndexOf(card);

                    if (delta.X > 0)
                    {
                        if (indexOfDraggedCard < container.Items.Count - 1)
                        {
                            CardView cardToMove = container.Items[indexOfDraggedCard + 1];
                            if (card.AnimationPosition.X + card.CardWidth * 0.5 > cardToMove.AnimationPosition.X)
                            {
                                cardToMove.AnimateToReletiveAsync(new Point(-card.CardWidth, 0), MainPage.AnimationSpeeds.VeryFast);
                                container.Items.Remove(card);
                                container.Items.Insert(container.Items.IndexOf(cardToMove) + 1, card);
                            }
                        }
                    }
                    else //moving left
                    {
                        if (indexOfDraggedCard > 0)
                        {
                            CardView cardToMove = container.Items[indexOfDraggedCard - 1];
                            if (card.AnimationPosition.X - card.CardWidth * 0.5 < cardToMove.AnimationPosition.X)
                            {
                                cardToMove.AnimateToReletiveAsync(new Point(card.CardWidth, 0), MainPage.AnimationSpeeds.VeryFast);
                                container.Items.Remove(card);
                                container.Items.Insert(container.Items.IndexOf(cardToMove), card);
                            }
                        }
                    }
                }


                pointMouseDown = pt;
            };

            pointerReleasedHandler = (Object s, PointerRoutedEventArgs e) =>
            {
                CardView localCard = (CardView)s;
                localCard.PointerMoved    -= pointerMovedHandler;
                localCard.PointerReleased -= pointerReleasedHandler;
                localCard.ReleasePointerCapture(origE.Pointer);
                localCard.PushCard(false);
                if (!dragging)
                {
                    ToggleSelectCard(card);
                    dragList.Clear();
                }



                Point exitPoint = e.GetCurrentPoint(mousePositionWindow).Position;

                if (progress != null)
                {
                    progress.PointerUp(exitPoint);
                }

                //if (container.HitTest(exitPoint) == true) // you landed where you started
                //    container.UpdateCardLayoutAsync(500, false);

                //
                //  returns the point that the mouse was released.  the _selectedCards list
                //  will have the cards that were selected.  if dragging occurred, the card(s)
                //  will be in the _draggingList
                taskCompletionSource.SetResult(exitPoint);
            };

            card.CapturePointer(origE.Pointer);
            card.PointerMoved    += pointerMovedHandler;
            card.PointerReleased += pointerReleasedHandler;
            return(taskCompletionSource.Task);
        }