/*
         #region DistributeHorizontal Command
         *
         * private void DistributeHorizontal_Executed(object sender, ExecutedRoutedEventArgs e)
         * {
         *  var selectedItems = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
         *                      where item.ParentID == Guid.Empty
         *                      let itemLeft = Canvas.GetLeft(item)
         *                      orderby itemLeft
         *                      select item;
         *
         *  if (selectedItems.Count() > 1)
         *  {
         *      double left = Double.MaxValue;
         *      double right = Double.MinValue;
         *      double sumWidth = 0;
         *      foreach (DesignerItem item in selectedItems)
         *      {
         *          left = Math.Min(left, Canvas.GetLeft(item));
         *          right = Math.Max(right, Canvas.GetLeft(item) + item.Width);
         *          sumWidth += item.Width;
         *      }
         *
         *      double distance = Math.Max(0, (right - left - sumWidth) / (selectedItems.Count() - 1));
         *      double offset = Canvas.GetLeft(selectedItems.First());
         *
         *      foreach (DesignerItem item in selectedItems)
         *      {
         *          double delta = offset - Canvas.GetLeft(item);
         *          foreach (DesignerItem di in SelectionService.GetGroupMembers(item))
         *          {
         *              Canvas.SetLeft(di, Canvas.GetLeft(di) + delta);
         *          }
         *          offset = offset + item.Width + distance;
         *      }
         *  }
         * }
         *
         * private void Distribute_Enabled(object sender, CanExecuteRoutedEventArgs e)
         * {
         *  //var groupedItem = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
         *  //                  where item.ParentID == Guid.Empty
         *  //                  select item;
         *
         *
         *  //e.CanExecute = groupedItem.Count() > 1;
         *  e.CanExecute = true;
         * }
         *
         #endregion
         *
         #region DistributeVertical Command
         *
         * private void DistributeVertical_Executed(object sender, ExecutedRoutedEventArgs e)
         * {
         *  var selectedItems = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
         *                      where item.ParentID == Guid.Empty
         *                      let itemTop = Canvas.GetTop(item)
         *                      orderby itemTop
         *                      select item;
         *
         *  if (selectedItems.Count() > 1)
         *  {
         *      double top = Double.MaxValue;
         *      double bottom = Double.MinValue;
         *      double sumHeight = 0;
         *      foreach (DesignerItem item in selectedItems)
         *      {
         *          top = Math.Min(top, Canvas.GetTop(item));
         *          bottom = Math.Max(bottom, Canvas.GetTop(item) + item.Height);
         *          sumHeight += item.Height;
         *      }
         *
         *      double distance = Math.Max(0, (bottom - top - sumHeight) / (selectedItems.Count() - 1));
         *      double offset = Canvas.GetTop(selectedItems.First());
         *
         *      foreach (DesignerItem item in selectedItems)
         *      {
         *          double delta = offset - Canvas.GetTop(item);
         *          foreach (DesignerItem di in SelectionService.GetGroupMembers(item))
         *          {
         *              Canvas.SetTop(di, Canvas.GetTop(di) + delta);
         *          }
         *          offset = offset + item.Height + distance;
         *      }
         *  }
         * }
         *
         #endregion
         */
        #region SelectAll Command

        private void SelectAll_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SelectionService.SelectAll();
        }
        private void Paste_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            XElement root = LoadSerializedDataFromClipBoard();

            if (root == null)
            {
                return;
            }

            // create DesignerItems
            Dictionary <Guid, Guid> mappingOldToNewIDs = new Dictionary <Guid, Guid>();
            List <ISelectable>      newItems           = new List <ISelectable>();
            IEnumerable <XElement>  itemsXML           = root.Elements("DesignerItems").Elements("DesignerItem");

            double offsetX = Double.Parse(root.Attribute("OffsetX").Value, CultureInfo.InvariantCulture);
            double offsetY = Double.Parse(root.Attribute("OffsetY").Value, CultureInfo.InvariantCulture);

            foreach (XElement itemXML in itemsXML)
            {
                Guid oldID = new Guid(itemXML.Element("ID").Value);
                Guid newID = Guid.NewGuid();
                mappingOldToNewIDs.Add(oldID, newID);
                DesignerItem item = DeserializeDesignerItem(itemXML, newID, offsetX, offsetY);
                this.Children.Add(item);
                SetConnectorDecoratorTemplate(item);
                newItems.Add(item);
            }

            // update group hierarchy
            SelectionService.ClearSelection();
            foreach (DesignerItem el in newItems)
            {
                if (el.ParentID != Guid.Empty)
                {
                    el.ParentID = mappingOldToNewIDs[el.ParentID];
                }
            }


            foreach (DesignerItem item in newItems)
            {
                if (item.ParentID == Guid.Empty)
                {
                    SelectionService.AddToSelection(item);
                }
            }

            // create Connections
            IEnumerable <XElement> connectionsXML = root.Elements("Connections").Elements("Connection");

            foreach (XElement connectionXML in connectionsXML)
            {
                Guid oldSourceID = new Guid(connectionXML.Element("SourceID").Value);
                Guid oldSinkID   = new Guid(connectionXML.Element("SinkID").Value);

                if (mappingOldToNewIDs.ContainsKey(oldSourceID) && mappingOldToNewIDs.ContainsKey(oldSinkID))
                {
                    Guid newSourceID = mappingOldToNewIDs[oldSourceID];
                    Guid newSinkID   = mappingOldToNewIDs[oldSinkID];

                    String sourceConnectorName = connectionXML.Element("SourceConnectorName").Value;
                    String sinkConnectorName   = connectionXML.Element("SinkConnectorName").Value;

                    Connector sourceConnector = GetConnector(newSourceID, sourceConnectorName);
                    Connector sinkConnector   = GetConnector(newSinkID, sinkConnectorName);

                    Connection connection = new Connection(sourceConnector, sinkConnector);
                    Canvas.SetZIndex(connection, Int32.Parse(connectionXML.Element("zIndex").Value));
                    this.Children.Add(connection);

                    SelectionService.AddToSelection(connection);
                }
            }

            DesignerCanvas.BringToFront.Execute(null, this);

            // update paste offset
            root.Attribute("OffsetX").Value = (offsetX + 10).ToString();
            root.Attribute("OffsetY").Value = (offsetY + 10).ToString();
            Clipboard.Clear();
            Clipboard.SetData(DataFormats.Xaml, root);
        }