public void importChallonge(String apiKey, String subDomain, List<Person> playerList)
        {
            if (subDomain != null && subDomain.Length > 0)
                portal = new ChallongePortal(apiKey, subDomain);
            else
                portal = new ChallongePortal(apiKey);

            //Fetch all tournaments that have been completed ahead of time and save into local variable
            //completedTournaments = portal.GetTournaments().Where(t => t.CompletedAt.HasValue).ToList();
            completedTournaments = portal.GetTournaments().ToList();

            //Fetch name of first tournament in list or leave blank if no tournaments
            tournamentName = completedTournaments.Select(t => t.Name).FirstOrDefault();

            //Load current players in leaderboard
            foreach (Person p in playerList)
            {
                currentPlayers.Add(p);
                playerNames.Add(p.Name);
            }
            playerNames.Sort();

            //Set event selector
            eventSelector.DataSource = completedTournaments;
            eventSelector.DisplayMember = "Name";
        }
        public TournamentContext(ChallongePortal portal, int tournamentId)
        {
            Portal = portal;
            this.tournamentId = tournamentId;

            var queryResults = queryData();
            if (queryResults != null)
            {
                Tournament = new ObservableTournament(queryResults.Item1, this);
                Tournament.Initialize(queryResults.Item2, queryResults.Item3);
            }
        }
        public void importChallonge(String apiKey, String subDomain, String specifiedTournamentName, List<Person> playerList)
        {
            if (subDomain != null && subDomain.Length > 0)
                portal = new ChallongePortal(apiKey, subDomain);
            else
                portal = new ChallongePortal(apiKey);

            //Fetch all tournaments for the user account or subdomain
            tournaments = portal.GetTournaments().ToList();

            //If a specific tournament name is provided, look it up individually. 
            if (!string.IsNullOrWhiteSpace(specifiedTournamentName))
            {
                specifiedTournament = portal.ShowTournament(specifiedTournamentName);
                
                //Only add it to the list if it's not there from the user account/subdomain.
                if (!tournaments.Contains(specifiedTournament))
                {
                    tournaments.Insert(0, specifiedTournament);
                }
            }

            //Fetch name of first tournament in list or leave blank if no tournaments
            tournamentName = tournaments.Select(t => t.Name).FirstOrDefault();

            //Load current players in leaderboard
            foreach (Person p in playerList)
            {
                currentPlayers.Add(p);
                playerNames.Add(p.Name);
            }
            playerNames.Sort();

            //Set event selector
            eventSelector.DataSource = tournaments;
            eventSelector.DisplayMember = "Name";
        }
        public MainViewModel()
        {
            CurrentScreen = ScreenType.ApiKey;

            //Observable.Start(() =>
            //{
            //    try
            //    {
            //        //I'm considering doing an http request to smashboards to find if a new version is released. I think smashboard's anti-DDOS protection is preventing it from working
            //        WebRequest request = WebRequest.Create(ThreadUrl);
            //        request.Credentials = CredentialCache.DefaultCredentials;

            //        WebResponse response = request.GetResponse();
            //        if (((HttpWebResponse)response).StatusDescription == "OK")
            //        {
            //            Stream dataStream = response.GetResponseStream();
            //            StreamReader reader = new StreamReader(dataStream);
            //            string responseFromServer = reader.ReadToEnd();
            //            reader.Close();
            //        }
            //        response.Close();
            //    }
            //    catch { /* ignore */ }
            //});

            //Modify ViewModel state when an action is initiated
            Action startAction = () =>
            {
                ErrorMessage = null;
                IsBusy = true;
            };

            //Modify ViewModel state when an action is completed
            Action endAction = () =>
            {
                IsBusy = false;
            };

            //Modify ViewModel state when an action comes back with an exception
            Action<Exception> errorHandler = ex =>
            {
                if (ex.InnerException is ChallongeApiException)
                {
                    var cApiEx = (ChallongeApiException)ex.InnerException;

                    if (cApiEx.Errors != null) ErrorMessage = cApiEx.Errors.Aggregate((one, two) => one + "\r\n" + two);
                    else ErrorMessage = string.Format("Error with ResponseStatus \"{0}\" and StatusCode \"{1}\". {2}", cApiEx.RestResponse.ResponseStatus,
                        cApiEx.RestResponse.StatusCode, cApiEx.RestResponse.ErrorMessage);
                }
                else
                {
                    ErrorMessage = ex.NewLineDelimitedMessages();
                }

                IsBusy = false;
            };

            var dispatcher = System.Threading.SynchronizationContext.Current;

            //Handle next button press
            NextCommand = Command.CreateAsync(() => true, () =>
            {
                switch (CurrentScreen)
                {
                    case ScreenType.ApiKey:
                        var subdomain = string.IsNullOrWhiteSpace(Subdomain) ? null : Subdomain;
                        Portal = new ChallongePortal(ApiKey, subdomain);

                        //Load list of tournaments that match apikey/subdomain
                        TournamentCollection = Portal.GetTournaments().OrderByDescending(t => t.CreatedAt).ToArray();

                        try
                        {
                            //This is a silly method for checking whether a new application version exists without me having my own website.
                            //I manage the most recent version number in the description of a tournament hosted on challonge. This code fetches that number
                            var versionCheckPortal = new ChallongePortal(ApiKey, "fizzitestorg");
                            MostRecentVersion = versionCheckPortal.GetTournaments().Where(t => t.Name == "CMDVersionTest").Select(t =>
                            {
                                //Modifying the description seems to put some html formatting into the result. This filters the description for
                                //just the version number by itself
                                var versionResult = string.Concat(t.Description.Where(c => char.IsDigit(c) || c == '.'));
                                return versionResult;
                            }).First();

                            //Check both version numbers to determine if current version is older than recent version
                            var versionCompareResult = Version.Split('.').Zip(MostRecentVersion.Split('.'), (v, mrv) =>
                            {
                                return int.Parse(v).CompareTo(int.Parse(mrv));
                            }).FirstOrDefault(i => i != 0);

                            //If app version is older than most recent version, show message
                            IsVersionOutdatedVisible = versionCompareResult < 0;
                        }
                        catch (Exception)
                        {
                            //If version check fails simply ignore the problem and move on
                            System.Diagnostics.Debug.WriteLine("Version check failed.");
                        }

                        break;
                    case ScreenType.TournamentSelection:
                        if (Context != null) Context.Dispose();
                        if (matchesChangedHandler != null) Context.Tournament.PropertyChanged -= matchesChangedHandler;

                        //Create tournament context from selected tournament
                        Context = new TournamentContext(Portal, SelectedTournament.Id);
                        Context.StartSynchronization(TimeSpan.FromMilliseconds(500), 6);

                        //Create TO View Model
                        OrgViewModel = new OrganizerViewModel(this, dispatcher);

                        //Load up matches into display matches. This is done to allow ordering of assigned matches over unassigned matches without having to refresh the view
                        DisplayMatches = Context.Tournament.Matches.Select(kvp => new DisplayMatch(OrgViewModel, kvp.Value, DisplayMatch.DisplayType.Assigned))
                            .Concat(Context.Tournament.Matches.Select(kvp => new DisplayMatch(OrgViewModel, kvp.Value, DisplayMatch.DisplayType.Unassigned))).ToList();

                        //This handler is used to keep matches display matches in sync with tournament context matches. If the matches in the context change, re-generate the display matches
                        matchesChangedHandler = new PropertyChangedEventHandler((sender, e) =>
                        {
                            if (e.PropertyName == "Matches")
                            {
                                if (Context.Tournament.Matches == null) DisplayMatches = null;
                                else
                                {
                                    DisplayMatches = Context.Tournament.Matches.Select(kvp => new DisplayMatch(OrgViewModel, kvp.Value, DisplayMatch.DisplayType.Assigned))
                                        .Concat(Context.Tournament.Matches.Select(kvp => new DisplayMatch(OrgViewModel, kvp.Value, DisplayMatch.DisplayType.Unassigned))).ToList();
                                }
                            }
                        });
                        Context.Tournament.PropertyChanged += matchesChangedHandler;

                        break;
                }

                CurrentScreen = (ScreenType)((int)CurrentScreen + 1);
            }, startAction, endAction, errorHandler);

            Back = Command.CreateAsync(() => true, () =>
            {
                switch (CurrentScreen)
                {
                    case ScreenType.TournamentSelection:
                        ApiKey = null;
                        break;
                    case ScreenType.PendingMatchView:
                        if (OrgViewModel != null)
                        {
                            OrgViewModel.Dispose();
                            OrgViewModel = null;
                        }
                        break;
                }
                CurrentScreen = (ScreenType)((int)CurrentScreen - 1);
            }, startAction, endAction, errorHandler);

            IgnoreVersionNotification = Command.Create(() => true, () => IsVersionOutdatedVisible = false);
        }