private void OnGetApiKeyRPCCompleted(object sender, XMLRPCCompletedEventArgs <Blog> args)
        {
            //the blog is updated by the rpc.  all we have to do here is unbind
            GetApiKeyRPC rpc = sender as GetApiKeyRPC;

            rpc.Completed -= OnGetApiKeyRPCCompleted;

            //check for empty args.Items, self-hosted blogs will return null here
            Blog newBlog;

            if (args.Items.Count == 0)
            {
                newBlog = rpc.blog;
            }
            else
            {
                newBlog = args.Items[0];
            }
            _trackedBlogs.Add(newBlog);

            this.DebugLog("Blog '" + newBlog.BlogName + "' is now downloading data.");

            //start with the comments
            GetAllCommentsRPC getCommentsRPC = new GetAllCommentsRPC(newBlog);

            getCommentsRPC.Number           = CHUNK_SIZE;
            getCommentsRPC.Offset           = 0;
            getCommentsRPC.Completed       += OnGetNewBlogCommentsCompleted;
            getCommentsRPC.ProgressChanged += OnGetCommentsRPCProgressChanged;

            getCommentsRPC.ExecuteAsync();
        }
        private void OnGetCommentsRPCProgressChanged(object sender, ProgressChangedEventArgs args)
        {
            GetAllCommentsRPC rpc = sender as GetAllCommentsRPC;
            Blog newBlog          = _trackedBlogs.Where(blog => blog.BlogId == rpc.BlogId).FirstOrDefault();

            if (null != newBlog)
            {
                this.DebugLog("OnGetCommentsRPCProgressChanged-- Blog: " + newBlog.BlogName);
            }
            this.DebugLog("GetCommentsProgressChanged-- Progress: " + args.ProgressPercentage.ToString());
            this.DebugLog("GetCommentsProgressChanged-- UserState: " + args.UserState);
        }
        public bool FetchCurrentBlogCommentsAsync(bool more)
        {
            if (null == CurrentBlog)
            {
                throw new ArgumentException("CurrentBlog may not be null", "CurrentBlog");
            }

            //we're already downloading data here--don't allow scenarios where we could be
            //kicking off another download
            if (_trackedBlogs.Contains(CurrentBlog))
            {
                return(false);
            }

            CurrentBlog.showLoadingIndicator();

            int numerberOfComments = 0;

            if (more)
            {
                numerberOfComments = Math.Max(CurrentBlog.Comments.Count, CHUNK_SIZE);
                if (CurrentBlog.HasOlderComments)
                {
                    numerberOfComments += CHUNK_SIZE;
                }
                else
                {
                    //removing this block you will enable the refresh of comments when reached the end of the list and no more comments are available
                    CurrentBlog.hideLoadingIndicator();
                    return(false);
                }
            }
            else
            {
                numerberOfComments = CHUNK_SIZE;
            }

            CurrentBlog.IsLoadingComments = true;
            GetAllCommentsRPC rpc = new GetAllCommentsRPC(CurrentBlog);

            rpc.Number     = numerberOfComments;
            rpc.Offset     = 0;
            rpc.Completed += OnFetchCurrentBlogCommentsCompleted;

            rpc.ExecuteAsync();
            return(true);
        }
        private void OnGetNewBlogCommentsCompleted(object sender, XMLRPCCompletedEventArgs <Comment> args)
        {
            GetAllCommentsRPC rpc = sender as GetAllCommentsRPC;

            rpc.Completed       -= OnGetNewBlogCommentsCompleted;
            rpc.ProgressChanged -= OnGetCommentsRPCProgressChanged;

            Blog newBlog = _trackedBlogs.Where(blog => blog.BlogId == rpc.BlogId).FirstOrDefault();

            if (null == newBlog)
            {
                return;
            }

            //report the error, but keep trying to get data
            if (null != args.Error)
            {
                this.DebugLog("OnFetchNewBlogCommentsCompleted: Exception occurred (" + newBlog.BlogName + ")");
                this.DebugLog(args.Error.ToString());
                NotifyExceptionOccurred(new ExceptionEventArgs(args.Error));
            }
            else
            {
                foreach (Comment comment in args.Items)
                {
                    newBlog.Comments.Add(comment);
                }
                this.DebugLog("Blog '" + newBlog.BlogName + "' has finished downloading comments.");
            }

            this.DebugLog("Blog '" + newBlog.BlogName + "' has finished downloading comments.");

            if (newBlog == CurrentBlog)
            {
                NotifyFetchComplete();
            }

            //get the posts for the new blog
            GetRecentPostsRPC recentPostsRPC = new GetRecentPostsRPC(newBlog);

            recentPostsRPC.NumberOfPosts    = CHUNK_SIZE;
            recentPostsRPC.Completed       += OnGetNewBlogRecentPostsCompleted;
            recentPostsRPC.ProgressChanged += OnGetNewBlogRecentPostsRPCProgressChanged;
            recentPostsRPC.ExecuteAsync();
        }
        private void OnFetchCurrentBlogCommentsCompleted(object sender, XMLRPCCompletedEventArgs <Comment> args)
        {
            GetAllCommentsRPC rpc = sender as GetAllCommentsRPC;

            rpc.Completed -= OnFetchCurrentBlogCommentsCompleted;
            CurrentBlog.IsLoadingComments = false;

            if (null == args.Error)
            {
                int prevCommentsCount = CurrentBlog.Comments.Count;
                CurrentBlog.Comments.Clear();

                // If we asked for more and we got what we had, there are no more posts to load
                if (rpc.Number > CHUNK_SIZE && (args.Items.Count <= prevCommentsCount))
                {
                    CurrentBlog.HasOlderComments = false;
                }
                else if (rpc.Number == CHUNK_SIZE)
                {
                    //we should reset the flag otherwise when you refresh this blog you can't get more than CHUNK_SIZE comments
                    CurrentBlog.HasOlderComments = true;
                }

                foreach (Comment comment in args.Items)
                {
                    CurrentBlog.Comments.Add(comment);
                }
                NotifyFetchComplete();
            }
            else
            {
                NotifyExceptionOccurred(new ExceptionEventArgs(args.Error));
            }

            CurrentBlog.hideLoadingIndicator();
        }