/// <summary>
        /// Get the list of all friends from database
        /// </summary>
        /// <returns>List of friends</returns>
        public static List<FriendEntity> GetFriendList()
        {
            using (var context = new BirthdayDataContext(Database.DbConnectionString))
            {
                var friendList = (from friend in context.Friends
                    select friend).ToList();

                return friendList;
            }
        }
        /// <summary>
        /// Creates db for storage if it does not exist
        /// </summary>
        /// <returns>Boolean value indicating if the db has already been upgraded</returns>
        public static bool UpdateSchema()
        {
            using (var context = new BirthdayDataContext(Database.DbConnectionString))
            {
                if (context.DatabaseExists())
                {
                    return true;
                }

                context.CreateDatabase();

                return false;
            }
        }
        /// <summary>
        /// Calculates birthdays and builds a list 
        /// </summary>
        /// <returns>List of Birthdays</returns>
        public static Birthdays GetBirthdays()
        {
            try
            {
                var context = new BirthdayDataContext(Database.DbConnectionString);

                var birthdays = (from friend in context.Friends
                                 where friend.IsHidden.HasValue == false || friend.IsHidden.Value == false
                                select new FriendBirthday
                                {
                                    Birthday = friend.Birthday.HasValue ? friend.Birthday.Value : new DateTime?(),
                                    Id = friend.UniqueId,
                                    Name = friend.Name,
                                    FacebookId = friend.FacebookId,
                                    ProfilePicUrl = friend.ProfilePictureUrl,
                                    DaysAhead = DateTimeUtility.GetTimeToEvent(friend.Birthday),
                                    TimeToEventText = GetRecentBirthdayText(friend.Birthday)
                                })
                                .ToList();

                if (!birthdays.Any())
                {
                    throw new Exception("Friend List is empty. Please setup your friends list.");
                }

                foreach (var birthday in birthdays)
                {
                    birthday.BirthdayText = Labels.BirthdayLabel + " : " +
                                            (birthday.Birthday.HasValue
                                                ? birthday.Birthday.Value.ToString("dd MMM")
                                                : Labels.NotKnownLabel);
                }

                context.Dispose();

                return new Birthdays
                {
                    AllBirthdays = birthdays.OrderBy(p => p.Name).ToList(),
                    RecentBirthdays = birthdays.FindAll(b => !string.IsNullOrEmpty(b.TimeToEventText))
                        .OrderBy(p => p.DaysAhead)
                        .Take(7)
                        .ToList()
                };
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        public static void MigrateXmlDataToDatabase()
        {
            var friendList = BirthdayUtility.GetFriendBirthdayList();

            if (friendList != null && friendList.Count > 0)
            {
                using (var context = new BirthdayDataContext(Database.DbConnectionString))
                {
                    foreach (var friend in friendList)
                    {
                        var dbFriend = new FriendEntity
                        {
                            BigProfilePictureUrl = friend.BigProfilePictureUrl,
                            Birthday =
                                string.IsNullOrEmpty(friend.Birthday)
                                    ? new DateTime?()
                                    : Convert.ToDateTime(friend.Birthday),
                            Email = friend.Email,
                            FacebookId = friend.Email,
                            IsReminderCreated = false,
                            IsHidden = friend.isHidden,
                            LastToastRaisedYear = friend.LastToastRaisedYear,
                            Name = friend.Name,
                            PhoneNumber = friend.PhoneNumber,
                            ProfilePictureLocation = friend.ProfilePictureLocation,
                            ProfilePictureUrl = friend.ProfilePictureUrl,
                            SendAutoEmailOnBirthday = friend.SendAutoEmailOnBirthday,
                            TypeOfContact = friend.TypeOfContact
                        };

                        context.Friends.InsertOnSubmit(dbFriend);
                    }

                    context.SubmitChanges();
                }
            }

            CleanUpOldFiles();
        }
        public static async Task SyncCards(string userId)
        {
            var service = new AzureStorageService(Services.AzureConnectionString, userId);
            var onlineCards = (await service.GetBirthdayCards()).ToList();

            var storedCards = GetBirthdayCards();

            var nonExistentCards = onlineCards.Where(c => storedCards.All(sc => sc.Id != c.Id));

            using (var context = new BirthdayDataContext(Database.DbConnectionString))
            {
                context.Cards.InsertAllOnSubmit(nonExistentCards);

                context.SubmitChanges();
            }
        }
        /// <summary>
        /// Save the ocal cards to file
        /// </summary>
        public static void SaveLocalCards()
        {
            using (var context = new BirthdayDataContext(Database.DbConnectionString))
            {
                if (context.Cards.Any()) return;

                var cards = new List<CardEntity>
                {
                    new CardEntity{Url = "http://www.simmsmanncenter.ucla.edu/wp-content/uploads/30420-birthday-candles1.jpg"},
                    new CardEntity{Url = "http://images.thefuntimesguide.com/wp-content/blogs.dir/46/files/strawberry-birthday-cake-by-chidorian-thumb-280x278-10085.jpg"}
                }
                .AsEnumerable();

                context.Cards.InsertAllOnSubmit(cards);
                context.SubmitChanges();
            }
        }
        public static void DeleteCards(List<int> cardIds)
        {
            using (var context = new  BirthdayDataContext(Database.DbConnectionString))
            {
                var cardsToDelete = (from card in context.Cards
                    where cardIds.Contains(card.Id)
                    select card).AsEnumerable();

                context.Cards.DeleteAllOnSubmit(cardsToDelete);

                context.SubmitChanges();
            }
        }
        /// <summary>
        /// Updates the details of a particulat friend
        /// </summary>
        /// <param name="friendDetails">The details of the friend to update</param>
        public static void UpdateFriendDetails(FriendEntity friendDetails)
        {  
            using (var context = new BirthdayDataContext(Database.DbConnectionString))
            {
                var existingFriend = (from friend in context.Friends
                    where friend.UniqueId == friendDetails.UniqueId
                    select friend).FirstOrDefault();

                CopyProperties(existingFriend, friendDetails);
                //considering the scenario where the data should be automatically updated as reference has been updated
                context.SubmitChanges();
            }
        }
        /// <summary>
        /// Gets the details of a crd by its id
        /// </summary>
        /// <param name="id">Id of the card</param>
        /// <returns>The card details</returns>
        public static CardEntity GetBirthdayCardById(int id)
        {
            using (var context = new BirthdayDataContext(Database.DbConnectionString))
            {
                var cardDetails = (from card in context.Cards
                    where card.Id == id
                    select card).Single();

                return cardDetails;
            }
        }
        /// <summary>
        /// Gets all the cards
        /// </summary>
        /// <returns>List of the cards</returns>
        public static List<CardEntity> GetBirthdayCards()
        {
            using (var context = new BirthdayDataContext(Database.DbConnectionString))
            {
                var cards = (from card in context.Cards
                    select card).ToList();

                return cards;
            }
        }
        public static void UpdateUrlInCard(int id, string url)
        {
            using (var context = new BirthdayDataContext(Database.DbConnectionString))
            {
                var existingCard = (from card in context.Cards
                    where card.Id == id
                    select card).Single();

                existingCard.Url = url;

                context.SubmitChanges();
            }
        }
 public static void AddBirthdayCard(CardEntity newCard)
 {
     using (var context = new BirthdayDataContext(Database.DbConnectionString))
     {
         context.Cards.InsertOnSubmit(newCard);
         context.SubmitChanges();
     }
 }
        /// <summary>
        /// Hides a friend record from display
        /// </summary>
        /// <param name="friendId">ID of the friend</param>
        public static void DeleteFriend(int friendId)
        {
            using (var context = new BirthdayDataContext(Database.DbConnectionString))
            {
                var friendToDelete = (from friend in context.Friends
                    where friend.UniqueId == friendId
                    select friend).Single();

                friendToDelete.IsHidden = true;

                context.SubmitChanges();
            }
        }
        /// <summary>
        /// Add a new friend
        /// </summary>
        /// <param name="friendDetails">The details of the friend to be added</param>
        /// <returns>The Guid of the new friend</returns>
        public static int AddNewFriend(FriendEntity friendDetails)
        {
            using (var context =new BirthdayDataContext(Database.DbConnectionString))
            {
                friendDetails.SendAutoEmailOnBirthday = true;
                friendDetails.IsReminderCreated = false;
                friendDetails.IsHidden = false;
                friendDetails.LastToastRaisedYear = 1900;

                context.Friends.InsertOnSubmit(friendDetails);
                context.SubmitChanges();

                return friendDetails.UniqueId;
            }
        }
        /// <summary>
        /// Deletes a specific card
        /// </summary>
        /// <param name="id">Id of the card to be deleted</param>
        public static void DeleteCard(int id)
        {
            using (var context = new BirthdayDataContext(Database.DbConnectionString))
            {
                context.Cards.DeleteOnSubmit(GetBirthdayCardById(id));

                context.SubmitChanges();
            }
        }
        /// <summary>
        /// Populate fb friends if not yet populated
        /// </summary>
        private void CheckFriendBirthdayFile()
        {
            int recordCount;

            using (var context = new BirthdayDataContext(Database.DbConnectionString))
            {
                recordCount = context.Friends.Count();
            }

            if (recordCount == 0)
            {
                var setupContactsMessageBox = new CustomMessageBox
                {
                    Height = 300,
                    Caption = AppResources.BdaySetupTitle,
                    Message = AppResources.BdaySetupMessage,
                    LeftButtonContent = AppResources.YesLabel,
                    RightButtonContent = AppResources.LaterLabel,
                    VerticalAlignment = VerticalAlignment.Center
                };

                setupContactsMessageBox.Dismissed += CustomMessageBoxDismissed;
                setupContactsMessageBox.Show();
            }
            else
            {
                ReminderUtility.UpdateCalendarEntries();

                if (_isSourceToast)
                {
                    MessageBox.Show(AppResources.ReminderUpdateSuccess, AppResources.ReminderUpdatedTitle, MessageBoxButton.OK);
                }
                if (IsSyncRequired())
                {
                    var result = MessageBox.Show(AppResources.ContactNotUpdatedMessage, AppResources.SyncContactsLabel, MessageBoxButton.OKCancel);
                    NavigationService.Navigate(result.Equals(MessageBoxResult.OK)
                        ? new Uri("/FacebookLogin.xaml?" + UriParameter.IsSyncScneario + "=Yes", UriKind.Relative)
                        : new Uri("/MainPage.xaml", UriKind.Relative));
                }
                else
                {
                    NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
                }
            }
        }
        /// <summary>
        /// Retrieves the friend details from file using GUID
        /// </summary>
        /// <param name="friendId">GUID of friend</param>
        /// <returns>The Friend details object</returns>
        public static FriendEntity GetFriendDetailsById(int friendId)
        {
            using (var context = new BirthdayDataContext(Database.DbConnectionString))
            {
                var friendDetails = (from friend in context.Friends
                    where friend.UniqueId == friendId
                    select friend).Single();

                return friendDetails;
            }
        }