internal static bool RateShow(TraktShowSummary show)
        {
            var rateObject = new TraktSyncShowRated
            {
                Ids = new TraktShowId
                {
                    Trakt = show.Ids.Trakt,
                    Imdb = show.Ids.Imdb.ToNullIfEmpty(),
                    Tmdb = show.Ids.Tmdb,
                    TvRage = show.Ids.TvRage,
                    Tvdb = show.Ids.Tvdb
                },
                Title = show.Title,
                Year = show.Year,
                RatedAt = DateTime.UtcNow.ToISO8601()
            };

            int? prevRating = show.UserRating();
            int newRating = 0;

            newRating = GUIUtils.ShowRateDialog<TraktSyncShowRated>(rateObject);
            if (newRating == -1) return false;

            // If previous rating not equal to current rating then
            // update skin properties to reflect changes
            if (prevRating == newRating)
                return false;

            if (prevRating == null || prevRating == 0)
            {
                // add to ratings
                TraktCache.AddShowToRatings(show, newRating);
                show.Votes++;
            }
            else if (newRating == 0)
            {
                // remove from ratings
                TraktCache.RemoveShowFromRatings(show);
                show.Votes--;
            }
            else
            {
                // rating changed, remove then add
                TraktCache.RemoveShowFromRatings(show);
                TraktCache.AddShowToRatings(show, newRating);
            }

            // update ratings until next online update
            // if we have the ratings distribution we could calculate correctly
            if (show.Votes == 0)
            {
                show.Rating = 0;
            }
            else if (show.Votes == 1 && newRating > 0)
            {
                show.Rating = newRating;
            }

            return true;
        }
        private void RateShow(DBSeries show)
        {
            var rateThread = new Thread((objShow) =>
            {
                if (show[DBOnlineSeries.cTraktIgnore]) return;

                var rateShow = objShow as DBSeries;
                if (rateShow == null) return;

                TraktLogger.Info("Received a Rate Show event from tvseries. Show Title = '{0}', Show Year = '{1}', Show TVDb ID = '{2}'", show[DBOnlineSeries.cOriginalName], show.Year, show[DBSeries.cID]);

                var showRateData = new TraktSyncShowRated
                {
                    Ids = new TraktShowId
                    {
                        Tvdb = show[DBSeries.cID],
                        Imdb = BasicHandler.GetProperImdbId(show[DBOnlineSeries.cIMDBID])
                    },
                    Title = show[DBOnlineSeries.cOriginalName],
                    Year = show.Year.ToNullableInt32(),
                    Rating = show[DBOnlineSeries.cMyRating],
                    RatedAt = DateTime.UtcNow.ToISO8601()
                };

                // update local cache
                TraktCache.AddShowToRatings(showRateData, showRateData.Rating);

                var response = TraktAPI.TraktAPI.AddShowToRatings(showRateData);
                TraktLogger.LogTraktResponse(response);

                if (response != null && response.NotFound != null && response.NotFound.Shows.Count > 0)
                {
                    TraktCache.RemoveShowFromRatings(showRateData);
                }
            })
            {
                IsBackground = true,
                Name = "Rate"
            };

            rateThread.Start(show);
        }
        public static bool ShowTraktExtTVShowMenu(string title, string year, string tvdbid, string imdbid, string fanart, SearchPeople people, bool showAll)
        {
            var dlg = (IDialogbox)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
            dlg.Reset();
            dlg.SetHeading(GUIUtils.PluginName());

            GUIListItem pItem = new GUIListItem(Translation.Comments);
            dlg.Add(pItem);
            pItem.ItemId = (int)TraktMenuItems.Shouts;

            pItem = new GUIListItem(Translation.Rate);
            dlg.Add(pItem);
            pItem.ItemId = (int)TraktMenuItems.Rate;

            pItem = new GUIListItem(Translation.RelatedShows);
            dlg.Add(pItem);
            pItem.ItemId = (int)TraktMenuItems.Related;

            pItem = new GUIListItem(Translation.ShowSeasonInfo);
            dlg.Add(pItem);
            pItem.ItemId = (int)TraktMenuItems.ShowSeasonInfo;

            pItem = new GUIListItem(Translation.AddToWatchList);
            dlg.Add(pItem);
            pItem.ItemId = (int)TraktMenuItems.AddToWatchList;

            pItem = new GUIListItem(Translation.AddToList);
            dlg.Add(pItem);
            pItem.ItemId = (int)TraktMenuItems.AddToCustomList;

            pItem = new GUIListItem(Translation.Cast);
            dlg.Add(pItem);
            pItem.ItemId = (int)TraktMenuItems.Cast;

            pItem = new GUIListItem(Translation.Crew);
            dlg.Add(pItem);
            pItem.ItemId = (int)TraktMenuItems.Crew;

            // Show SearchBy menu...
            if (people != null && people.Count != 0)
            {
                pItem = new GUIListItem(Translation.SearchBy + "...");
                dlg.Add(pItem);
                pItem.ItemId = (int)TraktMenuItems.SearchBy;
            }

            // also show non-context sensitive items related to shows
            if (showAll)
            {
                // might want to check your recently watched, stats etc
                pItem = new GUIListItem(Translation.UserProfile);
                dlg.Add(pItem);
                pItem.ItemId = (int)TraktMenuItems.UserProfile;

                pItem = new GUIListItem(Translation.Network);
                dlg.Add(pItem);
                pItem.ItemId = (int)TraktMenuItems.Network;

                pItem = new GUIListItem(Translation.Calendar);
                dlg.Add(pItem);
                pItem.ItemId = (int)TraktMenuItems.Calendar;

                pItem = new GUIListItem(Translation.Recommendations);
                dlg.Add(pItem);
                pItem.ItemId = (int)TraktMenuItems.Recommendations;

                pItem = new GUIListItem(Translation.Trending);
                dlg.Add(pItem);
                pItem.ItemId = (int)TraktMenuItems.Trending;

                pItem = new GUIListItem(Translation.Popular);
                dlg.Add(pItem);
                pItem.ItemId = (int)TraktMenuItems.Popular;

                pItem = new GUIListItem(Translation.Anticipated);
                dlg.Add(pItem);
                pItem.ItemId = (int)TraktMenuItems.Anticipated;

                pItem = new GUIListItem(Translation.WatchList);
                dlg.Add(pItem);
                pItem.ItemId = (int)TraktMenuItems.WatchList;

                pItem = new GUIListItem(Translation.Lists);
                dlg.Add(pItem);
                pItem.ItemId = (int)TraktMenuItems.Lists;
            }

            // Show Context Menu
            dlg.DoModal(GUIWindowManager.ActiveWindow);
            if (dlg.SelectedId < 0) return false;

            switch (dlg.SelectedId)
            {
                case ((int)TraktMenuItems.Rate):
                    TraktLogger.Info("Displaying rate dialog for tv show. Title = '{0}', Year = '{1}', TVDb ID = '{2}'", title, year.ToLogString(), tvdbid.ToLogString());
                    var show = new TraktSyncShowRated
                    {
                        Ids = new TraktShowId { Tvdb = tvdbid.ToNullableInt32(), Imdb = imdbid.ToNullIfEmpty() },
                        Title = title,
                        Year = year.ToNullableInt32()
                    };
                    int rating = GUIUtils.ShowRateDialog<TraktSyncShowRated>(show);

                    // update local databases
                    if (rating >= 0)
                    {
                        switch (GUIWindowManager.ActiveWindow)
                        {
                            case (int)ExternalPluginWindows.TVSeries:
                                TraktHandlers.TVSeries.SetShowUserRating(rating);
                                break;
                        }

                        if (rating == 0)
                            TraktCache.RemoveShowFromRatings(show);
                        else
                            TraktCache.AddShowToRatings(show, rating);
                    }
                    break;

                case ((int)TraktMenuItems.Shouts):
                    TraktLogger.Info("Displaying Shouts for tv show. Title = '{0}', Year = '{1}', TVDb ID = '{2}', IMDb ID = '{3}'", title, year.ToLogString(), tvdbid.ToLogString(), imdbid.ToLogString());
                    TraktHelper.ShowTVShowShouts(title, year.ToNullableInt32(), tvdbid.ToNullableInt32(), null, imdbid, false, fanart);
                    break;

                case ((int)TraktMenuItems.Related):
                    TraktLogger.Info("Displaying Related shows for tv show. Title = '{0}', Year = '{1}', TVDb ID = '{2}'", title, year.ToLogString(), tvdbid.ToLogString());
                    TraktHelper.ShowRelatedShows(title, year.ToNullableInt32(), tvdbid.ToNullableInt32(), imdbid.ToNullIfEmpty(), null, null);
                    break;

                case ((int)TraktMenuItems.ShowSeasonInfo):
                    TraktLogger.Info("Displaying Season Info for tv show. Title = '{0}', Year = '{1}', TVDb ID = '{2}'", title, year.ToLogString(), tvdbid.ToLogString());
                    var showSummary = new TraktShowSummary
                    {
                        Ids = new TraktShowId
                        {
                            Imdb = imdbid.ToNullIfEmpty(),
                            Tvdb = tvdbid.ToNullableInt32()
                        },
                        Title = title,
                        Year = year.ToNullableInt32()
                    };
                    GUIShowSeasons.Fanart = fanart;
                    GUIWindowManager.ActivateWindow((int)TraktGUIWindows.ShowSeasons, showSummary.ToJSON());
                    break;

                case ((int)TraktMenuItems.AddToWatchList):
                    TraktLogger.Info("Adding tv show to Watchlist. Title = '{0}', Year = '{1}', TVDb ID = '{2}'", title, year.ToLogString(), tvdbid.ToLogString());
                    TraktHelper.AddShowToWatchList(title, year.ToNullableInt32(), tvdbid.ToNullableInt32(), imdbid.ToNullIfEmpty(), null, null);
                    break;

                case ((int)TraktMenuItems.AddToCustomList):
                    TraktLogger.Info("Adding tv show to Custom List. Title = '{0}', Year = '{1}', TVDb ID = '{2}'", title, year.ToLogString(), tvdbid.ToLogString());
                    TraktHelper.AddRemoveShowInUserList(title, year, tvdbid, false);
                    break;

                case ((int)TraktMenuItems.Cast):
                    TraktLogger.Info("Displaying Cast for show. Title = '{0}', Year = '{1}', IMDb ID = '{2}'", title, year.ToLogString(), imdbid.ToLogString());
                    GUICreditsShow.Show = null;
                    GUICreditsShow.Type = GUICreditsShow.CreditType.Cast;
                    GUICreditsShow.Fanart = fanart;
                    GUIWindowManager.ActivateWindow((int)TraktGUIWindows.CreditsShow, imdbid);
                    break;

                case ((int)TraktMenuItems.Crew):
                    TraktLogger.Info("Displaying Crew for show. Title = '{0}', Year = '{1}', IMDb ID = '{2}'", title, year.ToLogString(), imdbid.ToLogString());
                    GUICreditsShow.Show = null;
                    GUICreditsShow.Type = GUICreditsShow.CreditType.Crew;
                    GUICreditsShow.Fanart = fanart;
                    GUIWindowManager.ActivateWindow((int)TraktGUIWindows.CreditsShow, imdbid);
                    break;
                case ((int)TraktMenuItems.SearchBy):
                    ShowSearchByMenu(people, title, fanart);
                    break;

                case ((int)TraktMenuItems.UserProfile):
                    GUIWindowManager.ActivateWindow((int)TraktGUIWindows.UserProfile);
                    break;

                case ((int)TraktMenuItems.Network):
                    GUIWindowManager.ActivateWindow((int)TraktGUIWindows.Network);
                    break;

                case ((int)TraktMenuItems.Calendar):
                    GUIWindowManager.ActivateWindow((int)TraktGUIWindows.Calendar);
                    break;

                case ((int)TraktMenuItems.Recommendations):
                    GUIWindowManager.ActivateWindow((int)TraktGUIWindows.RecommendationsShows);
                    break;

                case ((int)TraktMenuItems.Trending):
                    GUIWindowManager.ActivateWindow((int)TraktGUIWindows.TrendingShows);
                    break;

                case ((int)TraktMenuItems.Popular):
                    GUIWindowManager.ActivateWindow((int)TraktGUIWindows.PopularShows);
                    break;

                case ((int)TraktMenuItems.Anticipated):
                    GUIWindowManager.ActivateWindow((int)TraktGUIWindows.AnticipatedShows);

                    break;
                case ((int)TraktMenuItems.WatchList):
                    GUIWindowManager.ActivateWindow((int)TraktGUIWindows.WatchedListShows);
                    break;

                case ((int)TraktMenuItems.Lists):
                    GUIWindowManager.ActivateWindow((int)TraktGUIWindows.CustomLists);
                    break;
            }
            return true;
        }
        /// <summary>
        /// Rate a single show on trakt.tv
        /// </summary>
        public static TraktSyncResponse AddShowToRatings(TraktSyncShowRated show)
        {
            var shows = new TraktSyncShowsRated
            {
                Shows = new List<TraktSyncShowRated>() { show }
            };

            return AddShowsToRatings(shows);
        }