public override List<VideoInfo> GetVideos(Category category)
 {
     if (category.IsPlayNow())
     {
         List<VideoInfo> videos = new List<VideoInfo>();
         if (category.IsSinglePageCategoriesState())
         {
             foreach (NetflixData d in GetSinglePageNetflixData(category, true))
             {
                 videos.Add(new VideoInfo()
                 {
                     Title = d.Title,
                     VideoUrl = string.Format(playerUrl, d.Id) + "&trkid=" + d.TrackId,
                     Thumb = d.Cover,
                     Description = d.Description,
                     Other = new SerializableDictionary<string, string>() { { "TrackId", d.TrackId }, { "VideoId", d.Id } }
                 });
             }
         }
         return videos;
     }
     return new List<VideoInfo>() { new VideoInfo() { Description = category.Description, VideoUrl = string.Format(playerUrl, (category as RssLink).Url), Title = category.Name, Thumb = category.Thumb } };
 }
        public override int DiscoverSubCategories(Category parentCategory)
        {
            parentCategory.SubCategories = new List<Category>();

            #region Help

            if (parentCategory.IsHelpState())
                throw new OnlineVideosException("Forum: http://tinyurl.com/ov-netflix");

            #endregion

            #region Profiles
            if (parentCategory.IsProfilesState())
            {
                foreach (JToken profile in profiles)
                {
                    Category profileCat = new Category() { Name = profile["profileName"].Value<string>(), HasSubCategories = true, Thumb = profile["avatar"]["images"]["100"].Value<string>(), ParentCategory = parentCategory };
                    profileCat.SetState(NetflixUtils.ProfileState);
                    profileCat.SetProfile(profile);
                    parentCategory.SubCategories.Add(profileCat);
                }
            }

            else if (parentCategory.IsProfileState())
            {
                Settings.Categories.Clear();
                Settings.DynamicCategoriesDiscovered = false;
                currentProfile = parentCategory.GetProfile();
                parentCategory.ParentCategory.Name = ProfileCategoryName;
                MyGetWebData(string.Format(switchProfileUrl, apiRoot, ProfileToken));
                if (rememberStartupUserProfile)
                {
                    List<OnlineVideos.Reflection.FieldPropertyDescriptorByRef> props = GetUserConfigurationProperties();
                    OnlineVideos.Reflection.FieldPropertyDescriptorByRef prop = props.First(p => p.DisplayName == "Startup user profile");
                    this.SetConfigValueFromString(prop, ProfileName);
                    startupUserProfile = ProfileName;
                }
                throw new OnlineVideosException(CangedToProfile);

            }
            #endregion

            #region Home Categories
            

            else if (parentCategory.IsHomeCategoriesState())
            {
                string data = MyGetWebData((parentCategory as RssLink).Url);
                List<Category> cats = GetHomeCategories(data, parentCategory);
                parentCategory.SubCategories = cats;
            }

            #endregion

            #region Kids
            else if (parentCategory.IsKidsState())
            {
                string data = MyGetWebData((parentCategory as RssLink).Url);
                HtmlDocument doc = new HtmlDocument();
                doc.LoadHtml(data);
                RssLink characters = new RssLink() { Name = "Characters", HasSubCategories = true, SubCategories = new List<Category>(), ParentCategory = parentCategory };
                //Well use regex in this case...
                Regex rgx = new Regex(@"title=\\\""(?<name>[^\\]*)\\\"".href=\\\""(?<url>[^\\]*)(?:[^<]*)<img.src=\\""(?<thumb>[^\\]*)");
                foreach (Match m in rgx.Matches(data))
                {
                    RssLink character = new RssLink()
                    {
                        Name = m.Groups["name"].Value,
                        Url = m.Groups["url"].Value,
                        Thumb = m.Groups["thumb"].Value,
                        ParentCategory = characters,
                        HasSubCategories = true
                    };
                    character.SetState(NetflixUtils.SinglePageCategoriesState);
                    characters.SubCategories.Add(character);
                }
                characters.SubCategoriesDiscovered = characters.SubCategories.Count > 0;
                parentCategory.SubCategories.Add(characters);

                foreach (HtmlNode a in doc.DocumentNode.SelectNodes("//a[contains(@href, 'netflix.com/KidsAltGenre')]"))
                {
                    string url = a.GetAttributeValue("href", "");
                    if (!parentCategory.SubCategories.Any(c => (c as RssLink).Url == url))
                    {
                        RssLink category = new RssLink()
                        {
                            Name = a.InnerText.Trim(),
                            Url = a.GetAttributeValue("href", ""),
                            HasSubCategories = true,
                            ParentCategory = parentCategory
                        };
                        category.SetState(NetflixUtils.SinglePageCategoriesState);
                        parentCategory.SubCategories.Add(category);
                    }
                }

            }
            #endregion

            #region SinglePageCategories
            else if (parentCategory.IsSinglePageCategoriesState())
            {
                foreach (NetflixData d in GetSinglePageNetflixData(parentCategory, enableAddRemoveMylist))
                {
                    RssLink cat = new RssLink()
                    {
                        Name = d.Title,
                        Url = d.Id,
                        Thumb = d.Cover,
                        ParentCategory = parentCategory,
                        HasSubCategories = !(parentCategory.ParentCategory != null && parentCategory.ParentCategory.Name == "Characters"),
                        Description = d.Description
                    };
                    cat.SetState(NetflixUtils.TitleState);
                    if (!string.IsNullOrEmpty(d.TrackId))
                        cat.SetTrackId(d.TrackId);
                    parentCategory.SubCategories.Add(cat);
                }
            }
            #endregion

            #region MultiplePageCategories
            else if (parentCategory.IsMultiplePageCategoriesState()) //This is browse categories
            {
                string url = (parentCategory as RssLink).Url;
                string data = MyGetWebData(url);
                SetShaktiApiAndBuildId(data);
                Uri uri = new Uri(url);
                string agid = HttpUtility.ParseQueryString(uri.Query).Get("agid");
                if (!string.IsNullOrEmpty(ShaktiApi) && !string.IsNullOrEmpty(BuildId) && !string.IsNullOrEmpty(agid))
                {
                    data = MyGetWebData(string.Format(genreUrl, ShaktiApi, BuildId, agid, 0, 50, BrowseSort));
                    JObject json = (JObject)JsonConvert.DeserializeObject(data);
                    foreach (JObject item in json["catalogItems"])
                    {
                        RssLink category = new RssLink()
                        {
                            Name = (string)item["title"],
                            Url = ((int)item["titleId"]).ToString(),
                            Thumb = (string)item["boxart"],
                            ParentCategory = parentCategory,
                            HasSubCategories = true,
                            Description = enableDesc && enableDescInListing ? GetTitleDescription(((int)item["titleId"]).ToString(), ((int)item["trackId"]).ToString()) : ""
                        };
                        category.SetState(NetflixUtils.TitleState);
                        if (enableDesc || enableAddRemoveMylist)
                            category.SetTrackId(((int)item["trackId"]).ToString());
                        parentCategory.SubCategories.Add(category);
                    }
                    if (parentCategory.SubCategories.Count >= 50)
                    {
                        NextPageCategory next = new NextPageCategory() { Url = string.Format(genreUrl, ShaktiApi, BuildId, agid, "START_INDEX", "STOP_INDEX", BrowseSort), ParentCategory = parentCategory };
                        next.SetState(NetflixUtils.TitleState);
                        next.SetStartIndex("51");
                        parentCategory.SubCategories.Add(next);
                    }
                }
            }
            #endregion

            #region Title
            else if (parentCategory.IsTitleState())
            {
                string data = MyGetWebData(movieUrl + (parentCategory as RssLink).Url);
                Regex rgx = new Regex(@"nf\.constants\.page\.contextData =(.*); }\(netflix\)\);");
                Match m = rgx.Match(data);
                if (m.Success)
                {
                    string jsonData = m.Groups[1].Value;
                    JObject json = (JObject)JsonConvert.DeserializeObject(jsonData);

                    #region Series
                    if ((bool)json["displayPage"]["data"]["isShow"])
                    {

                        #region Multiple seasons
                        if (data.Contains("class=\"seasonItem"))
                        {
                            HtmlDocument doc = new HtmlDocument();
                            doc.LoadHtml(data);
                            foreach (HtmlNode li in doc.DocumentNode.SelectNodes("//li[starts-with(@class, 'seasonItem')]"))
                            {
                                HtmlNode a = li.SelectSingleNode("a");
                                RssLink season = new RssLink()
                                {
                                    Name = "Season " + a.InnerText,
                                    Url = string.Format(seasonDetailsUrl, (parentCategory as RssLink).Url, a.GetAttributeValue("data-vid", "")),
                                    HasSubCategories = true,
                                    ParentCategory = parentCategory,
                                    Thumb = parentCategory.Thumb
                                };
                                season.SetState(NetflixUtils.EpisodesState);
                                parentCategory.SubCategories.Add(season);
                            }
                        }
                        #endregion

                        #region Single season
                        else if (data.Contains("data-episodeid=\""))
                        {
                            HtmlDocument doc = new HtmlDocument();
                            doc.LoadHtml(data);
                            HtmlNode docNode = doc.DocumentNode;
                            HtmlNode seasonNode = docNode.SelectSingleNode("//span[@class = 'selectorTxt']");
                            string season = seasonNode == null ? "1x" : (seasonNode.InnerText + "x");
                            HtmlNode episodes = docNode.SelectSingleNode("//ul[@class = 'episodeList']");
                            foreach (HtmlNode episode in episodes.SelectNodes("li"))
                            {
                                string seqNum = episode.SelectSingleNode("span[@class = 'seqNum']").InnerText;
                                HtmlNode pDesc = enableDesc ? episode.SelectSingleNode(".//p[@class = 'synopsis']") : null;
                                parentCategory.SubCategories.Add(new RssLink()
                                {
                                    Name = season + (seqNum.Count() < 2 ? ("0" + seqNum) : seqNum) + " " + episode.SelectSingleNode("span[@class = 'episodeTitle']").InnerText,
                                    Url = episode.GetAttributeValue("data-episodeid", ""),
                                    ParentCategory = parentCategory,
                                    Thumb = parentCategory.Thumb,
                                    Description = pDesc != null ? pDesc.InnerText : "",
                                    HasSubCategories = false
                                });
                            }
                        }
                        #endregion

                        #region Netflix title
                        else
                        {
                            data = MyGetWebData(string.Format(netflixOrgEpisodes, apiRoot, (parentCategory as RssLink).Url, latestAuthUrl));
                            rgx = new Regex(@"({""title"":[^$]*)");
                            m = rgx.Match(data);
                            if (m.Success)
                            {
                                data = m.Groups[1].Value;

                                json = (JObject)JsonConvert.DeserializeObject(data);
                                foreach (JArray seasonArray in json["episodes"])
                                {
                                    foreach (JToken episode in seasonArray.Where(e => e["availableForED"] == null || e["availableForED"].Value<bool>()))
                                    {
                                        int e = (int)episode["episode"];
                                        int s = (int)episode["season"];
                                        RssLink cat = new RssLink()
                                        {
                                            Name = s + "x" + (e < 10 ? ("0" + e) : e.ToString()) + " " + (string)episode["title"],
                                            ParentCategory = parentCategory,
                                            Thumb = parentCategory.Thumb,
                                            HasSubCategories = false,
                                            Url = episode["episodeId"].ToString()
                                        };
                                        JToken stills = episode["stills"];
                                        if (stills != null && stills.Count() > 0)
                                        {
                                            cat.Thumb = stills.Last()["url"].Value<string>();
                                        }
                                        if (enableDesc)
                                        {
                                            cat.Description = episode["synopsis"].Value<string>();
                                        }
                                        parentCategory.SubCategories.Add(cat);
                                    }
                                }
                                parentCategory.SubCategories.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
                            }
                        #endregion
                        }
                    }
                    #endregion

                    #region Movies
                    else
                    {
                        parentCategory.SubCategories.Add(new RssLink() { Description = GetTitleDescription((parentCategory as RssLink).Url, parentCategory.GetTrackId()), Name = parentCategory.Name, Url = (parentCategory as RssLink).Url, Thumb = parentCategory.Thumb, ParentCategory = parentCategory, HasSubCategories = false });
                    }
                    #endregion
                }
            }


            #endregion

            #region Episodes
            else
            {
                string jsonData = MyGetWebData((parentCategory as RssLink).Url);
                JObject json = (JObject)JsonConvert.DeserializeObject(jsonData);
                string data = (string)json["html"];
                HtmlDocument doc = new HtmlDocument();
                doc.LoadHtml(data);
                HtmlNode docNode = doc.DocumentNode;
                HtmlNode episodes = docNode.SelectSingleNode("//ul[@class = 'episodeList']");
                foreach (HtmlNode episode in episodes.SelectNodes("li"))
                {
                    string seqNum = episode.SelectSingleNode("span[@class = 'seqNum']").InnerText;
                    HtmlNode pDesc = enableDesc ? episode.SelectSingleNode(".//p[@class = 'synopsis']") : null;
                    parentCategory.SubCategories.Add(new RssLink()
                    {
                        Name = parentCategory.Name.Replace("Season", "") + "x" + (seqNum.Count() < 2 ? ("0" + seqNum) : seqNum) + " " + episode.SelectSingleNode("span[@class = 'episodeTitle']").InnerText,
                        Url = episode.GetAttributeValue("data-episodeid", ""),
                        ParentCategory = parentCategory,
                        Thumb = parentCategory.Thumb,
                        Description = pDesc != null ? pDesc.InnerText : "",
                        HasSubCategories = false
                    });
                }
            }
            #endregion

            parentCategory.SubCategoriesDiscovered = parentCategory.RememberDiscoveredItems() && parentCategory.SubCategories.Count > 0;
            return parentCategory.SubCategories.Count;
        }