/// <summary>
        /// Sets Source for the first available image control on each new photo that's been added.
        /// </summary>
        /// <param name="layoutGrid">Layout grid whose Photo collection just got a new photo.</param>
        /// <param name="photo">The photo being added.</param>
        private static void OnNewPhotoAdded(LayoutGrid layoutGrid, Photo photo)
        {
            System.Diagnostics.Debug.WriteLine($"PhotoCollectionChanged -> Added {photo}");

            // Go through every image control and set the Source for the first one that doesn't host a photo/image, i.e. whose Source == null
            for (int i = 0; i < layoutGrid.images.Count; i++)
            {
                if (layoutGrid.images[i].Source == null)
                {
                    // Resets image control's scale and translate transforms so it doesn't use the last photo's values
                    layoutGrid.images[i].RenderTransform = new MatrixTransform();

                    if (layoutGrid.PhotoType == BitmapType.Thumbnail)
                    {
                        layoutGrid.images[i].Source = photo.Thumbnail;
                    }
                    else
                    {
                        // Display the Sand clock until the photo is loaded
                        layoutGrid.images[i].Source = new BitmapImage(new Uri(Environment.CurrentDirectory + @"..\..\..\Images\Sand clock.png"));

                        // This layout grid is the one the user will be using for manipulating individual photos
                        ThreadPool.QueueUserWorkItem((obj) =>
                        {
                            photo.RefreshBitmapSource(BitmapType.PreviewBitmap);
                            Application.Current.Dispatcher.BeginInvoke((Action)(() => layoutGrid.images[i].Source = photo.PreviewBitmap), System.Windows.Threading.DispatcherPriority.ApplicationIdle);
                        });
                    }

                    // Each individual photo can only be displayed once in the grid, so no need for continuation of the for loop -> the photo has been added
                    return;
                }
            }
        }
        /// <summary>
        /// Adds a new row to the specified layout grid. If the new row is at first position
        /// adds a new column first and a sub grid, which will hold the new row.
        /// </summary>
        /// <param name="row">Index of the new row.</param>
        /// <param name="col">Column in which the row will reside.</param>
        /// <param name="layoutGrid">Layout grid that is getting a new row.</param>
        private static void AddRowFirst(int row, int col, LayoutGrid layoutGrid)
        {
            Grid subGrid;

            // Check if a new column should be added (row with index 0 is next)
            if (row == 0)
            {
                // Add new column to the layout grid
                layoutGrid.ColumnDefinitions.Add(new ColumnDefinition());

                // Add sub grid to the layout grid and set its column to the current column
                subGrid = new Grid();
                Grid.SetColumn(subGrid, col);
                layoutGrid.Children.Add(subGrid);
            }
            else
            {
                // Sub grid was already created and added to the layout grid's children
                subGrid = layoutGrid.Children[col] as Grid;
            }

            // Add new row to the sub grid
            subGrid.RowDefinitions.Add(new RowDefinition());

            // Remove first manipulation border from the layotu grid and add it to the sub grid (the border cannot be a logical child of 2 panles)
            ManipulationBorder border = layoutGrid.borders[0];

            layoutGrid.borders.RemoveAt(0);
            subGrid.Children.Add(border);

            // Set row for the manipulation border
            Grid.SetRow(border, row);
        }
 /// <summary>
 /// Binds the count of photos to the private CellCount dependency property.
 /// </summary>
 /// <param name="d">LayoutGrid for which the binding is done.</param>
 /// <param name="collection">The collection of photos in Photos property.</param>
 private static void BindCellCountToPhotosCount(LayoutGrid layoutGrid, ObservableCollection <Photo> collection)
 {
     if (layoutGrid != null)
     {
         Binding cellCountBinding = new Binding("Count");
         cellCountBinding.Source = collection;
         layoutGrid.SetBinding(CellCountProperty, cellCountBinding);
     }
 }
 /// <summary>
 /// Rearanges images by moving every image source 1 image control to the left practically removing
 /// the photo on the starting image and making the last 2 image control Sources duplicates.
 /// </summary>
 /// <param name="layoutGrid">Layout grid whose images are being rearanged.</param>
 /// <param name="photoIndex">Starting index of the image whose Source is changing.</param>
 private static void RearangeImages(LayoutGrid layoutGrid, int photoIndex)
 {
     for (int i = photoIndex; i < layoutGrid.images.Count - 1; i++)
     {
         // Sets render transform of the next image to the current one, because its Source will hold the next image's Source as well
         layoutGrid.images[i].RenderTransform = layoutGrid.images[i + 1].RenderTransform;
         layoutGrid.images[i].Source          = layoutGrid.images[i + 1].Source;
     }
 }
        /// <summary>
        /// Resolves addition, removal and swapping/replacing of photos in the layout grid
        /// and binds cell count (private dependency property) to the count of photos in the new collection.
        /// </summary>
        private static void OnPhotosChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            LayoutGrid layoutGrid = d as LayoutGrid;

            if (layoutGrid == null)
            {
                return;
            }

            NotifyCollectionChangedEventHandler handler = (sender, collectionChangedEventArgs) =>
            {
                var   action = collectionChangedEventArgs.Action;
                Photo photo;
                switch (action)
                {
                case NotifyCollectionChangedAction.Add:
                    photo = (Photo)collectionChangedEventArgs.NewItems[0];
                    OnNewPhotoAdded(layoutGrid, photo);
                    break;

                case NotifyCollectionChangedAction.Remove:
                    photo = (Photo)collectionChangedEventArgs.OldItems[0];
                    OnPhotoRemoved(layoutGrid, photo);
                    break;

                case NotifyCollectionChangedAction.Move:
                    // TODO Determine how to resolve Replace function, as there must always be 2 Move operations for swapping/replacing
                    // Or if Remove, Add and another Remove, Add will be used to swap 2 Photos
                    break;
                }
            };

            var oldCollection = e.OldValue as ObservableCollection <Photo>;

            if (oldCollection != null)
            {
                // TODO Determine if this is necessary for releasing memory, i.e. if this can really cause memory leak
                oldCollection.Clear();
                oldCollection.CollectionChanged -= handler;
                GC.Collect();
            }

            var newCollection = e.NewValue as ObservableCollection <Photo>;

            if (newCollection != null)
            {
                newCollection.CollectionChanged += handler;
            }

            BindCellCountToPhotosCount(layoutGrid, newCollection);
        }
        /// <summary>
        /// Checks if the photo type is Thumbnail and if it is disables manipulation of all image controls for the layout grid.
        /// </summary>
        private static void OnPhotoTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            LayoutGrid layoutGrid = d as LayoutGrid;
            BitmapType type       = (BitmapType)e.NewValue;

            if (layoutGrid != null && type == BitmapType.Thumbnail)
            {
                // This layout grid is one of many displaying possible layouts that the user can choose from
                // and it must not have the option of manipulating individual photos
                foreach (Image img in layoutGrid.images)
                {
                    img.IsHitTestVisible = false;
                }
            }
        }
        /// <summary>
        /// Updates layout grid by specified action. Either by adding new rows/columns for the new photo or removing them.
        /// </summary>
        /// <param name="layoutGrid">LayoutGrid whose layout is updated.</param>
        /// <param name="action">Action with which to update the layout.</param>
        private static void UpdateLayout(LayoutGrid layoutGrid, LayoutAction action)
        {
            int  cellCount   = layoutGrid.CellCount;
            byte rowCount    = layoutGrid.LayoutMatrix[0];
            byte columnCount = layoutGrid.LayoutMatrix[1];

            // Depending on the layout orientation, whether new columns are added first or new rows, different methods are called
            if (layoutGrid.LayoutOrientation == LayoutOrientation.ColumnFirst)
            {
                UpdateLayoutColumnFirst(rowCount, columnCount, cellCount, layoutGrid, action);
            }
            else
            {
                UpdateLayoutRowFirst(rowCount, columnCount, cellCount, layoutGrid, action);
            }
        }
        /// <summary>
        /// Call update to layout depending on whether the cell count increased or decreased.
        /// </summary>
        private static void OnCellCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            LayoutGrid layoutGrid = d as LayoutGrid;

            if (layoutGrid != null)
            {
                if ((int)e.NewValue > (int)e.OldValue)
                {
                    // Cell count increased, meaning some photo was added
                    UpdateLayout(layoutGrid, LayoutAction.Addition);
                }
                else
                {
                    // Cell count decreased, meaning some photo was removed
                    UpdateLayout(layoutGrid, LayoutAction.Removal);
                }
            }
        }
        /// <summary>
        /// Sets Source to null for the image that previously held the specified photo.
        /// </summary>
        /// <param name="layoutGrid">Layout grid from whose Photo collection the photo is removed.</param>
        /// <param name="photo">The photo being removed.</param>
        private static void OnPhotoRemoved(LayoutGrid layoutGrid, Photo photo)
        {
            System.Diagnostics.Debug.WriteLine($"PhotoCollectionChanged -> Removed {photo}");

            // Go through every image control and see if it hosts the photo (either a Thumbnail or a PreviewBitmap version) and set its Source to null
            for (int i = 0; i < layoutGrid.images.Count; i++)
            {
                if (layoutGrid.images[i].Source != null && (layoutGrid.images[i].Source == photo.Thumbnail || layoutGrid.images[i].Source == photo.PreviewBitmap))
                {
                    RearangeImages(layoutGrid, i);
                    layoutGrid.images[layoutGrid.images.Count - 1].Source = null; // After rearange the last image is redundant (in most cases it's a duplicate of the next to last)
                    photo.PreviewBitmap = null;

                    // Each individual photo can only be displayed once in the grid, so no need for continuation of the for loop -> the one photo has been removed
                    return;
                }
            }
        }
        /// <summary>
        /// Changes LayoutOrientation if certain combination of LayoutMatrix and LayoutOrientation values are met.
        /// </summary>
        private static void OnLayoutMatrixChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            LayoutGrid layoutGrid = d as LayoutGrid;

            if (layoutGrid == null)
            {
                return;
            }

            if ((byte[])e.NewValue == Constants.JustColumnsLayout && layoutGrid.LayoutOrientation == LayoutOrientation.RowFirst)
            {
                // LayoutMatrix is set to JustColumnsLayout and infers just a columns layout, so LayoutOrientation must be changed to ColumnFirst
                layoutGrid.LayoutOrientation = LayoutOrientation.ColumnFirst;
            }
            else if ((byte[])e.NewValue == Constants.JustRowsLayout && layoutGrid.LayoutOrientation == LayoutOrientation.ColumnFirst)
            {
                // LayoutMatrix is set to JustRowssLayout and infers just a rows layout, so LayoutOrientation must be changed to RowFirst
                layoutGrid.LayoutOrientation = LayoutOrientation.RowFirst;
            }
        }
        /// <summary>
        /// Coerces the MinPhotoCount property to acceptable value. If the value is below 0 coerces it to 0,
        /// and if it's above <see cref="Constants.MaxSelectedPhotos"/> limit is set to that value.
        /// </summary>
        /// <param name="d">LayoutGrid whose property is being coerced.</param>
        /// <param name="baseValue">Specified value for the MinPhotoCount property.</param>
        /// <returns>Returns 0 if the value is negative, or <see cref="Constants.MaxSelectedPhotos"/> if it's above that value.</returns>
        private static object OnMinPhotoCountCoerceValue(DependencyObject d, object baseValue)
        {
            LayoutGrid layoutGrid = d as LayoutGrid;

            if (layoutGrid == null)
            {
                // TODO Decide if validation should be used instead and throw an exception
                return(0);
            }

            int count = (int)baseValue;

            if (count < 0)
            {
                count = 0;
            }
            else if (count > Constants.MaxSelectedPhotos)
            {
                count = Constants.MaxSelectedPhotos;
            }
            return(count);
        }
        /// <summary>
        /// Removes the last row from the specified layout grid. If the row is at first position
        /// removes the whole column with its sub grid.
        /// </summary>
        /// <param name="rowCount">Max row count of the final layout.</param>
        /// <param name="cellCount">Number of cells - photos currently in the grid.</param>
        /// <param name="col">Column in which the row resides.</param>
        /// <param name="layoutGrid">Layout grid from which a row is removed.</param>
        private static void RemoveRowFirst(byte rowCount, int cellCount, int col, LayoutGrid layoutGrid)
        {
            Grid subGrid;
            ManipulationBorder border;

            // Check if with the last row addition a new column was also added (with a new sub grid)
            if (cellCount % rowCount == 0)
            {
                // Column that was added in the last row addition
                col = cellCount / rowCount;
                // Sub grid that was added to the above column in the last row addition
                subGrid = layoutGrid.Children[col] as Grid;

                // Remove sub grid's only child, which is a manipulation border, and give it back to the layout grid borders (insert at first position)
                border = (ManipulationBorder)(subGrid.Children[0]);
                subGrid.Children.RemoveAt(0);
                layoutGrid.borders.Insert(0, border);

                // Remove sub grid from layout grid (along with its row)
                layoutGrid.Children.Remove(subGrid);

                // Remove the last column
                layoutGrid.ColumnDefinitions.RemoveAt(col);
            }
            else // Entire column doesn't need to be removed, just its last row
            {
                // Sub grid of the layout grid which holds a row that needs to be removed
                subGrid = layoutGrid.Children[col] as Grid;

                // Remove sub grid's last child, which is a manipulation border, and give it back to the layout grid borderds (insert at first position)
                border = (ManipulationBorder)(subGrid.Children[subGrid.RowDefinitions.Count - 1]);
                subGrid.Children.RemoveAt(subGrid.RowDefinitions.Count - 1);
                layoutGrid.borders.Insert(0, border);

                // Remove the last row from the sub grid
                subGrid.RowDefinitions.RemoveAt(subGrid.RowDefinitions.Count - 1);
            }
        }
        /// <summary>
        /// Coerces the orientation based on the LayoutMatrix of the layout grid.
        /// </summary>
        private static object CoerceLayoutOrientationValue(DependencyObject d, object baseValue)
        {
            LayoutGrid layoutGrid = d as LayoutGrid;

            if (layoutGrid == null)
            {
                return(null);
            }

            LayoutOrientation orientation = (LayoutOrientation)baseValue;

            if (layoutGrid.LayoutMatrix == Constants.JustColumnsLayout)
            {
                // LayoutMatrix is set to JustColumnsLayout so LayoutOrientation must be set to ColumnFirst
                orientation = LayoutOrientation.ColumnFirst;
            }
            else if (layoutGrid.LayoutMatrix == Constants.JustRowsLayout)
            {
                // LayoutMatrix is set to JustRowsLayout so LayoutOrientation must be set to RowFirst
                orientation = LayoutOrientation.RowFirst;
            }
            return(orientation);
        }
        /// <summary>
        /// Updates layout grid's layout, by rows, based on the action - either with addition of a new row or with the removal of the last one.
        /// </summary>
        /// <param name="rowCount">Max rows count of the final layout.</param>
        /// <param name="columnCount">Max column count of the final layout.</param>
        /// <param name="cellCount">Number of cells - photos currently in the grid.</param>
        /// <param name="layoutGrid">Layout grid whose layout is updating.</param>
        /// <param name="action">Action which is done upon a layout.</param>
        private static void UpdateLayoutRowFirst(byte rowCount, byte columnCount, int cellCount, LayoutGrid layoutGrid, LayoutAction action)
        {
            int col = (cellCount - 1) / rowCount;
            int row = (cellCount - 1) % rowCount;

            if (action == LayoutAction.Addition)
            {
                AddRowFirst(row, col, layoutGrid);
            }
            else
            {
                RemoveRowFirst(rowCount, cellCount, col, layoutGrid);
            }
        }
        /// <summary>
        /// Updates layout grid's layout, by columns, based on the action - either with addition of a new column or with the removal of the last one.
        /// </summary>
        /// <param name="rowCount">Max row count of the final layout.</param>
        /// <param name="columnCount">Max column count of the final layout.</param>
        /// <param name="cellCount">Number of cells - photos currently in the grid.</param>
        /// <param name="layoutGrid">Layout grid whose layout is updating.</param>
        /// <param name="action">Action which is done upon a layout.</param>
        private static void UpdateLayoutColumnFirst(byte rowCount, byte columnCount, int cellCount, LayoutGrid layoutGrid, LayoutAction action)
        {
            int row = (cellCount - 1) / columnCount; // Find which row needs a column added/removed
            int col = (cellCount - 1) % columnCount; // Find index of the next column in the above row

            if (action == LayoutAction.Addition)
            {
                AddColumnFirst(row, col, layoutGrid);
            }
            else
            {
                RemoveColumnFirst(columnCount, cellCount, row, layoutGrid);
            }
        }