/// <summary>
        /// Gets photos uploaded by the current user.
        /// </summary>
        /// <param name="continuationToken">Optional. The continuation token. By default, null.</param>
        /// <returns>The photos.</returns>
        public async Task <PagedResponse <Photo> > GetPhotosForCurrentUser(string continuationToken = null)
        {
            await SimulateWaitAndError();

            var stream = PhotoStreams.FirstOrDefault();

            var photos = stream.Photos.Where(photo => photo.User.UserId == User.UserId);

            stream.Photos = photos.ToList();

            if (stream != null)
            {
                // Found the first photo stream, return photos
                return(new PagedResponse <Photo>
                {
                    ContinuationToken = null,
                    Items = stream.Photos
                });
            }

            // First photo stream was null, return empty list.
            return(new PagedResponse <Photo>
            {
                ContinuationToken = null,
                Items = new List <Photo>()
            });
        }
        /// <summary>
        /// Gets the photo details for the given photo id.
        /// </summary>
        /// <param name="photoId">The photo identifier.</param>
        /// <returns>The photo.</returns>
        public async Task <Photo> GetPhotoDetails(string photoId)
        {
            await SimulateWaitAndError();

            var photo = PhotoStreams.SelectMany(s => s.Photos)
                        .FirstOrDefault(p => p.Id == photoId);

            photo.Annotations = new ObservableCollection <Annotation>(Annotations);

            return(photo);
        }
        /// <summary>
        /// Deletes the photo.
        /// </summary>
        /// <param name="photo">The photo.</param>
        public async Task DeletePhoto(Photo photo)
        {
            await SimulateWaitAndError();

            var category = PhotoStreams.FirstOrDefault(c => c.CateogoryId == photo.CategoryId);

            var photoInCategory = category?.Photos.FirstOrDefault(p => p.CategoryId == photo.CategoryId);

            if (photoInCategory != null)
            {
                category.Photos.Remove(photoInCategory);
            }
        }
        /// <summary>
        /// Uploads the photo.
        /// </summary>
        /// <param name="stream">The memory stream.</param>
        /// <param name="localPath">The local path.</param>
        /// <param name="caption">The caption.</param>
        /// <param name="categoryId">The id of the assocaited category.</param>
        /// <returns>The uploaded photo.</returns>
        public async Task <Photo> UploadPhoto(Stream stream, string localPath, string caption, string categoryId)
        {
            await SimulateWaitAndError();

            var photo = new Photo
            {
                Caption           = caption,
                ThumbnailUrl      = localPath,
                HighResolutionUrl = localPath,
                StandardUrl       = localPath,
                CreatedAt         = DateTime.Now,
                User = AppEnvironment.Instance.CurrentUser
            };

            PhotoStreams.FirstOrDefault(s => s.CateogoryId == categoryId).Photos.Insert(0, photo);

            AppEnvironment.Instance.CurrentUser.GoldBalance++;

            return(photo);
        }
        /// <summary>
        /// Gets photos for the given category id.
        /// </summary>
        /// <param name="categoryId">The identifier.</param>
        /// <param name="continuationToken">Optional. The continuation token. By default, null.</param>
        /// <returns>The photos.</returns>
        public async Task <PagedResponse <Photo> > GetPhotosForCategoryId(string categoryId,
                                                                          string continuationToken = null)
        {
            await SimulateWaitAndError();

            var stream = PhotoStreams.FirstOrDefault(s => s.CateogoryId == categoryId);

            if (stream != null)
            {
                // Category Id found, return photos
                return(new PagedResponse <Photo>
                {
                    ContinuationToken = null,
                    Items = stream.Photos
                });
            }

            // Category Id was not found, return empty list.
            return(new PagedResponse <Photo>
            {
                ContinuationToken = null,
                Items = new List <Photo>()
            });
        }
        private void InitLeaderboardData()
        {
            var allPhotos = PhotoStreams.SelectMany(s => s.Photos).ToList();
            var users     = _sampleUsers;

            var leaderboard = new Leaderboard
            {
                MostGoldCategories = new List <LeaderboardEntry <Category> >
                {
                    new LeaderboardEntry <Category>
                    {
                        Model = Categories[_random.Next(Categories.Count)],
                        Rank  = 1,
                        Value = 94
                    },
                    new LeaderboardEntry <Category>
                    {
                        Model = Categories[_random.Next(Categories.Count)],
                        Rank  = 2,
                        Value = 79
                    },
                    new LeaderboardEntry <Category>
                    {
                        Model = Categories[_random.Next(Categories.Count)],
                        Rank  = 3,
                        Value = 47
                    }
                },
                MostGoldPhotos = new List <LeaderboardEntry <Photo> >
                {
                    new LeaderboardEntry <Photo>
                    {
                        Model = allPhotos[_random.Next(allPhotos.Count)],
                        Rank  = 1,
                        Value = 38
                    },
                    new LeaderboardEntry <Photo>
                    {
                        Model = allPhotos[_random.Next(allPhotos.Count)],
                        Rank  = 2,
                        Value = 29
                    },
                    new LeaderboardEntry <Photo>
                    {
                        Model = allPhotos[_random.Next(allPhotos.Count)],
                        Rank  = 3,
                        Value = 21
                    }
                },
                MostGoldUsers = new List <LeaderboardEntry <User> >
                {
                    new LeaderboardEntry <User>
                    {
                        Model = users[_random.Next(users.Count)],
                        Rank  = 1,
                        Value = 68
                    },
                    new LeaderboardEntry <User>
                    {
                        Model = users[_random.Next(users.Count)],
                        Rank  = 2,
                        Value = 54
                    },
                    new LeaderboardEntry <User>
                    {
                        Model = users[_random.Next(users.Count)],
                        Rank  = 3,
                        Value = 37
                    }
                },
                MostGivingUsers = new List <LeaderboardEntry <User> >
                {
                    new LeaderboardEntry <User>
                    {
                        Model = users[_random.Next(users.Count)],
                        Rank  = 1,
                        Value = 34
                    },
                    new LeaderboardEntry <User>
                    {
                        Model = users[_random.Next(users.Count)],
                        Rank  = 2,
                        Value = 27
                    },
                    new LeaderboardEntry <User>
                    {
                        Model = users[_random.Next(users.Count)],
                        Rank  = 3,
                        Value = 17
                    }
                }
            };

            LeaderboardData = leaderboard;
        }