public CategoryPage()
        {
            InitializeComponent();

            _cf = CategoryConfigA.Config;

            //BusyIndicator.IsRunning = true;

            _isAddPinTap = false;

            _configString = "default";

            GiantDownloadCompleted = 0;
            NumOfDownloadCompleted = 0;
            IsDownloadCompleted = new int[12];
            for (var i = 0; i < 12; i++)
            {
                IsDownloadCompleted[i] = 0;
            }

            feedItems = new ObservableCollection<DataModel.UIContextItem>();
            CategoryChannelsListBox.ItemsSource = feedItems;

            giantCategoryitem = new DataModel.CategoryItem { ChannelItems = new List<DataModel.ChannelItem>() };

            var adsTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
            adsTimer.Tick += (sender, args) =>
            {
                InvokeAppendContent();
                adsTimer.Stop();
            };
            adsTimer.Start();

            GeneralHelper.SetupTutorial(2, Tutorial);

            FileHelper.RemoveFiles("fbd-giant");
        }
        private void SaveHelper(DownloadStringCompletedEventArgs e)
        {
            var u = e.UserState as DataModel.UserToken;
            try
            {

                if (u != null)
                {
                    // Write to the Isolated Storage
                    if (u.DataFetchType != null)
                    {

                        if ((u.DataFetchType).StartsWith("fbd-ctgy-"))
                        {
                            foreach (var item in _tempStorage)
                            {
                                try
                                {
                                    AppendFreshNewsItemToChannelStorage(item);
                                }
                                catch (Exception ex)
                                {
                                    Debug.WriteLine(ex.Message);
                                }
                            }
                        }

                        var categoryItem = new DataModel.CategoryItem
                            {
                                CategoryName = "123",
                                ChannelItems = _feedItemlist
                            };
                        MiscHelpers.SaveDataToIsolatedStorage(u.DataFetchType + ".xml", categoryItem,
                                                              typeof(DataModel.CategoryItem));
                    }

                    //Reset variable
                    _feedItemlist = new List<DataModel.ChannelItem>();

                    //Callback to goto new page once fetching is completed
                    if (u.Callback != null)
                    {
                        (u.Callback).Invoke();
                    }
                }
            }
            catch (Exception ex)
            {
                //Callback to goto new page once fetching is completed
                if (u.Callback != null)
                {
                    (u.Callback).Invoke();
                }
            }
        }
        private void InvokeAppendContent()
        {
            BusyIndicatorA.IsRunning = false;
            BusyIndicatorLayerA.Background = null;

            IDictionary<string, string> q = NavigationContext.QueryString;

            if (q.ContainsKey("storage"))
            {
                _storageName = HttpUtility.UrlEncode(q["storage"]);
            }

            if (q.ContainsKey("channel"))
            {
                _channelName = HttpUtility.UrlEncode(q["channel"]);
            }

            if (q.ContainsKey("category"))
            {
                _categoryName = q["category"];
                HeaderBox.Text = _cf[_categoryName]["title"];
                HeaderIcon.Source =
                    new BitmapImage(new Uri(_cf[_categoryName]["photo_channel"], UriKind.RelativeOrAbsolute));

                defaultPhoto = _cf[_categoryName]["photo_default"];
            }
            else
            {
                HeaderBox.Text = "news";
                HeaderIcon.Source =
                    new BitmapImage(new Uri("ApplicationIcon.png", UriKind.RelativeOrAbsolute));
            }

            if (q.ContainsKey("homegiant"))
            {
                if (_storageName == null)
                {
                    _storageName = "fbd-giant";
                }

                NewsListBox.ItemsSource = _ctgyNewsItems;
                giantCategoryitem = new DataModel.CategoryItem { ChannelItems = new List<DataModel.ChannelItem>() };

                string s = q["homegiant"];
                string[] homeGiantList = s.Split('|');

                _isHomeGiant = s;

                int i = 0;
                foreach (var h in homeGiantList)
                {
                    //string ctgy = h.Replace("fbd-localcache-", "").Replace("fbd-ctgy-", "");
                    //defaultPhoto = _cf[ctgy]["photo_default"];

                    bool isStorageFileExisted = false;

                    string fileName = h;
                    using (IsolatedStorageFile f = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        isStorageFileExisted = f.FileExists(fileName + ".xml");
                    }

                    if (isStorageFileExisted)
                    {
                        BackgroundWorker bw = new BackgroundWorker();
                        bw.WorkerSupportsCancellation = true;
                        bw.WorkerReportsProgress = true;
                        bw.DoWork += delegate
                            {
                                string ctgy = h.Replace("fbd-localcache-", "").Replace("fbd-ctgy-", "");
                                defaultPhoto = _cf[ctgy]["photo_default"];

                                AppendCategoryContent(h);
                            };
                        bw.RunWorkerAsync();
                    }
                    else
                    {
                        var secCount = 0;
                        var adsTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
                        var i1 = i;
                        string h1 = h;
                        adsTimer.Tick += (sender, args) =>
                        {

                            if (IsDownloadCompleted[i1] == 1)
                            {
                                var x = i1;
                                AppendCategoryContent(h1);
                                IsDownloadCompleted[x] = 2;
                            }

                            if (NumOfDownloadCompleted == homeGiantList.Length || secCount >= 40)
                            {
                                //Analytics.GetInstance().TrackLoadingTime("category_data", trackLoadingTime);
                                adsTimer.Stop();
                            }
                            secCount++;
                        };
                        adsTimer.Start();
                    }
                    i++;
                }

                //var addBottomButton = (ApplicationBarIconButton)ApplicationBar.Buttons[1];
                //var readlaterBottomButton = (ApplicationBarIconButton)ApplicationBar.Buttons[2];
                //addBottomButton.IsEnabled = false;
                //readlaterBottomButton.IsEnabled = false;

                _viewType = PinType.Category;

                _isSubscribed = GeneralHelper.SetSubscribeCategoryButton(
                    (ApplicationBarIconButton)ApplicationBar.Buttons[1],
                    _categoryName);
            }

            if (q.ContainsKey("viewtype"))
            {
                string viewType = q["viewtype"];

                if (PinType.Category.ToString().Equals(viewType))
                {
                    _viewType = PinType.Category;

                    _isSubscribed = GeneralHelper.SetSubscribeCategoryButton(
                        (ApplicationBarIconButton)ApplicationBar.Buttons[1],
                        _categoryName);

                    AppendCategoryContent(_storageName);
                }
                else if (PinType.SubCategory.ToString().Equals(viewType))
                {
                    _viewType = PinType.SubCategory;

                    _isSubscribed = GeneralHelper.SetSubscribeSubCategoryButton(
                        (ApplicationBarIconButton)ApplicationBar.Buttons[1],
                        _storageName);

                    AppendCategoryContent(_storageName);
                }
                else if (PinType.Channel.ToString().Equals(viewType))
                {
                    _viewType = PinType.Channel;

                        AppendContent(_storageName);
                }
            }
        }
        private void DownloadFeedContentCompletedCallback(Object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null) return;
            if (string.IsNullOrEmpty(e.Result)) return;

            var root = JsonConvert.DeserializeObject<DataModel.GoogleFeed>(e.Result);

            if (root.ResponseData != null)
            {
                var feedObj = root.ResponseData.Feed;

                var userToken = e.UserState as DataModel.UserToken;

                DataModel.ChannelItem feedItem = MiscHelpers.CreateFeedItem(feedObj, userToken.ChannelId);

                _tempStorage.Add(userToken.ChannelId, feedItem);

                _feedItemlist.Add(feedItem);

            }
            else
            {
                //ToDO: Feed obj not available, provide url instead

                DataModel.ChannelItem feedItem = new DataModel.ChannelItem()
                {
                    FeedAuthor = "123",
                    FeedDescription = "123",
                    FeedTitle = "123",
                    Tag = Guid.NewGuid()
                };
                var userToken = e.UserState as DataModel.UserToken;

                _tempStorage.Add(userToken.ChannelId, feedItem);

                _feedItemlist.Add(feedItem);

            }

            if (_feedItemlist.Count == _googleFeedsResponseDataEntryListSize)
            {

                var u = e.UserState as DataModel.UserToken;

                if (u != null)
                {
                    // Write to the Isolated Storage
                    if (u.DataFetchType != null)
                    {

                        if ((u.DataFetchType).StartsWith("fbd-"))
                        {
                            foreach (var item in _tempStorage)
                            {
                                AppendFreshNewsItemToChannelStorage(item);
                            }
                        }

                        var categoryItem = new DataModel.CategoryItem
                            {
                                CategoryName = "123",
                                ChannelItems = _feedItemlist
                            };
                        MiscHelpers.SaveDataToIsolatedStorage(u.DataFetchType + ".xml", categoryItem, typeof(DataModel.CategoryItem));
                    }

                    //Reset variable
                    _feedItemlist = new List<DataModel.ChannelItem>();

                    //Callback to goto new page once fetching is completed
                    if (u.Callback != null)
                    {
                        (u.Callback).Invoke();
                    }
                }
                else
                {
                    //Web-fetch only: _feedItemlist
                }
            }

            //Call ScheduledAgent's NotifyCompleted()
            //(e.UserState as Action).Invoke();
        }
        private void DownloadFeedsJsonCompletedCallback(Object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null) return;
            if (string.IsNullOrEmpty(e.Result)) return;

            //if (e.UserState == null) return;
            try
            {
                var root = JsonConvert.DeserializeObject<DataModel.GoogleFeeds>(e.Result);

                List<DataModel.GoogleFeedsResponseDataEntry> googleFeedsResponseDataEntryList = root.ResponseData.ResponseData;
                if (googleFeedsResponseDataEntryList != null)
                {
                    var _feedItemlist = new List<DataModel.ChannelItem>();

                    int n = 0;
                    foreach (var entry in googleFeedsResponseDataEntryList)
                    {
                        if (n++ >= 6) break;

                        if (entry.Url != null && !"".Equals(entry.Url))
                        {
                            string title = Regex.Replace(entry.Title, @"<[^>]+>|&nbsp;", "").Trim();
                            string snippet = Regex.Replace(entry.ContentSnippet, @"<[^>]+>|&nbsp;", "").Trim();

                            var channelItem = new DataModel.ChannelItem()
                            {
                                Tag = "feed|" + entry.Link + "|" + entry.Url,

                                FeedUrl = entry.Url,
                                FeedLink = entry.Link,
                                //FeedAuthor = feed.Authors.ToString(),
                                FeedDescription = snippet,
                                FeedTitle = title,

                                NewsItems = null,

                                NewsContent = snippet,
                                //NewsLink = entry.Link,
                                //NewsAuthor = feed.Authors.ToString(),
                                NewsSnippet = snippet,
                                NewsTitle = title,
                                NewsImages = null,

                                ChannelTag = entry.Link
                            };

                            _feedItemlist.Add(channelItem);
                        }
                    }

                    var categoryItem = new DataModel.CategoryItem
                    {
                        ChannelItems = _feedItemlist
                    };
                    var u = e.UserState as DataModel.UserToken;
                    Debug.WriteLine("Prefetch:" + u.DataFetchType);
                    MiscHelpers.SaveDataToIsolatedStorage(u.DataFetchType + ".xml", categoryItem,
                                                          typeof(DataModel.CategoryItem));
                }
            }
            catch (Exception ex)
            {
            }
        }
        private void ToCategoryPage(string mainCat)
        {
            var cfb = CategoryConfigB.Config;
            var subCatsStg = cfb[mainCat]["subcat"];
            var subCats = subCatsStg.Split('|');
            List<Dictionary<string, string>> categoryInfoList = subCats.Select(subCat => cfb[subCat]).ToList();

            //string fileNames = "";

            int countAddGiantDone = 0;
            var giantCategoryitem = new DataModel.CategoryItem { ChannelItems = new List<DataModel.ChannelItem>() };

            Func<string, bool> addGiantHelper = delegate(string fileName)
            {
                countAddGiantDone++;

                var categoryItem = MiscHelpers.GetItemFromIsolatedStorage<DataModel.CategoryItem>(fileName + ".xml");
                if (categoryItem != null && categoryItem.ChannelItems != null &&
                    categoryItem.ChannelItems.Count > 0)
                {
                    foreach (
                        var channelItem in
                            categoryItem.ChannelItems.Where(
                                channelItem => channelItem != null && channelItem.NewsItems != null &&
                                               channelItem.NewsItems.Count > 0))
                    {

                        var channelItem2 = MiscHelpers.CreateChannelItem2(channelItem);
                        channelItem2.NewsItems = new List<DataModel.NewsItem> { channelItem.NewsItems[0] };

                        giantCategoryitem.ChannelItems.Add(channelItem2);
                    }

                    if (countAddGiantDone == categoryInfoList.Count())
                    {
                        MiscHelpers.SaveDataToIsolatedStorage("fbd-giant.xml", giantCategoryitem,
                                                              typeof(DataModel.CategoryItem));

                        NewsListPage.GiantDownloadCompleted++;
                    }
                }
                return true;
            };

            int k = 0;
            foreach (var item in categoryInfoList)
            {
                bool isStorageFileExisted = false;

                string subscribeFileName = "fbd-ctgy-" + item["cachename"];
                using (IsolatedStorageFile f = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    isStorageFileExisted = f.FileExists(subscribeFileName + ".xml");
                }

                if (isStorageFileExisted)
                {

                    //fileNames += subscribeFileName + "|";

                    addGiantHelper(subscribeFileName);
                }
                else
                {
                    string keyword = item["keyword"];
                    string cacheName = "fbd-localcache-" + item["cachename"];
                    //cacheName = "fbd-ctgy-" + item["cachename"];
                    //fileNames += cacheName + "|";

                    var dataFetcher = new DataFeedsFetcher3();
                    int k1 = k;
                    Dispatcher.BeginInvoke(() => dataFetcher.FetchFeeds(keyword, new DataModel.UserToken
                    {
                        DataFetchType = cacheName,
                        Callback = () =>
                        {
                            //NewsListPage.NumOfDownloadCompleted++;
                            //NewsListPage.IsDownloadCompleted[k1]++;

                            addGiantHelper(cacheName);
                        }
                    }));
                }
                k++;
            }

            //fileNames = fileNames.TrimEnd('|');
            //NavigationService.Navigate(new Uri("/NewsListPage.xaml?homegiant=" + fileNames + "&category=" + mainCat, UriKind.Relative));

            NavigationService.Navigate(new Uri("/NewsListPage.xaml?storage=fbd-giant&category=" + mainCat + "&viewtype=" + PinType.Category, UriKind.Relative));
        }
        private void InvokeAppendContent()
        {
            BusyIndicatorA.IsRunning = false;
            BusyIndicatorLayerA.Background = null;

            DateTime trackLoadingTime = DateTime.Now;

            IDictionary<string, string> q = NavigationContext.QueryString;

            if (q.ContainsKey("cachenames"))
            {
                string cacheNamesStg = q["cachenames"];

                string[] cacheNames = cacheNamesStg.Split('|');

                _numOfCategory = cacheNames.Length;

                if (cacheNames != null && _numOfCategory > 0)
                {
                    string ctg = NavigationContext.QueryString["maincat"];
                    _configString = _cf[ctg]["cachename"];

                    HeaderBox.Text = _cf[ctg]["title"];
                    HeaderIcon.Source = new BitmapImage(new Uri(_cf[ctg]["photo_channel"], UriKind.RelativeOrAbsolute));

                    UIElementCollection uic = ContentPanel.Children;

                    int uicCount = uic.Count;
                    int size = (uicCount <= _numOfCategory) ? uicCount : _numOfCategory;

                    GiantDownloadCompleted = 0;
                    NumOfDownloadCompleted = 0;
                    IsDownloadCompleted = new int[size];
                    bool isGiantListReset = false;
                    for (var i = 0; i < size; i++)
                    {

                        IsDownloadCompleted[i] = 0;

                        var busyIndicator = uic[i + 10] as RadBusyIndicator;
                        if (busyIndicator != null)
                        {
                            busyIndicator.Visibility = Visibility.Visible;
                            busyIndicator.IsRunning = true;
                        }

                        uic[i + 1].Visibility = Visibility.Visible;

                        bool isStorageFileExisted = false;

                        string fileName = cacheNames[i];
                        using (IsolatedStorageFile f = IsolatedStorageFile.GetUserStoreForApplication())
                        {
                            isStorageFileExisted = f.FileExists(fileName + ".xml");
                        }

                        if (isStorageFileExisted)
                        {
                            AppendContent2(fileName, uic[i + 1], PinType.SubCategory, busyIndicator);
                        }
                        else
                        {
                            //Append prefetch context to UI
                            string prefetchFilename = "fbd-prefetch-" + fileName.Replace("fbd-localcache-", "").Replace("fbd-ctgy-", "");
                            AppendContent2(prefetchFilename, uic[i + 1], PinType.SubCategory, busyIndicator);

                            if (busyIndicator != null)
                            {
                                busyIndicator.Visibility = Visibility.Visible;
                                busyIndicator.IsRunning = true;
                            }

                            var secCount = 0;
                            var adsTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
                            var i1 = i;

                            adsTimer.Tick += (sender, args) =>
                            {
                                var x = i1;
                                if (IsDownloadCompleted[x] >= 1 && IsDownloadCompleted[x] < 100)
                                {
                                    if (!isGiantListReset)
                                    {
                                        isGiantListReset = true;
                                        //feedItems = new ObservableCollection<DataModel.UIContextItem>();
                                        //CategoryChannelsListBox.ItemsSource = feedItems;
                                        giantCategoryitem = new DataModel.CategoryItem { ChannelItems = new List<DataModel.ChannelItem>() };
                                    }
                                    IsDownloadCompleted[x] = 100;
                                    AppendContent2(cacheNames[x], uic[x + 1], PinType.SubCategory, busyIndicator);
                                    Analytics.GetInstance().TrackLoadingTime("category_loadedSubCat", trackLoadingTime);
                                }

                                if (NumOfDownloadCompleted == size || secCount >= 40)
                                {
                                    InitializeAdUnits();
                                    Analytics.GetInstance().TrackLoadingTime("category_loadedAllSubCat", trackLoadingTime);
                                    adsTimer.Stop();
                                }
                                secCount++;
                            };
                            adsTimer.Start();
                        }
                    }
                }
            }
        }