public static LocationFilterModel ToFilterModel(this Location entity)
        {
            if (entity == null)
                return null;

            var model = new LocationFilterModel
            {
                Id = entity.Id,
                Name = entity.Name
            };

            return model;
        }
        private LocationFilterModel PrepareLocationFilters(IList<BaseProject> projects, Location location = null)
        {
            if (location == null)
            {
                var topLocations = _locationService.GetAllChildLocations();
                LocationFilterModel allRegionFilter;

                if (topLocations.Count > 1)
                {
                    allRegionFilter = new LocationFilterModel { Name = "All Regions", ProjectCount = projects.Count };
                    foreach (var topLocation in topLocations)
                        allRegionFilter.ChildrenLocations.Add(PrepareLocationFilters(projects.Where(p => p.Locations.Any(l => l.LocationId == topLocation.Id)).ToList(), topLocation));
                }
                else
                {
                    allRegionFilter = PrepareLocationFilters(projects, topLocations.First());
                }

                return allRegionFilter;
            }

            var locationFilter = location.ToFilterModel();
            locationFilter.Link = GetPageLink(location.SeoName, location.ParentLocation != null ? location.ParentLocation.SeoName : null).ToString();
            locationFilter.ProjectCount = projects.Count(p => p.Locations.Any(l => l.LocationId == location.Id));

            foreach (var child in location.ChildLocations)
            {
                int projectCount = projects.Count(p => p.Locations.Any(l => l.LocationId == child.Id));
                if (projectCount > 0)
                {
                    var childFilter = child.ToFilterModel();
                    childFilter.Link = GetPageLink(child.SeoName, child.ParentLocation != null ? child.ParentLocation.SeoName : null).ToString();
                    childFilter.ProjectCount = projectCount;
                    locationFilter.ChildrenLocations.Add(childFilter);
                }
            }

            var parentLocation = location.ParentLocation;
            while (parentLocation != null)
            {
                var parentLocationFilter = parentLocation.ToFilterModel();
                parentLocationFilter.ChildrenLocations.Add(locationFilter);
                parentLocationFilter.Link = GetPageLink(parentLocation.SeoName, parentLocation.ParentLocation != null ? parentLocation.ParentLocation.SeoName :  null).ToString();
                parentLocationFilter.ProjectCount = projects.Count(p => p.Locations.Any(l => l.LocationId == parentLocation.Id));

                locationFilter = parentLocationFilter;
                parentLocation = parentLocation.ParentLocation;
            }

            return locationFilter;
        }
        private void PrepareListingResults(int? locationId = null, bool buildLocationFilters = true)
        {
            // Build non-javascript refinement links
            SetPageLink();
            SetPageLink(true);

            var sortTypeEnum = (ProjectSortType) _sortType;
            var sortDirectionEnum = (ProjectSortDirection) _sortDirection;

            // Build the category meta title
            if (_categories != null && _categories.Count > 0)
                _metaTitle = "Volunteer to do a good thing | {0} projects";

            // Start by getting all the projects and locations
            // based on how you're entering the page
            if (!string.IsNullOrEmpty(_query))
            {
                // Work out how far we should zoom in
                switch (_radius)
                {
                    case (int)ProjectSearchRadius.FiveMiles:
                        _mapZoomLevel = 12;
                        break;
                    case (int)ProjectSearchRadius.TenMiles:
                        _mapZoomLevel = 11;
                        break;
                    case (int)ProjectSearchRadius.FifteenMiles:
                        _mapZoomLevel = 10;
                        break;
                    case (int)ProjectSearchRadius.FiftyMiles:
                        _mapZoomLevel = 8;
                        break;
                }

                // If we have a search query, the user must have come from the search form
                // Get the lat/lng of their search query
                _geolocationService.GetLatLng(_query, out _mapLatitude, out _mapLongitude);

                // Get all the projects within a given radius of the search query
                _projects = _projectService.GetAllProjectsByCoords(_mapLatitude, _mapLongitude, _categories, (ProjectSearchRadius)_radius, (ProjectSearchStart)_start, (ProjectChildFriendly)_childFriendly);
                var locationProjects = _projects;

                // If we have an additional location filter, remove projects not in the location
                if ((locationId != null && locationId > 0) || !string.IsNullOrEmpty(_locationSeoName))
                {
                    if (locationId != null && locationId > 0)
                        _location = _locationService.GetLocationById((int)locationId);
                    else
                        _location = _locationService.GetLocationBySeoName(_locationSeoName, _parentSeoName);

                    _projects = _projects.Where(x => x.Locations.Any(l => l.LocationId == _location.Id)).ToList();

                    int parentCount = 0;
                    var parentLocation = _location.ParentLocation;
                    while (parentLocation != null)
                    {
                        parentCount++;
                        parentLocation = parentLocation.ParentLocation;
                    }

                    _mapLatitude = _location.Latitude;
                    _mapLongitude = _location.Longitude;
                    _mapZoomLevel = 7 + (int)Math.Round(parentCount * 1.5);
                }

                // Build location filters
                if (buildLocationFilters && _projects.Count > 0)
                {
                    var topLocation = _projects[0].Locations.ToList().FirstOrDefault(x => _projects.All(y => y.Locations.Any(z => z.LocationId == x.LocationId)));
                    if (topLocation != null)
                    {
                        _locationFilters = PrepareLocationFilters(locationProjects, topLocation.Location);
                    }
                }
            }
            else if ((locationId != null && locationId > 0) || !string.IsNullOrEmpty(_locationSeoName))
            {
                // If we are on a location project listing page
                // Get the location entity based on the location seo name in the URL
                if (locationId != null && locationId > 0)
                    _location = _locationService.GetLocationById((int)locationId);
                else
                    _location = _locationService.GetLocationBySeoName(_locationSeoName, _parentSeoName);

                // If we couldn't find a location matching the seo name, redirect to the main project listing page
                if (_location == null)
                {
                    var httpContextWrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
                    var urlHelper = new UrlHelper(new RequestContext(httpContextWrapper, new RouteData()));
                    System.Web.HttpContext.Current.Response.Redirect(urlHelper.RouteUrl("ProjectListing"), true);
                    return;
                }

                // Build the breadcrumbs based on the location
                var parentLocation = _location.ParentLocation;
                int parentCount = 0;

                // Build the breadcrumb hierarchy
                while (parentLocation != null)
                {
                    parentCount++;
                    AddBreadcrumb(parentLocation.Name, Url.RouteUrl("ProjectListingLocation", new { locationSeoName = parentLocation.SeoName }), 0);
                    parentLocation = parentLocation.ParentLocation;
                }

                AddBreadcrumb(_location.Name, Url.RouteUrl("ProjectListingLocation", new { locationSeoName = _location.SeoName }));

                // Change the map lat/lng and zoom based on the current location and number of parents
                _mapLatitude = _location.Latitude;
                _mapLongitude = _location.Longitude;
                _mapZoomLevel = 7 + (int)Math.Round(parentCount * 1.5);

                // Check if we need to build the location filters
                if (buildLocationFilters)
                {
                    // Get all the projects, regardless of location
                    _projects = _projectService.GetAllProjectsByLocation(null, _categories, sortTypeEnum, sortDirectionEnum);

                    // Build all the location filters, passing across the project list so we can populate location counts
                    _locationFilters = PrepareLocationFilters(_projects, _location);
                }
                else
                {
                    // Get all the projects, regardless of location
                    _projects = _projectService.GetAllProjectsByLocation(_location, _categories, sortTypeEnum, sortDirectionEnum);
                }

                // Filter the projects down to the location we need for presentation
                _projects = _projects.Where(p => p.Locations.Any(l => l.LocationId == _location.Id)).ToList();

                // Build the meta title
                string projectCountTitle = _projects.Count > 0 ? " - " + _projects.Count + " Projects" : "";
                _metaTitle = string.Format("{0} Opportunities in {1}{2} - #WeWillGather", _categories != null && _categories.Count > 0 ? "{0} " : "Volunteering ", _location.Name, projectCountTitle);
            }
            else
            {
                // We must be on the main projecting listing page
                // Get all projects, regardless of location
                _projects = _projectService.GetAllProjectsByLocation(null, _categories, sortTypeEnum, sortDirectionEnum);

                // Check if we need to build the location filters
                if (buildLocationFilters)
                    _locationFilters = PrepareLocationFilters(_projects);
            }
        }