/// <summary>
 /// Calls the specified delegate recursively for each outline element
 /// </summary>
 /// <param name="collection">Collection with outline items</param>
 /// <param name="callback">Delegate to call for each item</param>
 private void RecursiveWorker(OpmlOutlineCollection collection, OutlineCallbackDelegate callback)
 {
     //
     for (int i = 0; i < collection.Count; i++)
     //foreach(OpmlOutlineFavorite o in collection)
     {
         OpmlOutlineFavorite o = (OpmlOutlineFavorite)collection[i];
         //
         if (o.Items.Count > 0)
         {
             RecursiveWorker(o.Items, callback);
         }
         else
         {
             try
             {
                 callback(o);
             }
             catch (System.Exception e)
             {
                 _exceptionTable.Add(o, e);
             }
         }
     }
 }
        /// <summary>
        /// Updates the history with the specified item
        /// </summary>
        /// <param name="item"></param>
        private void UpdateHistory(OpmlOutlineFavorite item)
        {
            if (item.State != CacheState.Cached)
            {
                return;
            }
            //
            if (FindOutline(item, _historyDocument.Body.Items))
            {
                return;
            }
            //
            OpmlOutlineFavorite historyDayItem = null;

            foreach (OpmlOutlineFavorite historyItem in _historyDocument.Body.Items)
            {
                TimeSpan span = historyItem.LastVisited.Subtract(item.LastVisited);
                if (span.Days == 0)
                {
                    historyDayItem = historyItem;
                    break;
                }
            }
            // create on demand
            if (historyDayItem == null)
            {
                historyDayItem             = new OpmlOutlineFavorite();
                historyDayItem.LastVisited = item.LastVisited;
                historyDayItem.Text        = item.LastVisited.ToString("dddd");
                //
                _historyDocument.Body.Items.Add(historyDayItem);
            }
            // add new item
            historyDayItem.Items.Add(item);
        }
 /// <summary>
 /// Reset the favorite to it's default values.
 /// </summary>
 /// <param name="item"></param>
 private void ResetOutline(OpmlOutlineFavorite item)
 {
     System.IO.File.Delete(GetCachePathFromUri(new Uri(item.XmlUrl)));
     item.State        = CacheState.None;
     item.TimesVisited = 0;
     item.LastVisited  = DateTime.MinValue;
 }
 private void RefreshOutline(OpmlOutlineFavorite item)
 {
     if (item.State == CacheState.Cached)
     {
         return;
     }
     //
     this.GetFeed(item);
 }
 /// <summary>
 /// Find the outline item that holds the requested uri.
 /// </summary>
 /// <param name="uri">The URI of the outline item to find.</param>
 /// <param name="collection">RootCollection to search in.</param>
 /// <returns></returns>
 private OpmlOutlineFavorite FindOutlineByUri(Uri uri, System.Collections.ICollection collection)
 {
     foreach (OpmlOutlineFavorite o in collection)
     {
         if (object.Equals(o.XmlUrl, uri.AbsoluteUri))
         {
             return(o);
         }
         // recursive call
         OpmlOutlineFavorite outline = FindOutlineByUri(uri, o.Items);
         if (outline != null)
         {
             return(outline);
         }
     }
     return(null);
 }
 /// <summary>
 /// Recursive contains over the specified collection to find the outline item.
 /// </summary>
 /// <param name="uri">The URI of the outline item to find.</param>
 /// <param name="collection">RootCollection to search in.</param>
 /// <returns>True if the collection's hold this instance, otherwise False if not found.</returns>
 private bool FindOutline(OpmlOutlineFavorite item, OpmlOutlineCollection collection)
 {
     if (collection.Contains(item))
     {
         return(true);
     }
     //
     foreach (OpmlOutlineFavorite o in collection)
     {
         // recursive call
         if (FindOutline(item, o.Items))
         {
             return(true);
         }
     }
     return(false);
 }
        /// <summary>
        /// RssFeedManager implements the operations to create <see cref="RssChannel"/> objects.
        /// This class is responsible to manage the cache and is build to work with <see cref="OpmlOutlineFavorite"/> outline.
        /// </summary>
        /// <param name="outline">The <see cref="OpmlOutlineFavorite"/> of the resource to receive the data.</param>
        /// <returns>The requested see cref="IRssChannel" instance</returns>
        public IRssChannel GetFeed(OpmlOutlineFavorite outline)
        {
            Uri         uri        = new Uri(outline.XmlUrl);
            IRssChannel rssChannel = null;

            //System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
            try
            {
                // never fetched before
                if (outline.ExpireDate == DateTime.MinValue || outline.ExpireDate < DateTime.Now)
                {
                    // fetch channel from web
                    rssChannel = InternalGetFeed(uri);
                    // save channel to cache
                    rssChannel.Save(GetCachePathFromUri(uri));
                    //
                    if (rssChannel.Ttl > 0)
                    {
                        outline.ExpireDate = DateTime.Now.AddMinutes(rssChannel.Ttl);
                    }
                    else
                    {
                        outline.ExpireDate = DateTime.Now.AddMinutes(3600);
                    }
                    //
                    outline.State = CacheState.Cached;
                    //
                    // add/refresh loaded channel to internal non persistent cache list
                    _rssChannelCacheList[outline] = rssChannel;
                }
                // check cache
                else
                {
                    // cached and not out of date
                    if (_rssChannelCacheList.Contains(outline))
                    {
                        rssChannel = _rssChannelCacheList[outline] as IRssChannel;
                    }
                    // cached but out of date, refresh
                    else
                    {
                        // fetch channel from web
                        rssChannel    = InternalGetFeed(new Uri(GetCachePathFromUri(uri)));
                        outline.State = CacheState.Cached;
                        // update cache list
                        _rssChannelCacheList[outline] = rssChannel;
                    }
                }
            }
            catch (System.Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.Message);
                outline.State = CacheState.Error;
                throw e;
            }
            finally
            {
                //System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;
            }
            //
            outline.TimesVisited++;
            outline.LastVisited = DateTime.Now;
            UpdateHistory(outline);
            //
            return(rssChannel);
        }