/// <summary>
        /// Fired when an object is updated in the Moving Pictures Database
        /// </summary>
        /// <param name="obj"></param>
        private void DatabaseManager_ObjectUpdatedEx(DatabaseTable dbObject, TableUpdateInfo ui)
        {
            if (TraktSettings.AccountStatus != ConnectionState.Connected) return;

            //If it is user settings for a movie
            if (dbObject.GetType() == typeof(DBUserMovieSettings))
            {
                DBUserMovieSettings userMovieSettings = (DBUserMovieSettings)dbObject;
                DBMovieInfo movie = userMovieSettings.AttachedMovies[0];

                // don't do anything if movie is blocked
                if (TraktSettings.BlockedFilenames.Contains(movie.LocalMedia[0].FullPath) || TraktSettings.BlockedFolders.Any(f => movie.LocalMedia[0].FullPath.ToLowerInvariant().Contains(f.ToLowerInvariant())))
                {
                    TraktLogger.Info("Movie {0} is on the blocked list so we didn't update Trakt", movie.Title);
                    return;
                }

                // if we are syncing, we maybe manually setting state from trakt
                // in this case we dont want to resend to trakt
                if (SyncInProgress) return;

                // we check the watched flag and update Trakt respectfully
                // ignore if movie is the current movie being scrobbled, this will be set to watched automatically
                if (ui.WatchedCountChanged() && movie != currentMovie)
                {
                    if (userMovieSettings.WatchedCount == 0)
                    {
                        TraktLogger.Info("Received Un-Watched event in MovingPictures for movie '{0}'", movie.Title);
                        SyncMovie(CreateSyncData(movie), TraktSyncModes.unseen);
                    }
                    else
                    {
                        TraktLogger.Info("Received Watched event in MovingPictures for movie '{0}'", movie.Title);
                        if (!g_Player.IsVideo)
                        {
                            SyncMovie(CreateSyncData(movie), TraktSyncModes.seen);
                            RemoveMovieFromFiltersAndCategories(movie);
                        }
                    }
                }

                // we will update the Trakt rating of the Movie
                // ignore if we rated using trakt rate dialog
                if (ui.RatingChanged() && userMovieSettings.UserRating > 0 && !TraktRateSent)
                {
                    TraktLogger.Info("Received Rate event in MovingPictures for movie '{0}' with rating '{1}/5'", movie.Title, userMovieSettings.UserRating);
                    RateMovie(CreateRateData(movie, (userMovieSettings.UserRating * 2).ToString()));
                }
            }
        }
        private void DatabaseManager_ObjectUpdated(DatabaseTable obj, TableUpdateInfo updateInfo)
        {
            if (!MovingPicturesCore.Settings.FollwitEnabled) {
                logger.Warn("Attempt to call follw.it made when service is disabled.");
                return;
            }

            try {
                // we're looking for user rating changes
                if (obj.GetType() != typeof(DBUserMovieSettings))
                    return;

                DBUserMovieSettings settings = (DBUserMovieSettings)obj;
                if (updateInfo.RatingChanged()) {
                    if (!IsOnline) {
                        logger.Warn("Can not send rating info to follw.it because service is offline");
                        return;
                    }

                    DBMovieInfo movie = settings.AttachedMovies[0];

                    if (currentlySyncingMovies.Contains(movie))
                        return;

                    FollwitBackgroundProcess bgProc = new FollwitBackgroundProcess();
                    bgProc.Action = FitActions.UpdateUserRating;
                    bgProc.Movies.Add(movie);
                    MovingPicturesCore.ProcessManager.StartProcess(bgProc);
                }

            }
            catch (Exception ex) {
                logger.ErrorException("Unexpected error sending rating information to follw.it!", ex);
                _follwitAPI = null;
                MovingPicturesCore.Follwit.Status = FollwitConnector.StatusEnum.INTERNAL_ERROR;
            }
        }
        /// <summary>
        /// Fired when an object is updated in the Moving Pictures Database
        /// </summary>
        /// <param name="obj"></param>
        private void DatabaseManager_ObjectUpdatedEx(DatabaseTable dbObject, TableUpdateInfo ui)
        {
            // check connection state
            if (TraktSettings.AccountStatus != ConnectionState.Connected)
                return;

            // If it is user settings for a movie
            if (dbObject.GetType() != typeof(DBUserMovieSettings))
                return;

            // if we are syncing, we maybe manually setting state from trakt
            // in this case we dont want to resend to trakt
            if (SyncLibraryInProgress) return;

            DBUserMovieSettings userMovieSettings = (DBUserMovieSettings)dbObject;
            DBMovieInfo movie = userMovieSettings.AttachedMovies[0];

            // don't do anything if movie is blocked
            if (TraktSettings.BlockedFilenames.Contains(movie.LocalMedia[0].FullPath) || TraktSettings.BlockedFolders.Any(f => movie.LocalMedia[0].FullPath.ToLowerInvariant().Contains(f.ToLowerInvariant())))
            {
                TraktLogger.Info("Movie is on the blocked list so we didn't update trakt.tv. Title = '{0}', Year = '{1}', IMDB ID = '{2}', TMDb ID = '{3}'", movie.Title, movie.Year, movie.ImdbID ?? "<empty>", GetTmdbID(movie) ?? "<empty>");
                return;
            }

            // we check the watched flag and update Trakt respectfully
            // ignore if movie is the current movie being scrobbled, this will be set to watched automatically
            if (ui.WatchedCountChanged() && movie != currentMovie)
            {
                if (userMovieSettings.WatchedCount == 0)
                {
                    #region Unwatched Event
                    TraktLogger.Info("Received Un-Watched event in MovingPictures for movie. Title = '{0}', Year = '{1}', IMDB ID = '{2}', TMDb ID = '{3}'", movie.Title, movie.Year, movie.ImdbID ?? "<empty>", GetTmdbID(movie) ?? "<empty>");

                    var syncThread = new Thread((objMovie) =>
                    {
                        var tMovie = objMovie as DBMovieInfo;

                        var traktMovie = new TraktMovie
                        {
                            Ids = new TraktMovieId { Imdb = tMovie.ImdbID, Tmdb = GetTmdbID(tMovie).ToNullableInt32() },
                            Title = tMovie.Title,
                            Year = tMovie.Year
                        };

                        // update local cache
                        TraktCache.RemoveMovieFromWatchHistory(traktMovie);

                        var response = TraktAPI.TraktAPI.RemoveMovieFromWatchedHistory(traktMovie);
                        TraktLogger.LogTraktResponse(response);
                    })
                    {
                        IsBackground = true,
                        Name = "Sync"
                    };

                    syncThread.Start(movie);
                    #endregion
                }
                else
                {
                    #region Watched Event
                    TraktLogger.Info("Received Watched event in MovingPictures for movie. Title = '{0}', Year = '{1}', IMDB ID = '{2}', TMDb ID = '{3}'", movie.Title, movie.Year, movie.ImdbID ?? "<empty>", GetTmdbID(movie) ?? "<empty>");
                    if (!g_Player.IsVideo)
                    {
                        var syncThread = new Thread((objMovie) =>
                        {
                            var tMovie = objMovie as DBMovieInfo;

                            var traktMovie = new TraktSyncMovieWatched
                            {
                                Ids = new TraktMovieId { Imdb = tMovie.ImdbID, Tmdb = GetTmdbID(tMovie).ToNullableInt32() },
                                Title = tMovie.Title,
                                Year = tMovie.Year,
                                WatchedAt = DateTime.UtcNow.ToISO8601()
                            };

                            var response = TraktAPI.TraktAPI.AddMovieToWatchedHistory(traktMovie);
                            TraktLogger.LogTraktResponse(response);

                            if (response != null && response.NotFound != null && response.NotFound.Movies.Count == 0)
                            {
                                // update internal cache
                                TraktCache.AddMovieToWatchHistory(traktMovie);
                            }

                            // don't need to keep this movie anymore in categories/filter menu if it's watched
                            RemoveMovieCriteriaFromRecommendationsNode(tMovie.ImdbID);
                            RemoveMovieCriteriaFromWatchlistNode(tMovie.ImdbID);
                        })
                        {
                            IsBackground = true,
                            Name = "Sync"
                        };

                        syncThread.Start(movie);
                    }
                    #endregion
                }
            }

            // we will update the Trakt rating of the Movie
            // ignore if we rated using trakt rate dialog
            if (ui.RatingChanged() && userMovieSettings.UserRating > 0 && !TraktRateSent)
            {
                TraktLogger.Info("Received Rate event in MovingPictures for movie. Rating = '{0}/5', Title = '{1}', Year = '{2}', IMDB ID = '{3}', TMDb ID = '{4}'", userMovieSettings.UserRating, movie.Title, movie.Year, movie.ImdbID ?? "<empty>", GetTmdbID(movie) ?? "<empty>");

                var syncThread = new Thread((objMovie) =>
                {
                    var tMovie = objMovie as DBMovieInfo;

                    var traktMovie = new TraktSyncMovieRated
                    {
                        Ids = new TraktMovieId { Imdb = tMovie.ImdbID, Tmdb = GetTmdbID(tMovie).ToNullableInt32() },
                        Title = tMovie.Title,
                        Year = tMovie.Year,
                        RatedAt = DateTime.UtcNow.ToISO8601(),
                        Rating = (int)userMovieSettings.UserRating * 2
                    };

                    var response = TraktAPI.TraktAPI.AddMovieToRatings(traktMovie);
                    TraktLogger.LogTraktResponse(response);
                })
                {
                    IsBackground = true,
                    Name = "Sync"
                };
                syncThread.Start(movie);
            }
        }