/// <summary>
        /// Populates the PayloadDetails object's properties from the given collection of Community view object's properties.
        /// </summary>
        /// <param name="thisObject">PayloadDetails object</param>
        /// <param name="communities">Community View object</param>
        /// <returns>PayloadDetails instance</returns>
        public static PayloadDetails SetValuesFrom(this PayloadDetails thisObject, IEnumerable<CommunityDetails> communities)
        {
            if (communities != null)
            {
                if (thisObject == null)
                {
                    thisObject = InitializePayload();
                }

                foreach (var community in communities)
                {
                    var childCommunity = new PayloadDetails();
                    childCommunity.Name = community.Name;
                    childCommunity.Id = community.ID.ToString(CultureInfo.InvariantCulture);
                    childCommunity.MSRCommunityId = community.ID;
                    childCommunity.FolderType = "Earth";
                    childCommunity.Group = "Explorer";
                    childCommunity.CommunityType = community.CommunityType;
                    childCommunity.FolderRefreshType = "ConditionalGet";
                    childCommunity.Searchable = community.CommunityType == CommunityTypes.Community ? true.ToString() : false.ToString();
                    childCommunity.Thumbnail = (community.Thumbnail != null && community.Thumbnail.AzureID != Guid.Empty) ? community.Thumbnail.AzureID.ToString() : null;
                    childCommunity.Permission = community.UserPermission;

                    thisObject.Children.Add(childCommunity);
                }
            }

            return thisObject;
        }
 /// <summary>
 /// Initialize Payload instance
 /// </summary>
 /// <returns>PayloadDetails instance</returns>
 public static PayloadDetails InitializePayload()
 {
     var thisObject = new PayloadDetails();
     thisObject.Links = new Collection<Place>();
     thisObject.Children = new Collection<PayloadDetails>();
     thisObject.Tours = new Collection<TourModel>();
     thisObject.FolderType = "Earth";
     thisObject.Group = "Explorer";
     thisObject.Searchable = "True";
     thisObject.FolderRefreshType = "ConditionalGet";
     thisObject.CommunityType = CommunityTypes.Folder;
     thisObject.Permission = Permission.Reader;
     return thisObject;
 }
        /// <summary>
        /// Populates the PayloadDetails object's properties from the given collection of Community view object's properties.
        /// </summary>
        /// <param name="thisObject">PayloadDetails object</param>
        /// <param name="communities">Community View object</param>
        /// <returns>PayloadDetails instance</returns>
        public static PayloadDetails SetValuesFrom(this PayloadDetails thisObject, IEnumerable<CommunitiesView> communities)
        {
            if (communities != null)
            {
                if (thisObject == null)
                {
                    thisObject = InitializePayload();
                }

                foreach (var community in communities)
                {
                    var childCommunity = new PayloadDetails();
                    childCommunity.Name = community.CommunityName;
                    childCommunity.Id = community.CommunityID.ToString(CultureInfo.InvariantCulture);
                    childCommunity.MSRCommunityId = community.CommunityID;
                    childCommunity.FolderType = "Earth";
                    childCommunity.Group = "Explorer";
                    childCommunity.CommunityType = CommunityTypes.Community;
                    childCommunity.FolderRefreshType = "ConditionalGet";
                    childCommunity.Searchable = true.ToString();
                    childCommunity.Thumbnail = (community.ThumbnailID != null && community.ThumbnailID.Value != Guid.Empty) ? community.ThumbnailID.ToString() : null;
                    childCommunity.Permission = Permission.Reader;

                    // Permissions for Community view are hard-coded to Read as it is used for browse
                    thisObject.Children.Add(childCommunity);
                }
            }

            return thisObject;
        }
        /// <summary>
        /// Populates the PayloadDetails object's properties from the given collection of Categories object's properties.
        /// </summary>
        /// <param name="thisObject">PayloadDetails object</param>
        /// <param name="categories">Categories object</param>
        /// <returns>PayloadDetails instance</returns>
        public static PayloadDetails SetValuesFrom(this PayloadDetails thisObject, SelectList categories)
        {
            if (categories != null)
            {
                if (thisObject == null)
                {
                    thisObject = InitializePayload();
                }

                foreach (var category in categories)
                {
                    var childCategory = new PayloadDetails();
                    childCategory.Name = category.Text;
                    childCategory.Id = category.Value;
                    childCategory.FolderType = "Earth";
                    childCategory.Group = "Explorer";
                    childCategory.CommunityType = CommunityTypes.Folder;
                    childCategory.FolderRefreshType = "ConditionalGet";
                    childCategory.Searchable = true.ToString();

                    // TODO : Thumbnail for Each category
                    // childCommunity.Thumbnail = (community.ThumbnailID != null && community.ThumbnailID.Value != Guid.Empty) ? community.ThumbnailID.ToString() : null;
                    childCategory.Permission = Permission.Reader;

                    // Permissions for Community view are hard-coded to Read as it is used for browse
                    thisObject.Children.Add(childCategory);
                }
            }

            return thisObject;
        }
        /// <summary>
        /// Populates the PayloadDetails object's properties from the given Content object's properties.
        /// </summary>
        /// <param name="thisObject">PayloadDetails object</param>
        /// <param name="contentDetail">Content Details object</param>
        /// <returns>PayloadDetails instance</returns>
        public static PayloadDetails SetValuesFrom(this PayloadDetails thisObject, ContentDetails contentDetail)
        {
            if (contentDetail != null)
            {
                if (thisObject == null)
                {
                    thisObject = InitializePayload();
                }

                if (contentDetail.ContentData is FileDetail)
                {
                    var fileDetail = contentDetail.ContentData as FileDetail;
                    if (contentDetail.ContentData.ContentType == ContentTypes.Tours)
                    {
                        var tour = new TourModel();
                        tour.SetValuesFrom(contentDetail);
                        thisObject.Tours.Add(tour);
                    }
                    else if (contentDetail.ContentData.ContentType == ContentTypes.Wtml)
                    {
                        var childCollection = new PayloadDetails();
                        childCollection.Name = contentDetail.Name;
                        childCollection.Id = fileDetail.AzureID.ToString();
                        childCollection.MSRComponentId = contentDetail.ID;
                        childCollection.Group = "Explorer";
                        childCollection.IsCollection = true;
                        childCollection.Thumbnail = (contentDetail.Thumbnail != null && contentDetail.Thumbnail.AzureID != Guid.Empty) ? contentDetail.Thumbnail.AzureID.ToString() : null;
                        childCollection.Permission = contentDetail.UserPermission;
                        thisObject.Children.Add(childCollection);
                    }
                    else
                    {
                        var place = new Place();
                        place.SetValuesFrom(contentDetail);
                        thisObject.Links.Add(place);
                    }
                }
                else
                {
                    var place = new Place();
                    place.SetValuesFrom(contentDetail);
                    thisObject.Links.Add(place);
                }
            }

            return thisObject;
        }
        /// <summary>
        /// Populates the PayloadDetails object's properties from the given collection of ContentsView object's properties.
        /// </summary>
        /// <param name="thisObject">PayloadDetails object</param>
        /// <param name="contents">ContentsView objects</param>
        /// <returns>PayloadDetails instance</returns>
        public static PayloadDetails SetValuesFrom(this PayloadDetails thisObject, IEnumerable<ContentsView> contents)
        {
            if (contents != null)
            {
                if (thisObject == null)
                {
                    thisObject = InitializePayload();
                }

                foreach (var content in contents)
                {
                    if (content.Filename.EndsWith(Constants.TourFileExtension, StringComparison.OrdinalIgnoreCase))
                    {
                        var tour = new TourModel();
                        tour.SetValuesFrom(content);
                        thisObject.Tours.Add(tour);
                    }
                    else if (content.Filename.EndsWith(Constants.CollectionFileExtension, StringComparison.OrdinalIgnoreCase))
                    {
                        var childCollection = new PayloadDetails();
                        childCollection.Name = content.Title;
                        childCollection.Id = content.ContentAzureID.ToString();
                        childCollection.MSRComponentId = content.ContentID;
                        childCollection.Group = "Explorer";
                        childCollection.IsCollection = true;
                        childCollection.Thumbnail = (content.ThumbnailID.HasValue && content.ThumbnailID != Guid.Empty) ? content.ThumbnailID.ToString() : null;

                        // Permissions for Content view are hard-coded to Read as it is used for browse
                        childCollection.Permission = Permission.Reader;
                        thisObject.Children.Add(childCollection);
                    }
                    else
                    {
                        var place = new Place();
                        place.SetValuesFrom(content);
                        thisObject.Links.Add(place);
                    }
                }
            }

            return thisObject;
        }
 /// <summary>
 /// Get File stream for all the tours in a folder
 /// </summary>
 /// <param name="payloadDetails">payload Details object</param>
 /// <returns>Result Stream.</returns>
 private Stream GetOutputStream(PayloadDetails payloadDetails)
 {
     Response.ContentType = "application/xml";
     var stream = payloadDetails.GetXmlStream();
     stream.Seek(0, SeekOrigin.Begin);
     return stream;
 }
        /// <summary>
        /// Adds all tours and latest tours to the Payload for the community.
        /// </summary>
        /// <param name="payloadDetails">PayloadDetails object</param>
        private void AddTourFolders(PayloadDetails payloadDetails)
        {
            var baseUri = ServiceBaseUri();
            var allTours = PayloadDetailsExtensions.InitializePayload();
            allTours.Name = "All Tours";
            allTours.Url = string.Format(CultureInfo.InvariantCulture, "{0}/Community/{1}/Tours", baseUri, payloadDetails.Id);

            var latestTours = PayloadDetailsExtensions.InitializePayload();
            latestTours.Name = "Latest";
            latestTours.Url = string.Format(CultureInfo.InvariantCulture, "{0}/Community/{1}/Latest", baseUri, payloadDetails.Id);

            // Insert tour folders at the start
            payloadDetails.Children.Insert(0, latestTours);
            payloadDetails.Children.Insert(0, allTours);
        }
        /// <summary>
        /// Rewrites the Thumbnail path and the URL of the Payload for the community.
        /// </summary>
        /// <param name="payloadDetails">PayloadDetails object</param>
        /// <param name="hasChildCommunities"></param>
        
        private async void RewritePayloadUrls(PayloadDetails payloadDetails, bool hasChildCommunities)
        {
            var baseUri = BaseUri();

            if (payloadDetails.CommunityType == CommunityTypes.Community)
            {
                payloadDetails.Thumbnail = RewriteThumbnailUrl(payloadDetails.Thumbnail, "defaultcommunitywwtthumbnail");
            }
            else
            {
                payloadDetails.Thumbnail = RewriteThumbnailUrl(payloadDetails.Thumbnail, "defaultfolderwwtthumbnail");
            }

            // Update Place Urls
            foreach (var place in payloadDetails.Links)
            {
                place.Thumbnail = RewriteThumbnailUrl(place.Thumbnail, place.FileType.GetContentTypeImage());
                var fileExt = "none";
                if (place.Url.Contains(".") && place.FileType != ContentTypes.Link)
                {
                    fileExt = place.Url.Substring(place.Url.LastIndexOf(".") + 1);
                }
                
                place.Url = place.FileType == ContentTypes.Link
                    ? place.ContentLink
                    : string.Format(CultureInfo.InvariantCulture, "{0}/File/Download/{1}/{2}/{3}/{4}", baseUri,
                        place.ContentAzureID, Uri.EscapeDataString(place.Name.Replace("&", "and")), fileExt,
                        fileExt == "wtml" ? "wwtfull=true":string.Empty); 
            }

            // Update Content Urls
            foreach (var childCommunity in payloadDetails.Children)
            {
                if (childCommunity.IsCollection)
                {
                    // Only for collection set the default thumbnail, not for folders.
                    childCommunity.Thumbnail = RewriteThumbnailUrl(childCommunity.Thumbnail, "defaultwtmlwwtthumbnail");
                    childCommunity.Url = string.Format(CultureInfo.InvariantCulture, "{0}/File/Download/{1}/ChildCommunityData", baseUri, childCommunity.Id);
                }
                else
                {
                    if (hasChildCommunities)
                    {
                        childCommunity.Thumbnail = RewriteThumbnailUrl(childCommunity.Thumbnail, "defaultcommunitywwtthumbnail");
                        childCommunity.Url = string.Format(CultureInfo.InvariantCulture, "{0}/Community/{1}", ServiceBaseUri(), childCommunity.Id);
                    }
                    else
                    {
                        childCommunity.Thumbnail = RewriteThumbnailUrl(childCommunity.Thumbnail, 
                            childCommunity.CommunityType == CommunityTypes.Community ? 
                            "defaultcommunitywwtthumbnail" : 
                            "defaultfolderwwtthumbnail");

                        childCommunity.Url = string.Format(CultureInfo.InvariantCulture, "{0}/Folder/{1}", ServiceBaseUri(), childCommunity.Id);
                    }
                }
            }

            // Get profile details of all the user who have created the tours
            IEnumerable<ProfileDetails> profileDetails = new List<ProfileDetails>();
            if (payloadDetails.Tours.Any())
            {
                // AuthorImageUrl has the created by ID of the user. This needs to be replaced with the URL for users picture
                var userList = payloadDetails.Tours.Select(item => item.AuthorImageUrl).ToList().ConvertAll<long>(Convert.ToInt64).AsEnumerable();
                profileDetails =  _profileService.GetProfiles(userList.Distinct());
            }

            // Update Tour Urls including thumbnail, author and author image
            foreach (var tour in payloadDetails.Tours)
            {
                tour.ThumbnailUrl = RewriteThumbnailUrl(tour.ThumbnailUrl, "defaulttourswwtthumbnail");
                tour.TourUrl = string.Format(CultureInfo.InvariantCulture, "{0}/File/Download/{1}/{2}/wtt/?wwtfull=true", baseUri, tour.TourUrl, Uri.EscapeDataString(tour.Title.Replace("&", "and")));
                tour.AuthorURL = string.Format(CultureInfo.InvariantCulture, "{0}/Profile/Index/{1}", baseUri, tour.AuthorURL);

                // Get profile picture ID using AuthorImageUrl which is CreatedByID value.
                var firstOrDefault = profileDetails.FirstOrDefault(item => item.ID.ToString(CultureInfo.InvariantCulture) == tour.AuthorImageUrl);
                if (firstOrDefault != null)
                {
                    var pictureId = firstOrDefault.PictureID;
                    if (pictureId.HasValue)
                    {
                        tour.AuthorImageUrl = string.Format(CultureInfo.InvariantCulture, "{0}/File/Thumbnail/{1}", baseUri, pictureId.Value);
                    }
                    else 
                    {
                        // return default profile image
                        tour.AuthorImageUrl = RewriteThumbnailUrl(string.Empty, "wwtprofile");
                    }
                }
            }
        }