public override StoryInfo RequestInfo(string storyUrl)
        {
            var html = NetworkHelper.GetHtml(storyUrl);

            HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlDocument();

            htmlDoc.LoadHtml(html);

            var nameNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id=\"bc\"]//a[last()]");

            StoryInfo info = new StoryInfo()
            {
                Url = storyUrl,
                Name = nameNode.InnerText.Trim(),
            };

            var chapterNodes = htmlDoc.DocumentNode.SelectNodes("//*[@class=\"download-link\"]");

            foreach (HtmlNode chapter in chapterNodes)
            {
                ChapterInfo chap = new ChapterInfo()
                {
                    Name = chapter.InnerText ,//+ " " + chapter.ChildNodes[0].InnerText + " " + chapter.ChildNodes[1].InnerText,
                    Url = HostUrl + chapter.Attributes["href"].Value,
                    
                };
                chap.ChapId = ExtractID(chap.Name);
                info.Chapters.Add(chap);
            }
            info.Chapters = info.Chapters.OrderBy(p => p.ChapId).ToList();
            return info;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {
            string urlPattern = this.ListStoryURL;

            List<StoryInfo> results = base.ReloadChachedData();
            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();
               
                    
                string html = NetworkHelper.GetHtml(this.ListStoryURL);
                HtmlDocument htmlDoc = new HtmlDocument();
                htmlDoc.LoadHtml(html);

                var nodes = htmlDoc.DocumentNode.SelectNodes("//*[@class=\"series_index\"]//a");
                if (nodes != null && nodes.Count > 0)
                {
                    foreach (var node in nodes)
                    {
                        StoryInfo info = new StoryInfo()
                        {
                            Url = node.Attributes["href"].Value,
                            Name = node.InnerText.Trim()
                        };
                        results.Add(info);
                    }

                       
                }
                

            }
            this.SaveCache(results);
            return results;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {


            List<StoryInfo> results = base.ReloadChachedData();
            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();

                string html = NetworkHelper.GetHtml(this.ListStoryURL);
                HtmlDocument htmlDoc = new HtmlDocument();
                htmlDoc.LoadHtml(html);

                var nodes = htmlDoc.DocumentNode.SelectNodes("//div[@class=\"list_manga\"]//li/a");

                foreach (var node in nodes)
                {
                    StoryInfo info = new StoryInfo()
                    {
                        Url =  node.Attributes["href"].Value,
                        Name = node.Attributes["rel"].Value.Trim()
                    };
                    results.Add(info);
                }


            }
            this.SaveCache(results);
            return results;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {


            List<StoryInfo> results = base.ReloadChachedData();
            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();

                string html = NetworkHelper.GetHtml(this.ListStoryURL);
                HtmlDocument htmlDoc = new HtmlDocument();
                htmlDoc.LoadHtml(html);

                var nodes = htmlDoc.DocumentNode.SelectNodes("//*[@id=\"inner_page\"]//div[contains(@class,\"c_h\")]/a");
                if(nodes!=null)
                foreach (var node in nodes)
                {
                    StoryInfo info = new StoryInfo()
                    {
                        Url = HostUrl + node.Attributes["href"].Value,
                        Name = node.InnerText.Trim()
                    };
                    results.Add(info);
                }


            }
            this.SaveCache(results);
            return results;
        }
        public override StoryInfo RequestInfo(string storyUrl)
        {
            var html = NetworkHelper.GetHtml(storyUrl);

            HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlDocument();

            htmlDoc.LoadHtml(html);

            var nameNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id=\"main\"]//h1");

            StoryInfo info = new StoryInfo()
            {
                Url = storyUrl,
                Name = nameNode.ChildNodes[1].InnerText.Trim(),
            };

            var chapterNodes = htmlDoc.DocumentNode.SelectNodes("//*[@class=\"detail_list\"]//li//a");

            foreach (HtmlNode chapter in chapterNodes)
            {
                ChapterInfo chap = new ChapterInfo()
                {
                    Name = chapter.InnerText.Trim(),
                    Url = chapter.Attributes["href"].Value,
                    ChapId = ExtractID(chapter.InnerText.Trim())
                };
                info.Chapters.Add(chap);
            }
            info.Chapters = info.Chapters.OrderBy(p => p.ChapId).ToList();
            return info;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {
             List<StoryInfo> results = ReloadChachedData();
            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();

            string html = NetworkHelper.GetHtml(this.ListStoryURL);
                HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();

                // There are various options, set as needed
                htmlDoc.OptionFixNestedTags = true;

                StringReader reader = new StringReader(html);
                // filePath is a path to a file containing the html
                htmlDoc.Load(reader);

                //if (htmlDoc.ParseErrors != null && htmlDoc.ParseErrors.Count() > 0)
                //{
                //    // Handle any parse errors as required

                //}
                //else

                {

                    if (htmlDoc.DocumentNode != null)
                    {
                        var nodes = htmlDoc.DocumentNode.SelectNodes("//div[@class='list-manga-paging']/span");

                        int count = nodes.Count;
                   
                        foreach (var item in nodes.Take(count))
                        {
                            string requestListPage = string.Format("http://vechai.info/list.php?job=ajaxlist&letter=all&page={0}&sort=1", item.InnerText);
                            var pageHtml = NetworkHelper.GetHtml(requestListPage);

                            string regex = "<span class=\"item-number\">(\\d*)</span><a href=\"/([\\d\\w\\s_-]*)/\">(.*)</a>";

                            var matches = Regex.Matches(pageHtml, regex);
                            foreach (Match match in matches)
                            {
                                var story = new StoryInfo()
                                {
                                    Url = HostUrl + "/" + match.Groups[2].Value,

                                    Name = match.Groups[3].Value
                                };
                                results.Add(story);

                            }
                        }
                    }
                }
                
            }
            SaveCache(results);
            return results;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {
             List<StoryInfo> results = base.ReloadChachedData();
             if (results == null || results.Count == 0 || forceOnline)
             {
                 results = new List<StoryInfo>();

                 var html = NetworkHelper.GetHtml(this.ListStoryURL);

                 HtmlDocument htmlDoc = new HtmlDocument();
                 htmlDoc.LoadHtml(html);

                 var catPages = htmlDoc.DocumentNode.SelectNodes("/html/body/div[2]//a[@href]");
                 foreach (var item in catPages)
                 {
                     string urlPattern = item.Attributes["href"].Value.Replace(".html", "_{0}.html");


                     int currentPage = 1;
                     bool isStillHasPage = true;
                     while (isStillHasPage)
                     {
                         string url = string.Format(urlPattern, currentPage);

                         var phtml = NetworkHelper.GetHtml(url);
                         HtmlDocument phtmlDoc = new HtmlDocument();
                         phtmlDoc.LoadHtml(phtml);

                         var nodes = phtmlDoc.DocumentNode.SelectNodes("//*[@class='intro']//h2/a");
                         if (nodes != null && nodes.Count > 0)
                         {
                             currentPage++;
                             foreach (var node in nodes)
                             {
                                 StoryInfo info = new StoryInfo()
                                 {
                                     Url =node.Attributes["href"].Value,
                                     Name = node.InnerText.Trim()
                                 };
                                 results.Add(info);
                             }
                         }
                         else
                         {
                             isStillHasPage = false;
                         }

                     }

                 }
             }
            this.SaveCache(results);
            return results;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {
            string urlPattern = this.ListStoryURL + "?page={0}";

            List<StoryInfo> results = base.ReloadChachedData();

            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();
                int currentPage = 1;
                bool isStillHasPage = true;
                while (isStillHasPage)
                {
                    string url = string.Format(urlPattern, currentPage);

                    string html = NetworkHelper.GetHtml(url);
                    //var pattern = "<a class=\"bigChar\" href=\"(.*)\">(.*)</a>";

                    HtmlDocument htmlDoc = new HtmlDocument();
                    htmlDoc.LoadHtml(html);
                    var nodes = htmlDoc.DocumentNode.SelectNodes("//*[@class=\"listing\"]/tr/td[1]/a");
                    //var nodes = htmlDoc.DocumentNode.Descendants("a")
                    //                    .Where(p => p.Attributes.Contains("class") &&
                    //                              p.Attributes["class"].Value == "bigChar")
                    //                    .ToList();
                    //var matches = Regex.Matches(html, pattern);
                    if (nodes != null && nodes.Count > 0)
                    {
                        currentPage++;
                        //cheat page 25 return no result
                        if (currentPage == 25) currentPage++;
                        foreach (HtmlNode node in  nodes)
                        {
                            StoryInfo info = new StoryInfo()
                            {
                                Url = HostUrl  +node.Attributes["href"].Value,
                                Name = node.InnerText.Trim(),
                            };
                            results.Add(info);
                        }
                    }
                    else
                    {
                        isStillHasPage = false;
                    }

                }

            }
            this.SaveCache(results);
            return results;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {
            string urlPattern = this.ListStoryURL + "trang-{0}.html";
           
            List<StoryInfo> results = base.ReloadChachedData();
            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();


                string html = NetworkHelper.GetHtml(this.ListStoryURL);
                HtmlDocument htmlDoc = new HtmlDocument();
                htmlDoc.LoadHtml(html);

                var totalPageNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@class=\"navigation\"]//span[1]/b[2]");

                int totalPage = Convert.ToInt32(totalPageNode.InnerText);
                for (int i = 1; i <= totalPage; i++)
                {
                    
              
                    string url = string.Format(urlPattern, i);

                     html = NetworkHelper.GetHtml(url);
                    HtmlDocument parser = new HtmlDocument();
                    parser.LoadHtml(html);

                    var nodes = parser.DocumentNode.SelectNodes("//*[@id=\"table_example\"]//td[1]/a");
                    if (nodes != null && nodes.Count > 0)
                    {
                        
                        foreach (var node in nodes)
                        {
                            StoryInfo info = new StoryInfo()
                            {
                                Url = node.Attributes["href"].Value,
                                Name = node.FirstChild.InnerText
                            };
                            results.Add(info);
                        }
                    }
                  
                                        
                }

            }
            this.SaveCache(results);
            return results;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {
            string urlPattern = "http://truyen.lauphim.com/manga-list/all/any/name-az/{0}/";
            //*[@id="sct_content"]/div/div/div[1]/ul
            List<StoryInfo> results = base.ReloadChachedData();
            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();

                string html = NetworkHelper.GetHtml(ListStoryURL);
                HtmlDocument htmlDoc = new HtmlDocument();
                htmlDoc.LoadHtml(html);

                var node = htmlDoc.DocumentNode.SelectSingleNode("//*[@class=\"pgg\"]//li[last()]/a");
                
                var match = Regex.Match(node.Attributes["href"].Value,@"/(\d*)/$");
                
                int totalPage = int.Parse(match.Groups[1].Value);;
                for (int i = 1; i <= totalPage; i++)
			{
                    string url = string.Format(urlPattern, i);

                     html = NetworkHelper.GetHtml(url);
                     htmlDoc.LoadHtml(html);

                     var nodes = htmlDoc.DocumentNode.SelectNodes("//*[@id=\"sct_content\"]//div[contains(@class,\"img_wrp\")]//a[1]");
                    if (nodes != null && nodes.Count > 0)
                    {
                        
                        foreach (var currentNode in nodes)
                        {
                            StoryInfo info = new StoryInfo()
                            {
                                Url = currentNode.Attributes["href"].Value,
                                Name = currentNode.Attributes["title"].Value.Trim()
                            };
                            results.Add(info);
                        }
                    }
                   
                                        
                }

            }
            
            this.SaveCache(results);
            return results;
        }
        public override StoryInfo RequestInfo(string url)
        {
            StoryInfo info = new StoryInfo();

            // LockControl(false);
            //string url = string.Format(StoryUrlPattern, urlSegment);

            var html = NetworkHelper.GetHtml(url);

            HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
            htmlDoc.LoadHtml(html);

            var node = htmlDoc.DocumentNode.SelectSingleNode("//*[@id=\"fontsize-chitiet\"]/span[1]");
            info.Name = node.InnerText;
            var node2 = htmlDoc.DocumentNode.SelectSingleNode("//*[@id=\"fontsize-chitiet\"]/span[2]");
            info.AltName = node2.InnerText;
            var node3 = htmlDoc.DocumentNode.SelectSingleNode("//*[@id=\"fontsize-chitiet\"]/span[2]");
            info.Categories = node3.InnerText;
            info.Url = url;

            var ccontentmain = htmlDoc.DocumentNode.SelectSingleNode("//*[@id=\"content-main\"]");
            

            htmlDoc.LoadHtml(ccontentmain.InnerHtml);

            var chapterLinks = htmlDoc.DocumentNode.SelectNodes("//a[@href!='']");

            info.ChapterCount = chapterLinks.Count;
            foreach (HtmlNode item in chapterLinks)
            {

                ChapterInfo chapter = new ChapterInfo()
                {
                    Url = string.Format("{0}{1}doc-truyen/", HostUrl, item.Attributes["href"].Value),
                    Name = item.InnerText
                    ,
                    ChapId = ExtractID(item.InnerText)

                };
               

                info.Chapters.Add(chapter);
            }

            info.Chapters = info.Chapters.OrderBy(p => p.ChapId).ToList();

            return info;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {
            string urlPattern = this.ListStoryURL + "{0}";

            List<StoryInfo> results = base.ReloadChachedData();

            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();
                int currentPage = 1;
                bool isStillHasPage = true;
                while (isStillHasPage)
                {
                    string url = string.Format(urlPattern, currentPage);

                    string html = NetworkHelper.GetHtml(url);


                    HtmlDocument htmlDoc = new HtmlDocument();
                    htmlDoc.LoadHtml(html);

                    var nodes = htmlDoc.DocumentNode.SelectNodes("//div[@class=\"list_search\"]//h3/a");
                                        
                    if (nodes != null && nodes.Count > 0)
                    {
                        currentPage++;
                        foreach (HtmlNode node in nodes)
                        {
                            StoryInfo info = new StoryInfo()
                            {
                                Url = node.Attributes["href"].Value,
                                Name = node.InnerText,
                            };
                            results.Add(info);
                        }
                    }
                    else
                    {
                        isStillHasPage = false;
                    }

                }

            }
            this.SaveCache(results);
            return results;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {
            string urlPattern = "http://www.hakihome.com/ListMangaHentai.html/pagel/{0}/";
           
            List<StoryInfo> results = base.ReloadChachedData();
            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();
                int currentPage = 1;
                bool isStillHasPage = true;
                while (isStillHasPage)
                {
                    string url = string.Format(urlPattern, currentPage);

                    string html = NetworkHelper.GetHtml(url);
                    HtmlDocument htmlDoc = new HtmlDocument();
                    htmlDoc.LoadHtml(html);

                    var nodes = htmlDoc.DocumentNode.SelectNodes("//*[@class=\"listing\"]//td[1]/a");
                    if (nodes != null && nodes.Count > 0)
                    {
                        currentPage++;
                        foreach (var node in nodes)
                        {
                            StoryInfo info = new StoryInfo()
                            {
                                Url = node.Attributes["href"].Value,
                                Name = node.InnerText
                            };
                            results.Add(info);
                        }
                    }
                    else
                    {
                        isStillHasPage = false;
                    }
                                        
                }

            }
            results = results.OrderBy(p => p.Name).ToList();
            this.SaveCache(results);
            return results;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {

            string urlPattern = "http://www.jpmanga.com/manga-directory-p{0}/"; 

            List<StoryInfo> results = base.ReloadChachedData();
            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();
                int currentPage = 1;
                bool isStillHasPage = true;
                while (isStillHasPage)
                {
                    string url = string.Format(urlPattern, currentPage);

                    string html = NetworkHelper.GetHtml(url);
                    HtmlDocument htmlDoc = new HtmlDocument();
                    htmlDoc.LoadHtml(html);

                    var nodes = htmlDoc.DocumentNode.SelectNodes("//*[@class=\"lvkbg2\"]//td[1]/a[@class=\"a_comicname\"]");
                    if (nodes != null && nodes.Count > 0)
                    {
                        currentPage++;
                        foreach (var node in nodes)
                        {
                            StoryInfo info = new StoryInfo()
                            {
                                Url = HostUrl + node.Attributes["href"].Value,
                                Name = node.InnerText.Trim()
                            };
                            results.Add(info);
                        }
                    }
                    else
                    {
                        isStillHasPage = false;
                    }

                }

            }
            this.SaveCache(results);
            return results;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {
            string urlPattern = this.ListStoryURL + "{0}";

            List<StoryInfo> results = base.ReloadChachedData();
            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();
                int currentPage = 1;
                bool isStillHasPage = true;
                while (isStillHasPage)
                {
                    string url = string.Format(urlPattern, currentPage);
                    string html = NetworkHelper.GetHtml(url);
                    HtmlDocument htmlDoc = new HtmlDocument();
                    htmlDoc.LoadHtml(html);

                    var urlNodes = htmlDoc.DocumentNode.SelectNodes("//*[@class=\"footer bg9 leftBoxFtr\"]/p/a");
                    var titleNodes = htmlDoc.DocumentNode.SelectNodes("//*[@class=\"infoBox-title\"]/h2");
                    if (urlNodes != null && urlNodes.Count > 0)
                    {
                        currentPage++;

                        for(int i = 0; i < urlNodes.Count; i++)
                        {
                            StoryInfo info = new StoryInfo()
                            {
                                Url = HostUrl.Substring(0,HostUrl.Length-1) + urlNodes[i].Attributes["href"].Value,
                                Name = titleNodes[i].InnerText.Trim()
                            };
                            results.Add(info);
                        }
                    }
                    else
                    {
                        isStillHasPage = false;
                    }

                }

            }
            this.SaveCache(results);
            return results;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {
            List<StoryInfo> results = base.ReloadChachedData();

            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();

                string[] urls = {"http://blogtruyen.com/list/list-0abc-3.js",
                              "http://blogtruyen.com/list/list-defgh-3.js",
                              "http://blogtruyen.com/list/list-ijkl-3.js",
                              "http://blogtruyen.com/list/list-mnop-3.js",
                              "http://blogtruyen.com/list/list-qrst-3.js",
                              "http://blogtruyen.com/list/list-uvwxyz-3.js"
                             };
                foreach (var url in urls)
                {

                    string html = NetworkHelper.GetHtml(url);

                    HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
                    htmlDoc.LoadHtml(html);
                    var links = htmlDoc.DocumentNode.SelectNodes("//*[@class=\"listing\"]//a");

                    //htmlDoc.LoadHtml(table.InnerHtml);
                    //var links = htmlDoc.DocumentNode.SelectNodes("//a");
                    foreach (HtmlNode item in links)
                    {
                        StoryInfo info = new StoryInfo()
                        {
                            Name = item.InnerText,
                            Url = item.Attributes["href"].Value
                        };
                        results.Add(info);
                    }
#if DEBUG
                   // break;
#endif
                }
            }
            base.SaveCache(results);
            return results;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {
            string urlPattern = this.ListStoryURL + "npage-{0}";

            List<StoryInfo> results = base.ReloadChachedData();
            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();
                int currentPage = 1;
                bool isStillHasPage = true;
                while (isStillHasPage)
                {
                    string url = currentPage == 1 ? ListStoryURL : string.Format(urlPattern, currentPage);
                    string html = NetworkHelper.GetHtml(url);
                    HtmlDocument htmlDoc = new HtmlDocument();
                    htmlDoc.LoadHtml(html);

                    var nodes = htmlDoc.DocumentNode.SelectNodes("//*[@id=\"MostPopular\"]//td[1]/a");
                    if (nodes != null && nodes.Count > 0)
                    {
                        currentPage++;
                        foreach (var node in nodes)
                        {
                            StoryInfo info = new StoryInfo()
                            {
                                Url = HostUrl + node.Attributes["href"].Value,
                                Name = node.ChildNodes[2].InnerText.Trim()
                            };
                            results.Add(info);
                        }
                    }
                    else
                    {
                        isStillHasPage = false;
                    }

                }

            }
            this.SaveCache(results);
            return results;
        }
        public override List<StoryInfo> GetListStories(bool forceOnline)
        {
            string urlPattern = this.ListStoryURL + "{0}";

            List<StoryInfo> results = base.ReloadChachedData();

            if (results == null || results.Count == 0 || forceOnline)
            {
                results = new List<StoryInfo>();


                string html = NetworkHelper.GetHtml(this.ListStoryURL);

                
                string p = "<option value='([^>]*)'>([^<]*)</option>";

                var matches = Regex.Matches(html, p);

                if (matches != null && matches.Count > 0)
                {

                    foreach (Match m in matches)
                    {
                        StoryInfo info = new StoryInfo()
                        {
                            Url = HostUrl+m.Groups[1].Value,
                            Name = m.Groups[2].Value,
                        };
                        results.Add(info);
                    }
                }


            }


            this.SaveCache(results);
            return results;
        }
        public override StoryInfo RequestInfo(string storyUrl)
        {
            var html = NetworkHelper.GetHtml(storyUrl);

            HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlDocument();

            htmlDoc.LoadHtml(html);

            var nameNode = htmlDoc.DocumentNode.SelectSingleNode("//section[@class=\"manga\"]//h1");

            StoryInfo info = new StoryInfo()
            {
                Url = storyUrl,
                Name = nameNode.InnerText.Trim().Replace("Manga",""),
            };

            
            var chapters = htmlDoc.DocumentNode.SelectNodes("//*[@id=\"list\"]//li/span/a");
            var links = htmlDoc.DocumentNode.SelectNodes("//*[@id=\"list\"]//em/a[last()]");

            for (int i = 0; i < chapters.Count; i++)
            {
            
                ChapterInfo chap = new ChapterInfo()
                {
                    Name = chapters[i].ChildNodes[0].InnerText + chapters[i].ChildNodes[1].InnerText,
                    Url = HostUrl + links[i].Attributes["href"].Value.Trim()
                    //ChapId = ExtractID(chapter.InnerText)
                };
                chap.ChapId = ExtractID(chap.Name, "Ch.(\\d*)");
                info.Chapters.Add(chap);
            }
            
            info.Chapters = info.Chapters.OrderBy(p => p.ChapId).ToList();
            return info;
        }
        public override StoryInfo RequestInfo(string storyUrl)
        {
            var html = NetworkHelper.GetHtml(storyUrl);

            HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlDocument();

            htmlDoc.LoadHtml(html);

            var nameNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id=\"title\"]//h1");

            StoryInfo info = new StoryInfo()
            {
                Url = storyUrl,
                Name = nameNode.InnerText.Replace("Manga",""),
            };

            var volumns = htmlDoc.DocumentNode.SelectNodes("//*[@class=\"slide\"]");
            foreach (HtmlNode item in volumns)
	        {
		    string vol = item.SelectSingleNode("h3").InnerText;
            vol = Regex.Replace(vol, "(Volume \\d*).*", "$1");
            var chapterNodes = item.NextSibling.SelectNodes("li//a[@class=\"tips\"]");
            foreach (HtmlNode chapter in chapterNodes)
            {
                ChapterInfo chap = new ChapterInfo()
                {
                    Name =vol+" - "+ chapter.InnerText,
                    Url = chapter.Attributes["href"].Value,
                    ChapId = ExtractID(chapter.InnerText)
                };
                info.Chapters.Add(chap);
            }
            }
            info.Chapters = info.Chapters.OrderBy(p => p.ChapId).ToList();
            return info;
        }
        public override List<StoryInfo> OnlineSearch(string keyword)
        {
            string urlPattern = string.Format("http://manga4.com/search?Type%3A=either&title_range=0&title={0}&author_range=0&author=&artist_range=0&artist=&genre%5BAction%5D=0&genre%5BAdventure%5D=0&genre%5BComedy%5D=0&genre%5BDoujinshi%5D=0&genre%5BDrama%5D=0&genre%5BEcchi%5D=0&genre%5BFantasy%5D=0&genre%5BGender_Bender%5D=0&genre%5BHarem%5D=0&genre%5BHistorical%5D=0&genre%5BHorror%5D=0&genre%5BJosei%5D=0&genre%5BMartial_Arts%5D=0&genre%5BMature%5D=0&genre%5BMecha%5D=0&genre%5BMystery%5D=0&genre%5BPsychological%5D=0&genre%5BRomance%5D=0&genre%5BSchool_Life%5D=0&genre%5BSci-fi%5D=0&genre%5BSeinen%5D=0&genre%5BShotacon%5D=0&genre%5BShoujo%5D=0&genre%5BShoujo_Ai%5D=0&genre%5BShounen%5D=0&genre%5BShounen_Ai%5D=0&genre%5BSlice_of_Life%5D=0&genre%5BSmut%5D=0&genre%5BSports%5D=0&genre%5BSupernatural%5D=0&genre%5BTragedy%5D=0&genre%5BYaoi%5D=0&genre%5BYuri%5D=0&Completed=0&yor_range=0&year=", keyword.Replace(" ", "+"));
            urlPattern = urlPattern + "&page={0}";

            var results = new List<StoryInfo>();

            //page 1 ung voi &page=0
            int currentPage = 0;
            while (currentPage < Constant.LimitedPageForSearch)
            {
                string url = string.Format(urlPattern, currentPage);

                string html = NetworkHelper.GetHtml(url);
                HtmlDocument htmlDoc = new HtmlDocument();
                htmlDoc.LoadHtml(html);

                var nodes = htmlDoc.DocumentNode.SelectNodes("//ul[@class=\"mangalist\"]/li/div[@class=\"manga-details\"]/h3//a");
                if (nodes != null && nodes.Count > 0)
                {

                    foreach (var node in nodes)
                    {

                        StoryInfo info = new StoryInfo()
                        {
                            Url = HostUrl + node.Attributes["href"].Value,
                            Name = node.InnerText.Trim()
                        };
                        results.Add(info);
                    }
                }

                currentPage++;
            }
            return results;
        }
        public override List<StoryInfo> OnlineSearch(string keyword)
        {
            string urlPattern = string.Format("http://www.mangahere.com/search.php?name={0}", keyword.Replace(" ", "+"));
            urlPattern = urlPattern + "&page={0}";

            var results = new List<StoryInfo>();

            int currentPage = 1;

            while (currentPage <= Constant.LimitedPageForSearch)
            {
                string url = string.Format(urlPattern, currentPage);

                string html = NetworkHelper.GetHtml(url);
                HtmlDocument htmlDoc = new HtmlDocument();
                htmlDoc.LoadHtml(html);

                var nodes = htmlDoc.DocumentNode.SelectNodes("//div[@class=\"result_search\"]/dl/dt/a[position()=1]");
                if (nodes != null && nodes.Count > 0)
                {

                    foreach (var node in nodes)
                    {

                        StoryInfo info = new StoryInfo()
                        {
                            Url = node.Attributes["href"].Value,
                            Name = node.InnerText.Trim()
                        };
                        results.Add(info);
                    }
                }

                currentPage++;
            }
            return results;
        }
        public override List<StoryInfo> GetLastestUpdates()
        {
            string lastestUpdateUrl = HostUrl;
            List<StoryInfo> stories = new List<StoryInfo>();
            var html = NetworkHelper.GetHtml(lastestUpdateUrl);

            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(html);
            var nodes = htmlDoc.DocumentNode.SelectNodes("//div[@class=\"manga_updates\"]//dt/a");

            foreach (HtmlNode node in nodes)
            {
                StoryInfo info = new StoryInfo()
                {
                    Url = node.Attributes["href"].Value,
                    Name = node.InnerText.Trim(),
                    Chapters = new List<ChapterInfo>(),
                };
                var chapters = node.ParentNode.ParentNode.SelectNodes("dd/a");
                if (chapters != null)
                    foreach (HtmlNode chap in chapters)
                    {
                        info.Chapters.Add(new ChapterInfo()
                        {
                            Name = chap.InnerText.Trim(),
                            Url = chap.Attributes["href"].Value,
                        });
                    }
                stories.Add(info);
            }
            return stories;
        }
        public override List<StoryInfo> GetLastestUpdates()
        {
            string lastestUpdateUrl = HostUrl;
            List<StoryInfo> stories = new List<StoryInfo>();
            var html = NetworkHelper.GetHtml(lastestUpdateUrl);

            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(html);
            var nodes = htmlDoc.DocumentNode.SelectNodes("//div[@class=\"side-list\"]//td/a");

            foreach (HtmlNode node in nodes)
            {
                var chapUrl = HostUrl + node.Attributes["href"].Value;
                var storyUrl = chapUrl.Substring(0, chapUrl.LastIndexOf("/"));
                storyUrl = storyUrl.Substring(0, storyUrl.LastIndexOf("/"));

                var chapTitle = node.InnerText.Trim();
                chapTitle = chapTitle.Substring(chapTitle.LastIndexOf("]") + 1);
                var storyTitle = chapTitle.Substring(0, chapTitle.LastIndexOf(" "));

                StoryInfo info = new StoryInfo()
                {
                    Url = storyUrl ,
                    Name = storyTitle,
                    Chapters = new List<ChapterInfo>(),
                };

                info.Chapters.Add(new ChapterInfo()
                {
                    Name = chapTitle,
                    Url = chapUrl
                });

                stories.Add(info);
            }
            return stories;
        }
        public override StoryInfo RequestInfo(string url)
        {

            var html = NetworkHelper.GetHtml(url);

            HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
            htmlDoc.LoadHtml(html);
            var nameNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id=\"mangainfo\"]//h3");

            StoryInfo info = new StoryInfo()
            {
                Url = url,
                Name = nameNode.InnerText.Trim()
            };

            var chapterLinks = htmlDoc.DocumentNode.SelectNodes("//*[@id=\"manga_chapters\"]//span[1]/a");

            info.ChapterCount = chapterLinks.Count;
            foreach (HtmlNode item in chapterLinks)
            {

                ChapterInfo chapter = new ChapterInfo()
                {
                    Url = item.Attributes["href"].Value,
                    Name = item.InnerText
                    ,
                    ChapId = ExtractID(item.InnerText, @"Chapter (\d*)")

                };


                info.Chapters.Add(chapter);
            }

            info.Chapters = info.Chapters.OrderBy(p => p.ChapId).ToList();

            return info;
        }
        public override List<StoryInfo> OnlineSearch(string keyword)
        {
            string urlPattern = string.Format("http://www.mangareader.net/search/?w={0}&rd=0&status=0&order=0&genre=0000000000000000000000000000000000000", keyword.Replace(" ", "+"));
            urlPattern = urlPattern + "&p={0}";

            var results = new List<StoryInfo>();

            //&p= so item da hien
            int currentPage = 1;
            int items = 0;

            while (currentPage <= Constant.LimitedPageForSearch)
            {
                string url = string.Format(urlPattern, currentPage);

                string html = NetworkHelper.GetHtml(url);
                HtmlDocument htmlDoc = new HtmlDocument();
                htmlDoc.LoadHtml(html);

                var nodes = htmlDoc.DocumentNode.SelectNodes("//*[@class=\"manga_name\"]//h3/a");
                if (nodes != null && nodes.Count > 0)
                {

                    foreach (var node in nodes)
                    {

                        StoryInfo info = new StoryInfo()
                        {
                            Url = HostUrl + node.Attributes["href"].Value,
                            Name = node.InnerText.Trim()
                        };
                        results.Add(info);
                    }
                }

                items = results.Count;
                currentPage++;
            }
            return results;
        }
        public override List<StoryInfo> GetLastestUpdates()
        {
            List<StoryInfo> stories = new List<StoryInfo>();
            var html = NetworkHelper.GetHtml(this.HostUrl);

            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(html);
            var nodes = htmlDoc.DocumentNode.SelectNodes("//*[@id=\"latestchapters\"]/table[1]//a[@class=\"chapter\"]");

            foreach (HtmlNode node in nodes)
            {
                StoryInfo info = new StoryInfo()
                {
                    Url = HostUrl + node.Attributes["href"].Value,
                    Name = node.InnerText.Trim(),
                    Chapters = new List<ChapterInfo>(),
                };
                var chapters = node.ParentNode.SelectNodes("a[@class='chaptersrec']");
                if (chapters != null)
                    foreach (HtmlNode chap in chapters)
                    {
                        info.Chapters.Add(new ChapterInfo()
                        {
                            Name = chap.InnerText.Trim(),
                            Url = HostUrl + chap.Attributes["href"].Value,
                        });
                    }
                stories.Add(info);
            }
            return stories;
        }
        public override List<StoryInfo> GetLastestUpdates()
        {
            string lastestUpdateUrl = HostUrl;
            List<StoryInfo> stories = new List<StoryInfo>();
            var html = NetworkHelper.GetHtml(lastestUpdateUrl);

            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(html);
            var nodes = htmlDoc.DocumentNode.SelectNodes("//div[@id=\"leftcol\"]/div[@style]/div/li[position()=1]/a");

            foreach (HtmlNode node in nodes)
            {
                var chapterUrl = node.Attributes["href"].Value;
                var storyUrl = chapterUrl.Substring(0, chapterUrl.LastIndexOf("-chap"));

                StoryInfo info = new StoryInfo()
                {
                    Url = storyUrl,
                    Name = node.InnerText.Trim(),
                    Chapters = new List<ChapterInfo>(),
                };

                info.Chapters.Add(new ChapterInfo()
                {
                    Name = node.Attributes["title"].Value.Trim(),
                    Url = chapterUrl
                });
                stories.Add(info);
            }
            return stories;
        }
        public override List<StoryInfo> GetLastestUpdates()
        {
            string lastestUpdateUrl = HostUrl;
            List<StoryInfo> stories = new List<StoryInfo>();
            var html = NetworkHelper.GetHtml(lastestUpdateUrl);

            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(html);
            var nodes = htmlDoc.DocumentNode.SelectNodes("//ul[@class=\"updated_list\"]/li/a[position()=1]");

            foreach (HtmlNode node in nodes)
            {
                StoryInfo info = new StoryInfo()
                {
                    Url = HostUrl + node.Attributes["href"].Value,
                    Name = node.FirstChild.InnerText.Trim(),
                    Chapters = new List<ChapterInfo>(),
                };
                var chapters = node.ParentNode.SelectNodes("a[position()>1]");
                if (chapters != null)
                {
                    foreach (HtmlNode chap in chapters)
                    {
                        info.Chapters.Add(new ChapterInfo()
                        {
                            Name = chap.InnerText.Trim(),
                            Url = HostUrl + "/" + chap.Attributes["href"].Value,
                        });
                    }
                }
                stories.Add(info);
            }
            return stories;
        }
        public override StoryInfo RequestInfo(string storyUrl)
        {
            var html = NetworkHelper.GetHtml(storyUrl);

            HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlDocument();

            htmlDoc.LoadHtml(html);

            var nameNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id=\"mangaproperties\"]/h1");

            StoryInfo info = new StoryInfo()
            {
                Url = storyUrl,
                Name = nameNode.InnerText.Trim(),
            };

            //var match = Regex.Match(html,"<table id=\"listing\"");
            //var index = match.Captures[0].Index;
            //var table = html.Substring(index, html.IndexOf("</table>", index)-index+9);
            //htmlDoc.LoadHtml(table);
            var chapterNodes = htmlDoc.DocumentNode.SelectNodes("//*[@id=\"listing\"]//td//a");

            if (chapterNodes != null)
            {
                foreach (HtmlNode chapter in chapterNodes)
                {
                    ChapterInfo chap = new ChapterInfo()
                    {
                        Name = chapter.InnerText.Trim(),
                        Url = HostUrl + chapter.Attributes["href"].Value,
                        ChapId = ExtractID(chapter.InnerText)
                    };
                    info.Chapters.Add(chap);
                }
                info.Chapters = info.Chapters.OrderBy(p => p.ChapId).ToList();
            }
            return info;
        }