private void StartDragDrop(InputEventArgs e,
                                  ContentControl draggedElement,
                                  FrameworkElement dragSrc, //ScatterView or BadgeFolder
                                  ObservableCollection<object> srcCollection)
        {
            cursorState = new DragCursorState(draggedElement, dragSrc, srcCollection);

            ArgPoint argPtData = (draggedElement.DataContext as ArgPoint);
            BadgeFolder folderData = (draggedElement.Content as BadgeFolder);
            if (folderData == null)
            {
                if (draggedElement.Content is Viewbox)
                    folderData = (BadgeFolder)((Viewbox)draggedElement.Content).Child;                
            }

            // If the data has not been specified as draggable, 
            // or the ScatterViewItem cannot move, return.
            if (argPtData == null && folderData==null)
            {
                return;
            }

            // Set the dragged element. This is needed in case the drag operation is canceled.
            //data.DraggedElement = draggedElement;

            // Create the cursor visual.
            ContentControl cursorVisual = null;
            object data = null;
            if (argPtData != null)
            {
                data = argPtData;
                cursorVisual = new ContentControl()
                {
                    Content = argPtData,
                    Style = FindResource("BadgeCursorStyle") as Style
                };
            }
            else if (folderData != null)
            {
                data = folderData;
                cursorVisual = new ContentControl()
                {
                    Content = folderData.model,
                    Style = FindResource("FolderCursorStyle") as Style
                };
            }
                        
            SurfaceDragDrop.AddTargetChangedHandler(cursorVisual, TargetChanged);

            // Create a list of input devices, 
            // and add the device passed to this event handler.
            List<InputDevice> devices = new List<InputDevice>();
            devices.Add(e.Device);

            // If there are touch devices captured within the element,
            // add them to the list of input devices.
            foreach (InputDevice device in draggedElement.TouchesCapturedWithin)
            {
                if (device != e.Device)
                {
                    devices.Add(device);
                }
            }
            
            // Start the drag-and-drop operation.
            SurfaceDragCursor cursor =
                SurfaceDragDrop.BeginDragDrop(
                // The ScatterView object that the cursor is dragged out from.
                  dragSrc,
                // The ScatterViewItem object that is dragged from the drag source.
                  draggedElement,
                // The visual element of the cursor.
                  cursorVisual,
                // The data attached with the cursor.
                  data,
                // The input devices that start dragging the cursor.
                  devices,
                // The allowed drag-and-drop effects of the operation.
                  DragDropEffects.Move);

            // If the cursor was created, the drag-and-drop operation was successfully started.
            if (cursor != null)
            {
                // Hide the ScatterViewItem.
                draggedElement.Visibility = Visibility.Hidden;

                // This event has been handled.
                e.Handled = true;
            }
        }
        private void DragCanceled()
        {
            if (cursorState == null)
                return;

            if (cursorState.draggedItem is ScatterViewItem)
                (cursorState.draggedItem as ScatterViewItem).Visibility = Visibility.Visible;
            else if (cursorState.draggedItem is ListBoxItem)
                (cursorState.draggedItem as ListBoxItem).Visibility = Visibility.Visible;
            
            cursorState = null;

            dragDropTooltip.Content = "";

            unsolvedDragTapRecognizer.Stop();
            agreedDragTapRecognizer.Stop();
            disagreedDragTapRecognizer.Stop();
        }
        void ProcessDropTarget(SurfaceDragCursor cursor, 
                               ObservableCollection<object> src, 
                               ObservableCollection<object> dst,
                               int NewResolutionCode)
        {
            if (cursorState == null)
                return;

            bool handled = false; 
            if (cursor.DragSource == cursor.CurrentTarget || src == null || dst==null)
            {
                DragCanceled();                
            }  
            else 
            {
                switch(cursorState.Operation)
                {
                    case DragCursorState.OperationType.None:
                        break;
                    case DragCursorState.OperationType.ResolveAgreement:
                        if (cursor.Data is ArgPoint)
                        {
                            ArgPoint ap = cursor.Data as ArgPoint;
                            if (src.Contains(ap))
                                src.Remove(ap);
                            dst.Add(ap);
                            ap.AgreementCode = NewResolutionCode;
                            handled = true;
                        }
                        else if (cursor.Data is BadgeFolder)
                        {
                            int ResolutionCode = -1;

                            if (cursor.CurrentTarget == unsolved)
                                ResolutionCode = (int)AgreementCode.UnsolvedAndGrouped;
                            else if(cursor.CurrentTarget == agreement)
                                ResolutionCode = (int)AgreementCode.AgreedAndGrouped;
                            else if(cursor.CurrentTarget == disagreement)
                                ResolutionCode = (int)AgreementCode.DisagreedAndGrouped;

                            if (ResolutionCode != -1)
                            {
                                BadgeFolder bf = cursor.Data as BadgeFolder;

                               // ScatterViewItem 
                                FrameworkElement itemContainer = (FrameworkElement)bf.Parent;
                                if (itemContainer != null && itemContainer.Parent is ScatterViewItem)
                                    itemContainer = (FrameworkElement)itemContainer.Parent;

                                if (itemContainer != null && itemContainer is ScatterViewItem)
                                {
                                    if (src.Contains(itemContainer))
                                    {
                                        src.Remove(itemContainer);
                                    }

                                    if (itemContainer is ContentControl)
                                    {
                                        if ((itemContainer as ContentControl).Content is Viewbox)
                                            ((itemContainer as ContentControl).Content as Viewbox).Child = null;

                                        (itemContainer as ContentControl).Content = null;
                                    }

                                    if(cursor.CurrentTarget==unsolved)
                                        dst.Add(CreateContainer(bf));
                                    else
                                        dst.Add(CreateSmallContainer(bf));

                                    foreach (ArgPoint ap in bf.model.ArgPoint)
                                        ap.AgreementCode = ResolutionCode;
                                    handled = true;
                                }
                            }
                        }
                        break;
                    case DragCursorState.OperationType.MoveToGroup:
                        if (cursorState.currentTarget is BadgeFolder && 
                            cursorState.draggedItem is ScatterViewItem &&
                            (cursorState.draggedItem as ScatterViewItem).Content is ArgPoint)
                        {
                            if(MoveToGroup((BadgeFolder)cursorState.currentTarget,
                                          (ArgPoint)(cursorState.draggedItem as ScatterViewItem).Content))
                                handled = true;
                        }
                        break;
                    case DragCursorState.OperationType.MoveFromGroup:
                        if (cursorState.DragSrc is BadgeFolder &&
                            cursorState.currentTarget == unsolved &&
                            (cursorState.draggedItem as ListBoxItem).Content is ArgPoint)
                        {
                            MoveFromGroup((BadgeFolder)cursorState.DragSrc, 
                                          (ArgPoint)(cursorState.draggedItem as ListBoxItem).Content);
                            handled = true;
                        }
                        break;
                    case DragCursorState.OperationType.MergeWith:
                        if ((cursorState.draggedItem as ScatterViewItem).Content is ArgPoint)
                        {
                            Badge target = (Badge)cursorState.currentTarget;
                            MergeTwoBadges((ArgPoint)target.DataContext, 
                                           (ArgPoint)(cursorState.draggedItem as ScatterViewItem).Content);
                            handled = true;
                        }
                        break;
                }
            }

            DragCanceled();

            if (handled)
            {
                CtxSingleton.SaveChangesIgnoreConflicts();
                
                //reset sviRotationBlocked to force-align new badges at next tick 
                sviRotationBlocked = false;

                HighlightOwnSmallBadges();

                _sharedClient.clienRt.SendNotifyStructureChanged(selectedTopic.Id);
            }

            dragDropTooltip.Content = "";
            cursorState = null;
        }