/// <summary>
 /// Swap items between two cells
 /// </summary>
 /// <param name="firstCell"> Cell </param>
 /// <param name="secondCell"> Cell </param>
 public void SwapItems(DragAndDropCell firstCell, DragAndDropCell secondCell)
 {
     if ((firstCell != null) && (secondCell != null))
     {
         DragAndDropItem firstItem  = firstCell.GetItem();                               // Get item from first cell
         DragAndDropItem secondItem = secondCell.GetItem();                              // Get item from second cell
         // Swap items
         if (firstItem != null)
         {
             firstItem.transform.SetParent(secondCell.transform, false);
             firstItem.transform.localPosition = Vector3.zero;
             firstItem.MakeRaycast(true);
         }
         if (secondItem != null)
         {
             secondItem.transform.SetParent(firstCell.transform, false);
             secondItem.transform.localPosition = Vector3.zero;
             secondItem.MakeRaycast(true);
         }
         // Update states
         firstCell.UpdateMyItem();
         secondCell.UpdateMyItem();
         firstCell.UpdateBackgroundState();
         secondCell.UpdateBackgroundState();
     }
 }
        /// <summary>
        /// This item started to drag.
        /// </summary>
        /// <param name="eventData"></param>
        public void OnBeginDrag(PointerEventData eventData)
        {
            if (dragDisabled == false)
            {
                sourceCell  = GetCell();                                                                        // Remember source cell
                draggedItem = this;                                                                             // Set as dragged item
                // Create item's icon
                icon = new GameObject();
                icon.transform.SetParent(canvas.transform);
                icon.name = "Icon";
                Image myImage = GetComponent <Image>();
                myImage.raycastTarget = false;                                                          // Disable icon's raycast for correct drop handling
                Image iconImage = icon.AddComponent <Image>();
                iconImage.raycastTarget = false;
                iconImage.sprite        = myImage.sprite;
                RectTransform iconRect = icon.GetComponent <RectTransform>();
                // Set icon's dimensions
                RectTransform myRect = GetComponent <RectTransform>();
                iconRect.pivot     = new Vector2(0.5f, 0.5f);
                iconRect.anchorMin = new Vector2(0.5f, 0.5f);
                iconRect.anchorMax = new Vector2(0.5f, 0.5f);
                iconRect.sizeDelta = new Vector2(myRect.rect.width, myRect.rect.height);

                if (OnItemDragStartEvent != null)
                {
                    OnItemDragStartEvent(this);                                                                         // Notify all items about drag start for raycast disabling
                }
            }
        }
 /// <summary>
 /// Resets all temporary conditions.
 /// </summary>
 private void ResetConditions()
 {
     if (icon != null)
     {
         Destroy(icon);                                                                          // Destroy icon on item drop
     }
     if (OnItemDragEndEvent != null)
     {
         OnItemDragEndEvent(this);                                                                       // Notify all cells about item drag end
     }
     draggedItem = null;
     icon        = null;
     sourceCell  = null;
 }
 /// <summary>
 /// Put item into this cell.
 /// </summary>
 /// <param name="item">Item.</param>
 private void PlaceItem(DragAndDropItem item)
 {
     if (item != null)
     {
         DestroyItem();                                                                  // Remove current item from this cell
         myDadItem = null;
         DragAndDropCell cell = item.GetComponentInParent <DragAndDropCell>();
         if (cell != null)
         {
             if (cell.unlimitedSource == true)
             {
                 string itemName = item.name;
                 item      = Instantiate(item);                                                  // Clone item from source cell
                 item.name = itemName;
             }
         }
         item.transform.SetParent(transform, false);
         item.transform.localPosition = Vector3.zero;
         item.MakeRaycast(true);
         myDadItem = item;
     }
     UpdateBackgroundState();
 }
        /// <summary>
        /// Item is dropped in this cell
        /// </summary>
        /// <param name="data"></param>
        public void OnDrop(PointerEventData data)
        {
            if (DragAndDropItem.icon == null)
            {
                return;
            }
            DragAndDropItem item       = DragAndDropItem.draggedItem;
            DragAndDropCell sourceCell = DragAndDropItem.sourceCell;

            if (DragAndDropItem.icon.activeSelf == true)                                // If icon inactive do not need to drop item into cell
            {
                if ((item != null) && (sourceCell != this))
                {
                    if (!section.Equals(item.section))
                    {
                        return;
                    }

                    if ((!slot.Equals(item.slot)) && (!slot.Equals(DragAndDrop.Slot.Everything)))
                    {
                        return;
                    }

                    DropEventDescriptor desc = new DropEventDescriptor();
                    switch (cellType)                                                           // Check this cell's type
                    {
                    case CellType.Swap:                                                         // Item in destination cell can be swapped
                        UpdateMyItem();
                        switch (sourceCell.cellType)
                        {
                        case CellType.Swap:                                                                 // Item in source cell can be swapped
                            // Fill event descriptor
                            desc.item            = item;
                            desc.sourceCell      = sourceCell;
                            desc.destinationCell = this;
                            SendRequest(desc);                                                                  // Send drop request
                            StartCoroutine(NotifyOnDragEnd(desc));                                              // Send notification after drop will be finished
                            if (desc.permission == true)                                                        // If drop permitted by application
                            {
                                if (myDadItem != null)                                                          // If destination cell has item
                                {
                                    // Fill event descriptor
                                    DropEventDescriptor descAutoswap = new DropEventDescriptor();
                                    descAutoswap.item            = myDadItem;
                                    descAutoswap.sourceCell      = this;
                                    descAutoswap.destinationCell = sourceCell;
                                    SendRequest(descAutoswap);                                                                          // Send drop request
                                    StartCoroutine(NotifyOnDragEnd(descAutoswap));                                                      // Send notification after drop will be finished
                                    if (descAutoswap.permission == true)                                                                // If drop permitted by application
                                    {
                                        SwapItems(sourceCell, this);                                                                    // Swap items between cells
                                    }
                                    else
                                    {
                                        PlaceItem(item);                                                                    // Delete old item and place dropped item into this cell
                                    }
                                }
                                else
                                {
                                    PlaceItem(item);                                                                    // Place dropped item into this empty cell
                                }
                            }
                            break;

                        default:                                                                            // Item in source cell can not be swapped
                            // Fill event descriptor
                            desc.item            = item;
                            desc.sourceCell      = sourceCell;
                            desc.destinationCell = this;
                            SendRequest(desc);                                                                  // Send drop request
                            StartCoroutine(NotifyOnDragEnd(desc));                                              // Send notification after drop will be finished
                            if (desc.permission == true)                                                        // If drop permitted by application
                            {
                                PlaceItem(item);                                                                // Place dropped item into this cell
                            }
                            break;
                        }
                        break;

                    case CellType.DropOnly:                                                         // Item only can be dropped into destination cell
                        // Fill event descriptor
                        desc.item            = item;
                        desc.sourceCell      = sourceCell;
                        desc.destinationCell = this;
                        SendRequest(desc);                                                              // Send drop request
                        StartCoroutine(NotifyOnDragEnd(desc));                                          // Send notification after drop will be finished
                        if (desc.permission == true)                                                    // If drop permitted by application
                        {
                            PlaceItem(item);                                                            // Place dropped item in this cell
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
            if (item != null)
            {
                if (item.GetComponentInParent <DragAndDropCell>() == null)                  // If item have no cell after drop
                {
                    Destroy(item.gameObject);                                               // Destroy it
                }
            }
            UpdateMyItem();
            UpdateBackgroundState();
            sourceCell.UpdateMyItem();
            sourceCell.UpdateBackgroundState();
        }