List<IStore> IStoreRetriever.GetAllStoresInRadius(double latitude, double longitude, double radius)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                Tuple<double, double> north = _distanceCalculator.GetNorthernPoint(latitude, longitude, radius);
                Tuple<double, double> south = _distanceCalculator.GetSouthernPoint(latitude, longitude, radius);
                Tuple<double, double> east = _distanceCalculator.GetEasternPoint(latitude, longitude, radius);
                Tuple<double, double> west = _distanceCalculator.GetWesternPoint(latitude, longitude, radius);

                List<IStore> stores = dataContext.StoreDtos.Where(c => (double)c.Latitude < north.Item1 && (double)c.Latitude > south.Item1
                                                                && (double)c.Longitude < east.Item2 && (double)c.Longitude > west.Item2)
                                                                .Cast<IStore>().ToList();

                List<IStore> storesToRemove = new List<IStore>();

                foreach (IStore store in stores)
                {
                    if (_distanceCalculator.CalculateMiles(latitude, longitude, store.Latitude, store.Longitude) > radius)
                    {
                        storesToRemove.Add(store);
                    }
                }

                stores.RemoveAll(c => storesToRemove.Contains(c));

                return stores;
            }
        }
        List<IZombiePack> IZombiePackRetriever.GetAllZombiePacksInRadius(double latitude, double longitude, double radius)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                Tuple<double, double> north = _distanceCalculator.GetNorthernPoint(latitude, longitude, radius);
                Tuple<double, double> south = _distanceCalculator.GetSouthernPoint(latitude, longitude, radius);
                Tuple<double, double> east = _distanceCalculator.GetEasternPoint(latitude, longitude, radius);
                Tuple<double, double> west = _distanceCalculator.GetWesternPoint(latitude, longitude, radius);

                List<IZombiePack> zombiePacks = dataContext.ZombiePackDtos.Where(c => (double)c.Latitude < north.Item1 && (double)c.Latitude > south.Item1
                                                                && (double)c.Longitude < east.Item2 && (double)c.Longitude > west.Item2)
                                                                .Cast<IZombiePack>().ToList();

                List<IZombiePack> zombiePacksToRemove = new List<IZombiePack>();

                foreach (IZombiePack zombiePack in zombiePacks)
                {
                    if (_distanceCalculator.CalculateMiles(latitude, longitude, zombiePack.Latitude, zombiePack.Longitude) > radius)
                    {
                        zombiePacksToRemove.Add(zombiePack);
                    }
                }

                zombiePacks.RemoveAll(c => zombiePacksToRemove.Contains(c));

                return zombiePacks;
            }
        }
        bool IUserRetriever.UserExists(Guid userId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.UserExists(userId);
            }
        }
        Guid IZombiePackRetriever.GetHotZoneByZombiePackId(Guid zombiePackId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.ZombiePackDtos.Single(c => c.Id == zombiePackId).HotZoneId;
            }
        }
        IZombiePack IZombiePackRetriever.GetZombiePackById(Guid id)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.ZombiePackDtos.SingleOrDefault(c => c.Id == id);
            }
        }
        bool ISafeHouseRetriever.SafeHouseExists(Guid safeHouseId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.SafeHouseDtos.Any(c => c.Id == safeHouseId);
            }
        }
        bool IStoreRetriever.StoreExists(double latitude, double longitude)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.StoreDtos.Any(c => (double)c.Latitude == latitude && (double)c.Longitude == longitude);
            }
        }
        List<IZombiePack> IZombiePackRetriever.GetAllZombiePacksInHotZone(Guid hotZoneId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.ZombiePackDtos.Where(c => c.HotZoneId == hotZoneId).Cast<IZombiePack>().ToList();
            }
        }
        IItem IItemRetriever.GetItemById(Guid itemId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.GetItemById(itemId);
            }
        }
        IUser IUserRetriever.GetUserById(Guid userId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.GetUserById(userId);
            }
        }
        List<KeyValuePair<Guid, string>> IHotZoneRetriever.GetStartingHotZones()
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.HotZoneDtos.Where(h => h.CanStartHere == true).Select(s => new KeyValuePair<Guid, string>(s.Id, s.Name)).ToList();
            }
        }
        bool IHotZoneRetriever.IsStartingHotZone(Guid hotZoneId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.HotZoneDtos.Any(h => h.CanStartHere == true && h.Id == hotZoneId);
            }
        }
        bool IHotZoneRetriever.HotZoneExists(Guid hotZoneId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.HotZoneDtos.Any(s => s.Id == hotZoneId);
            }
        }
        List<IHotZone> IHotZoneRetriever.GetAllHotZones()
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.HotZoneDtos.Cast<IHotZone>().ToList();
            }
        }
        List<IItem> IStoreRetriever.GetItems(Guid storeId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.ItemDtos.Cast<IItem>().ToList();
            }
        }
        bool IZombiePackRetriever.ZombiePackExists(Guid zombiePackId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.ZombiePackDtos.Any(c => c.Id == zombiePackId);
            }
        }
        bool IItemRetriever.ItemExists(Guid itemId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.ItemExists(itemId);
            }
        }
        bool ISafeHouseRetriever.SafeHouseHasItem(Guid itemId, Guid userId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.SafeHouseItemDtos.Any(c => c.ItemId == itemId
                                                            && c.UserId == userId);
            }
        }
        Guid? IUserRetriever.GetLastVisitedHotZone(Guid userId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                UserDto user = dataContext.GetUserById(userId);
                return user.LastVisitedHotZoneId;
            }
        }
        int IUserRetriever.GetCurrentMoney(Guid userId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                IUser user = dataContext.GetUserById(userId);
                return user.Money;
            }
        }
        List<IItem> IItemRetriever.GetAllBelowPrice(int price)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                return dataContext.ItemDtos
                                  .Where(i => i.Price <= price)
                                  .Cast<IItem>()
                                  .ToList();
            }
        }
        List<IItem> IUserItemRetriever.GetUserItems(Guid userId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                List<IItem> items = (from userItems in dataContext.UserItemDtos
                                     join item in dataContext.ItemDtos
                                     on userItems.ItemId equals item.Id
                                     where userItems.UserId == userId
                                     select item).Cast<IItem>().ToList();

                return items;
            }
        }
        List<IItem> ISafeHouseRetriever.GetItems(Guid userId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                var items = (from safeHouseItem in dataContext.SafeHouseItemDtos
                             join item in dataContext.ItemDtos
                             on safeHouseItem.ItemId equals item.Id
                             where safeHouseItem.UserId == userId
                             select item);

                return items.Cast<IItem>().ToList(); ;
            }
        }
        Tuple<int, DateTime> IUserRetriever.GetLastSavedEnergy(Guid userId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();
                var dto = dataContext.UserDtos.SingleOrDefault(s => s.Id == userId);
                if (dto != null)
                {
                    if (dto.LastEnergy == null)
                    {
                        return null;
                    }

                    if (dto.LastEnergyDate == null)
                    {
                        dto.LastEnergyDate = DateTime.Now;
                    }

                    return new Tuple<int, DateTime>(dto.LastEnergy.Value, dto.LastEnergyDate.Value);
                }
            }

            return null;
        }
        int IUserRetriever.GetEnergyForDifficultyCalculation(Guid userId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                UserDto user = dataContext.GetUserById(userId);
                return user.BaseLineEnergy;
            }
        }
        int? IUserRetriever.GetCurrentBaseSightRadius(Guid userId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                UserDto dto = dataContext.GetUserById(userId);

                if (dto != null)
                {
                    return dto.BaseSightRadius;
                }
            }

            return null;
        }
        int IUserRetriever.GetCurrentLevel(Guid userId)
        {
            using (UndeadEarthDataContext undeadEarthDataContext = new UndeadEarthDataContext(_connectionString))
            {
                undeadEarthDataContext.ReadUncommited();

                UserDto userDto = undeadEarthDataContext.GetUserById(userId);
                return userDto.Level;
            }
        }
        int IUserRetriever.GetCurrentBaseSlots(Guid userId)
        {
            using (UndeadEarthDataContext undeadEarthDataContext = new UndeadEarthDataContext(_connectionString))
            {
                undeadEarthDataContext.ReadUncommited();

                UserDto userDto = undeadEarthDataContext.GetUserById(userId);
                return userDto.PossibleItemAmount;
            }
        }
        void IUserSaver.UpdateUserLocation(Guid userId, double lattitude, double longitude)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                UserDto userDto = dataContext.GetUserById(userId);

                HotZoneDto hotZone = dataContext.HotZoneDtos.SingleOrDefault(c => c.Latitude == (decimal)lattitude && c.Longitude == (decimal)longitude);

                if (userDto != null)
                {
                    userDto.Latitude = (decimal)lattitude;
                    userDto.Longitude = (decimal)longitude;
                    userDto.ZoneId = hotZone != null ? hotZone.Id : userDto.ZoneId;
                    dataContext.SubmitChanges();
                }
            }
        }
        void IUserSaver.UpdateZone(Guid userId, Guid hotZoneId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                UserDto userDto = dataContext.GetUserById(userId);

                if (userDto != null)
                {
                    userDto.ZoneId = hotZoneId;

                    dataContext.SubmitChanges();
                }
            }
        }