public static void SyncNewEpisodes(ProgressDialog.ProgressDelegate progress)
        {
            // grab list of all local episodes
            SQLCondition condition = new SQLCondition();
            condition.Add(new DBOnlineEpisode(), DBOnlineEpisode.cFollwitId, 0, SQLConditionType.Equal);
            List<DBEpisode> episodes = DBEpisode.Get(condition, false);

            SyncEpisodes(episodes, progress);
        }
        public static void SyncAllEpisodes(ProgressDialog.ProgressDelegate progress)
        {
            // grab list of all local episodes
            SQLCondition condition = new SQLCondition();
            condition.Add(new DBOnlineEpisode(), DBOnlineEpisode.cSeriesID, 0, SQLConditionType.GreaterThan);
            List<DBEpisode> episodes = DBEpisode.Get(condition, false);

            SyncEpisodes(episodes, progress);
        }
        public static void SyncEpisodes(List<DBEpisode> episodes, ProgressDialog.ProgressDelegate progress)
        {
            if (!Enabled || episodes == null) return;

            Thread thread = new Thread(new ThreadStart(delegate {
                try {
                    MPTVSeriesLog.Write("[follw.it] Beginning synchronization of {0} episodes.", episodes.Count);
                    DateTime start = DateTime.Now;

                    // basic data structures used for our processing loop
                    Dictionary<string, DBEpisode> episodeLookup = new Dictionary<string, DBEpisode>();
                    List<FitEpisode> epsToSend = new List<FitEpisode>();
                    List<FitEpisode> totalOutput = new List<FitEpisode>();

                    int sent = 0;
                    int total = episodes.Count;
                    bool canceled = false;

                    // send episodes to server in small groups at a time.
                    foreach (DBEpisode currEpisode in episodes) {
                        if (!currEpisode.IsAvailableLocally) {
                            total--;
                            continue;
                        }

                        // build follwit episode object. clear watched flag if unwatched
                        // to preserve a possible positive watched status on the server
                        FitEpisode fitEpisode = GetFitEpisode(currEpisode);
                        episodeLookup[fitEpisode.SourceId] = currEpisode;
                        if (fitEpisode.Watched == false) fitEpisode.Watched = null;

                        epsToSend.Add(fitEpisode);

                        if (epsToSend.Count > 30) {
                            totalOutput.AddRange(FollwitConnector.FollwitApi.BulkAction(epsToSend));
                            sent += epsToSend.Count;
                            epsToSend.Clear();

                            // send progress update to any listeners
                            try { if (progress != null) canceled = progress(ProgressDialog.Status.RUNNING, (sent * 100) / total); }
                            catch (Exception) { }

                            // if the listener sent a cancel message, we are done
                            if (canceled) break;
                        }
                    }

                    // send remaining group of episodes
                    totalOutput.AddRange(FollwitConnector.FollwitApi.BulkAction(epsToSend));
                    sent += epsToSend.Count;

                    // locally store returned data (currently only follwit id)
                    foreach (FitEpisode fitEp in totalOutput) {
                        DBEpisode ep = episodeLookup[fitEp.SourceId];
                        ep[DBOnlineEpisode.cFollwitId] = fitEp.FollwitId;
                        ep[DBOnlineEpisode.cWatched] = fitEp.Watched;
                        if (fitEp.Rating != 0) ep[DBOnlineEpisode.cMyRating] = fitEp.Rating * 2;
                        ep.Commit();
                    }

                    // send final progress update to listeners
                    if (canceled) {
                        try { if (progress != null) progress(ProgressDialog.Status.CANCELED, (sent * 100) / total); }
                        catch (Exception) { }

                        MPTVSeriesLog.Write("[follw.it] Synchronized {0}/{1} episodes. Canceled by user. ({2}).",
                                            sent, total, DateTime.Now - start);
                    }
                    else {
                        try { if (progress != null) progress(ProgressDialog.Status.DONE, (sent * 100) / total); }
                        catch (Exception) { }

                        MPTVSeriesLog.Write("[follw.it] Synchronized {0} episodes. ({1})", sent, DateTime.Now - start);

                    }
                }
                catch (Exception e) {
                    try { if (progress != null) progress(ProgressDialog.Status.CANCELED, 0); }
                    catch (Exception) { }
                    MPTVSeriesLog.Write("[follw.it] Failed episode synchronization: {0}", e.Message);
                }
            }));

            thread.IsBackground = true;
            thread.Name = "follw.it syncer";
            thread.Start();
        }
 private void Sync()
 {
     ProgressDialog popup = new ProgressDialog();
     popup.Text = "Synchronizing Collection...";
     popup.Owner = FindForm();
     FollwitConnector.SyncAllEpisodes(popup.SetProgress);
     popup.ShowDialog();
 }