/// <summary>
        /// Tiles the at position.
        /// </summary>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <returns>A TileMaskCollection.</returns>
        public TileMaskCollection TilesAtPosition(int x, int y, int width, int height)
        {
            TileMaskCollection find = new TileMaskCollection(BytesPerColor)
            {
                tiles = tiles.Where((t) =>
                {
                    if (t.X + t.Width < x + 1)
                    {
                        return(false);
                    }
                    if (x + width < t.X + 1)
                    {
                        return(false);
                    }
                    if (t.Y + t.Height < y + 1)
                    {
                        return(false);
                    }
                    if (y + height < t.Y + 1)
                    {
                        return(false);
                    }

                    return(true);
                }).ToList()
            };

            find.Sort();
            find.UpdateContainer();
            return(find);
        }
        /// <summary>
        /// Fusions the.
        /// </summary>
        /// <param name="c1">The c1.</param>
        /// <param name="c2">The c2.</param>
        /// <returns>A SpriteTileMaskCollection.</returns>
        public static TileMaskCollection Fusion(TileMaskCollection c1, TileMaskCollection c2)
        {
            if (c1 == null)
            {
                throw new ArgumentNullException(nameof(c1));
            }
            if (c2 == null)
            {
                throw new ArgumentNullException(nameof(c2));
            }
            c1.Sort();
            c2.Sort();

            var vals1 = c1.tiles;
            var vals2 = c2.tiles;

            TileMaskCollection ret = new TileMaskCollection(c1.BytesPerColor);

            int total = vals1.Count + vals2.Count;
            var enum1 = vals1.GetEnumerator();
            var enum2 = vals2.GetEnumerator();

            enum1.MoveNext();
            enum2.MoveNext();

            for (int i = 0; i < total; i++)
            {
                if (enum2.Current == null ||
                    (enum1.Current != null && enum1.Current.Z <= enum2.Current.Z))
                {
                    ret.tiles.Add(enum1.Current);
                    enum1.MoveNext();
                }
                else if (enum2.Current != null)
                {
                    ret.tiles.Add(enum2.Current);
                    enum2.MoveNext();
                }
            }

            ret.sorted = true;
            ret.Left   = Math.Min(c1.Left, c2.Left);
            if (ret.Left < 0)
            {
                ret.Left = Math.Max(c1.Left, c2.Left);
            }
            ret.Right = Math.Max(c1.Right, c2.Right);
            ret.Top   = Math.Min(c1.Top, c2.Top);
            if (ret.Top < 0)
            {
                ret.Top = Math.Max(c1.Top, c2.Top);
            }
            ret.Bottom = Math.Max(c1.Bottom, c2.Bottom);

            return(ret);
        }
        /// <summary>
        /// Decreases the selection z index.
        /// </summary>
        public bool DecreaseSelectionZIndex()
        {
            selection.Sort();

            uint     selMinZ  = selection.tiles.First().Z;
            uint     selMaxZ  = selection.tiles.Last().Z;
            TileMask MinZTile = tiles.FirstOrDefault(t =>
            {
                return(t.Z < selMinZ && !selection.tiles.Contains(t));
            });

            if (MinZTile != default(TileMask))
            {
                var upperTiles = tiles.Where(t =>
                {
                    return(t.Z < MinZTile.Z && !selection.tiles.Contains(t));
                });

                uint i = MinZTile.Z - 1;

                foreach (TileMask t in selection.tiles)
                {
                    t.Z = i;
                    i--;
                }

                foreach (TileMask t in upperTiles)
                {
                    t.Z = i;
                    i--;
                }
                sorted = false;
                Sort();
                OnSelectionZIndexChanged?.Invoke(this, selection);
                return(true);
            }
            return(false);
        }
 /// <summary>
 /// Adds the collection.
 /// </summary>
 /// <param name="col">The col.</param>
 public void AddCollection(TileMaskCollection col)
 {
     ClearSelection();
     if (col != null)
     {
         col.Sort();
         foreach (TileMask t in col.tiles)
         {
             Add(t);
         }
     }
     RequireRefresh = true;
     OnCollectionAdded?.Invoke(this, col);
 }