public List <string> AllTheGamesThatPlayesNow()
        {
            List <string> gamesThatPlaysNow = new List <string>();

            try
            {
                using (var ctx = new FourinrowDBContext())
                {
                    var gamesNow = (from gdn in ctx.GameDetailsNows
                                    select gdn).ToList();

                    int i; i = 1;

                    /*doing the thing*/
                    foreach (var gn in gamesNow)
                    {
                        gamesThatPlaysNow.Add($" {i++}: {gn.User1Name} against " +
                                              $"{gn.User2Name}, start time: " +
                                              $"{gn.GameDateStart.ToString("t", DateTimeFormatInfo.InvariantInfo)}");
                    }/*end of loop*/

                    return(gamesThatPlaysNow);
                }/*end of using*/
            }
            catch (DbException dex)
            {
                throw new FaultException <DbException>(dex);
            }
            catch (Exception ex)
            {
                throw new FaultException <Exception>(ex);
            }
        }
 public void ClientRegistered(string userName, string hashedPasswd)
 {
     if (Clients.ContainsKey(userName))
     {
         throw new FaultException <UserExistsFault>(new UserExistsFault()
         {
             Details = "User name " + userName + " already exists. Try something else"
         });
     }
     using (var ctx = new FourinrowDBContext())
     {
         var user = (from u in ctx.Users
                     where u.UserName == userName
                     select u).FirstOrDefault();
         if (user == null)
         {
             User newUser = new User()
             {
                 UserName       = userName,
                 HashedPassword = hashedPasswd
             };
             ctx.Users.Add(newUser);
             ctx.SaveChanges();
         }
         ++NumClients;
         IFourRowServiceCallback callbackChannel = OperationContext.Current.GetCallbackChannel <IFourRowServiceCallback>();
         Clients.Add(userName, callbackChannel);
     }
 }
        /*getAllUsersEver method*/
        public List <string> GetAllUsersEver()
        {
            List <string> allUsers = new List <string>();

            try
            {
                using (var ctx = new FourinrowDBContext())
                {
                    var theUsersRequested = (from u in ctx.Users
                                             select u).ToList();

                    foreach (var tur in theUsersRequested)
                    {
                        allUsers.Add(tur.UserName);
                    }

                    return(allUsers);
                }/*end of using*/
            }
            catch (DbException dex)
            {
                throw new FaultException <DbException>(dex);
            }
            catch (Exception ex)
            {
                throw new FaultException <Exception>(ex);
            }
        }/*end of -getAllUsersEver- method*/
        public List <string> GetAllUsersInDb()
        {
            try
            {
                List <string> res = new List <string>();
                using (var ctx = new FourinrowDBContext())
                {
                    List <string> users = (from u in ctx.Users
                                           select u.UserName).ToList();
                    if (users.FirstOrDefault() == null)
                    {
                        res.Add("DB is empty");
                        return(res);
                    }
                    res.Add($"There is {users.Count} users in db");

                    foreach (var str in users)
                    {
                        res.Add(str);
                    }
                    return(res);
                }
            }
            catch (DbException ex)
            {
                throw new FaultException <DbException>(ex);
            }
            catch (Exception ex)
            {
                throw new FaultException <Exception>(ex);
            }
        }
        private void UpdatePointAndHistory(
            string currentPlayer,
            string opponent,
            string winnerName,
            Game theGame,
            FourinrowDBContext ctx)
        {
            Tuple <int, int> points            = theGame.CalcPoints(currentPlayer, opponent, winnerName);
            DateTime         endGameDate       = DateTime.Now;
            GameDetail       updateGameHistory = (from gd in ctx.GameDetails
                                                  where ((gd.User1Name == currentPlayer && gd.User2Name == opponent &&
                                                          gd.PointsUser1 == -1 && gd.PointsUser2 == -1) ||
                                                         (gd.User1Name == opponent && gd.User2Name == currentPlayer &&
                                                          gd.PointsUser1 == -1 && gd.PointsUser2 == -1))
                                                  select gd).FirstOrDefault();

            if (updateGameHistory == null)
            {
                return;
            }
            updateGameHistory.WinningUserName = winnerName;
            updateGameHistory.PointsUser1     = points.Item1;
            updateGameHistory.PointsUser2     = points.Item2;
            updateGameHistory.GameDateEnd     = endGameDate;
            ctx.SaveChanges();
        }
        public void ClientDisconnectedThrowGame(string currentPlayer, string opponent, string whosOut)
        {
            try
            {
                Tuple <string, string> thisGamePlayers = Tuple.Create(currentPlayer, opponent);
                Game theGame = null;
                if (_games.ContainsKey(thisGamePlayers))
                {
                    theGame = _games[thisGamePlayers];
                    _games.Remove(thisGamePlayers);
                }
                using (var ctx = new FourinrowDBContext())
                {
                    var removeGameNow = (from gdw in ctx.GameDetailsNows
                                         where ((gdw.User1Name == currentPlayer && gdw.User2Name == opponent) ||
                                                (gdw.User1Name == opponent && gdw.User2Name == currentPlayer))
                                         select gdw).FirstOrDefault();

                    if (removeGameNow != null)
                    {
                        ctx.GameDetailsNows.Remove(removeGameNow);
                        ctx.SaveChanges();
                    }

                    string winnerName = whosOut == currentPlayer ? opponent : currentPlayer;

                    UpdatePointAndHistory(currentPlayer, opponent, winnerName, theGame, ctx);
                    ctx.SaveChanges();

                    string player2Notify = whosOut == currentPlayer ? opponent : currentPlayer;

                    if (ConnectedClient.ContainsKey(player2Notify))
                    {
                        new Thread(() =>
                        {
                            Clients[player2Notify].OpponentDisconnectedThrowGameYouWon();
                        }).Start();
                    }

                    if (_clientsThatNotPlay.Contains(player2Notify))
                    {
                        return;
                    }

                    _clientsThatNotPlay.Add(player2Notify);
                }
            }
            catch (DbException ex)
            {
                throw new FaultException <DbException>(ex);
            }
            catch (Exception ex)
            {
                throw new FaultException <Exception>(ex);
            }
        }
        public bool ClearUsers()
        {
            try
            {
                using (var ctx = new FourinrowDBContext())
                {
                    string res = "elements: ";
                    int    cnt = 0;
                    var    x   = (from u in ctx.Users
                                  select u); // clear db
                    foreach (var item in x)
                    {
                        if (item.UserName != null)
                        {
                            res += item.UserName + " ";
                        }
                        cnt++;
                        if (x.FirstOrDefault() == null)
                        {
                            break;
                        }
                        ctx.Users.Remove(item);
                        //ctx.SaveChanges();
                    }
                    MessageBox.Show(res + " element count: " + cnt.ToString());

                    ctx.SaveChanges();

                    var x1 = (from u in ctx.Users
                              orderby u.UserName descending
                              select u).FirstOrDefault();
                    if (x1 == null)
                    {
                        Clients.Clear();
                        return(true);
                    }
                }
            }
            catch (DbException dex)
            {
                throw new FaultException <DbException>(dex);
            }
            catch (Exception ex)
            {
                throw new FaultException <Exception>(ex);
            }
            return(false);
        }
        }/*end of -getAllUsersEver- method*/

        public List <UserHistory> AllUsersGamesHistoryPrivately()
        {
            List <UserHistory> allUsersGamesHistory = new List <UserHistory>();
            int numOfPlays, numOfWins, numOfLoses, numOfPoints;

            using (var ctx = new FourinrowDBContext())
            {
                var allUsers = (from u in ctx.Users
                                select u.UserName).ToList();

                var allGames = (from gd in ctx.GameDetails
                                select gd).ToList();

                /*get the details of each user*/
                foreach (var user in allUsers)
                {
                    numOfPlays = numOfWins = numOfLoses = numOfPoints = 0;

                    foreach (var game in allGames)
                    {
                        if (!(user == game.User1Name || user == game.User2Name))
                        {
                            continue;
                        }

                        numOfPlays++;
                        numOfWins   += (user == game.WinningUserName ? 1 : 0);
                        numOfLoses  += (user == game.WinningUserName ? 0 : (game.WinningUserName == "draw" ? 0 : 1));
                        numOfPoints += (user == game.User1Name ? game.PointsUser1 : game.PointsUser2);
                    }/*end of inner loop*/

                    UserHistory userHistory = new UserHistory()
                    {
                        UserName         = user,
                        NumberOfGames    = numOfPlays,
                        NumberOfWinnings = numOfWins,
                        NumberOfLoses    = numOfLoses,
                        NumberOfPoints   = numOfPoints
                    };

                    allUsersGamesHistory.Add(userHistory);
                }/*end of outer loop*/

                return(allUsersGamesHistory);
            }
        }
 public void ClientConnected(string userName, string hashedPasswd)
 {
     if (ConnectedClient.ContainsKey(userName))
     {
         throw new FaultException <UserAlreadyConnectedFault>(new UserAlreadyConnectedFault()
         {
             Details = "User name " + userName + " Already Connected"
         });
     }
     using (var ctx = new FourinrowDBContext())
     {
         var user = (from u in ctx.Users
                     where u.UserName == userName
                     select u).FirstOrDefault();
         if (user == null)
         {
             throw new FaultException <UserDoesntExistsFault>(new UserDoesntExistsFault()
             {
                 Details = "User name " + userName + " Doesnt exists. Please register"
             });
         }
         if (user.HashedPassword != hashedPasswd)
         {
             throw new FaultException <WrongPasswordFault>(new WrongPasswordFault()
             {
                 Details = "Worng PassWord!"
             });
         }
         if (!Clients.ContainsKey(userName))
         {
             IFourRowServiceCallback callbackChannel = OperationContext.Current.GetCallbackChannel <IFourRowServiceCallback>();
             Clients.Add(userName, callbackChannel);
         }
         if (!ConnectedClient.ContainsKey(userName))
         {
             ConnectedClient.Add(userName, Clients[userName]);
         }
         if (!_clientsThatNotPlay.Contains(userName))
         {
             _clientsThatNotPlay.Add(userName);
         }
         ++ConnectedClientsCnt;
     }
 }
        public List <string> AllTheGamesThatPlayesSoFar()
        {
            List <string> gamesthatPlayedSofar = new List <string>();

            try
            {
                using (var ctx = new FourinrowDBContext())
                {
                    var gamesSoFar = (from gd in ctx.GameDetails
                                      select gd).ToList();
                    int i = 1;

                    /*arrange the things*/
                    foreach (var gsf in gamesSoFar)
                    {
                        string someString = $" {i++}: {gsf.User1Name} against {gsf.User2Name}, ";

                        if (gsf.WinningUserName == "draw")
                        {
                            someString += "draw, ";
                        }
                        else
                        {
                            int winnerPoints = gsf.WinningUserName == gsf.User1Name ? gsf.PointsUser1 : gsf.PointsUser2;
                            someString += $"winner: {gsf.WinningUserName},  winner points: {winnerPoints}, ";
                        }
                        someString += $"game date: {gsf.GameDateStart.ToString("d", DateTimeFormatInfo.InvariantInfo)}";

                        gamesthatPlayedSofar.Add(someString);
                    }/*end of loop*/

                    return(gamesthatPlayedSofar);
                }/*end of using*/
            }
            catch (DbException dex)
            {
                throw new FaultException <DbException>(dex);
            }
            catch (Exception ex)
            {
                throw new FaultException <Exception>(ex);
            }
        }
 private void WinOrDraw(
     string currentPlayer,
     string opponent,
     Game theGame,
     MoveResult result,
     string whoMoved)
 {
     using (FourinrowDBContext ctx = new FourinrowDBContext())
     {
         GameDetailsNow gameDetailsNow = (from gdn in ctx.GameDetailsNows
                                          where ((gdn.User1Name == currentPlayer && gdn.User2Name == opponent) ||
                                                 (gdn.User1Name == opponent && gdn.User2Name == currentPlayer))
                                          select gdn).FirstOrDefault();
         if (gameDetailsNow != null)
         {
             ctx.GameDetailsNows.Remove(gameDetailsNow);
             ctx.SaveChanges();
         }
         string winnerName = result == MoveResult.Draw ? "draw" : whoMoved;
         UpdatePointAndHistory(currentPlayer, opponent, winnerName, theGame, ctx);
         ctx.SaveChanges();
     }
 }
        public void OpponentAcceptToPlay(string currentPlayer, string opponent)
        {
            try
            {
                if (!(Clients.ContainsKey(currentPlayer) && Clients.ContainsKey(opponent)))
                {
                    return;
                }

                if (_clientsThatNotPlay.Contains(currentPlayer))
                {
                    _clientsThatNotPlay.Remove(currentPlayer);
                }

                if (_clientsThatNotPlay.Contains(opponent))
                {
                    _clientsThatNotPlay.Remove(opponent);
                }

                Tuple <string, string> thisGamePlayers = Tuple.Create(currentPlayer, opponent);

                if (_sideModeClients.Contains(thisGamePlayers))
                {
                    _sideModeClients.Remove(thisGamePlayers);
                }

                if (!_games.ContainsKey(thisGamePlayers))
                {
                    _games.Add(thisGamePlayers, new Game());
                }

                using (var ctx = new FourinrowDBContext())
                {
                    ctx.GameDetailsNows.Add(new GameDetailsNow()
                    {
                        User1Name     = currentPlayer,
                        User2Name     = opponent,
                        GameDateStart = DateTime.Now
                    });


                    ctx.SaveChanges();

                    ctx.GameDetails.Add(new GameDetail()
                    {
                        User1Name       = currentPlayer,
                        User2Name       = opponent,
                        WinningUserName = "******",
                        PointsUser1     = -1,
                        PointsUser2     = -1,
                        GameDateStart   = DateTime.Now,
                        GameDateEnd     = DateTime.Now
                    });
                    ctx.SaveChanges();
                }
                if (ConnectedClient.ContainsKey(currentPlayer))
                {
                    Thread updateOtherPlayerThread = new Thread(() =>
                    {
                        Clients[currentPlayer].OpponentAcceptToPlayLetsStart();
                    }
                                                                );

                    updateOtherPlayerThread.Start();
                }

                if (ConnectedClient.ContainsKey(opponent))
                {
                    Thread updateOtherPlayerThread = new Thread(() =>
                    {
                        Clients[opponent].LetsStart();
                    }
                                                                );

                    updateOtherPlayerThread.Start();
                }
            }
            catch (DbException ex)
            {
                throw new FaultException <DbException>(ex);
            }
            catch (Exception ex)
            {
                throw new FaultException <Exception>(ex);
            }
        }
        public List <string> AllTheGamesOfSomeClient(string userName)
        {
            List <string> theGamesOfSomeClient = new List <string>();

            try
            {
                using (var ctx = new FourinrowDBContext())
                {
                    var gamesOfSomeClient = (from gd in ctx.GameDetails
                                             where (gd.User1Name == userName ||
                                                    gd.User2Name == userName)
                                             select gd).ToList();

                    if (gamesOfSomeClient.Count == 0)
                    {
                        return(theGamesOfSomeClient);
                    }

                    theGamesOfSomeClient.Add($"             all the games of {userName}   \n" +
                                             $"                   total games: {gamesOfSomeClient.Count}   ");

                    int i = 1;
                    int totalWinnings, totalLoses, totalPoints;
                    totalWinnings = totalLoses = totalPoints = 0;

                    foreach (var gosc in gamesOfSomeClient)
                    {
                        string someString = $" {i++}: {userName} against ";

                        if (gosc.User1Name == userName)
                        {
                            someString += $"{gosc.User2Name}";
                        }
                        else
                        {
                            someString += $"{gosc.User1Name}";
                        }

                        someString += $", game date: {gosc.GameDateStart.ToString("g", DateTimeFormatInfo.InvariantInfo)}, ";

                        if (gosc.WinningUserName == "draw")
                        {
                            someString += "draw";
                        }
                        else
                        {
                            someString += $"winner: {gosc.WinningUserName}";

                            if (gosc.WinningUserName == userName)
                            {
                                totalWinnings++;
                            }
                            else
                            {
                                totalLoses++;
                            }
                        }

                        if (gosc.User1Name == userName)
                        {
                            totalPoints += gosc.PointsUser1;
                        }
                        else
                        {
                            totalPoints += gosc.PointsUser2;
                        }

                        theGamesOfSomeClient.Add(someString);
                    }/*end of loop*/

                    string someOtherString = "\n            conclusins   \n";

                    someOtherString += $"•winnings: {totalWinnings},    •losses: {totalLoses}\n";
                    someOtherString += $"win ratio (precentage): {String.Format("{0:0.00}", Convert.ToDecimal(totalWinnings) / gamesOfSomeClient.Count * 100)}%\n";
                    someOtherString += $"total points: {totalPoints}";

                    theGamesOfSomeClient.Add(someOtherString);

                    return(theGamesOfSomeClient);
                }/*end of using*/
            }
            catch (DbException dex)
            {
                throw new FaultException <DbException>(dex);
            }
            catch (Exception ex)
            {
                throw new FaultException <Exception>(ex);
            }
        }
        public List <string> AllTheGamesBetweenTwoClients(string userName1, string userName2)
        {
            List <string> gamesBetweenTwoClients = new List <string>();

            try
            {
                using (var ctx = new FourinrowDBContext())
                {
                    var thoseGames = (from gd in ctx.GameDetails
                                      where ((gd.User1Name == userName1 && gd.User2Name == userName2) ||
                                             (gd.User1Name == userName2 && gd.User2Name == userName1))
                                      select gd).ToList();

                    if (thoseGames.Count == 0)
                    {
                        return(gamesBetweenTwoClients);
                    }

                    gamesBetweenTwoClients.Add($"           the games between {userName1} and {userName2}   \n" +
                                               $"                        total games: {thoseGames.Count}   ");

                    int i = 1;
                    int numOfWinsUser1, numOfWinsUser2;
                    numOfWinsUser1 = numOfWinsUser2 = 0;

                    foreach (var tg in thoseGames)
                    {
                        string someString = $" {i++}: game date: {tg.GameDateStart.ToString("g", DateTimeFormatInfo.InvariantInfo)}, ";

                        if (tg.WinningUserName == "draw")
                        {
                            someString += "draw";
                        }
                        else
                        {
                            someString += $"winner: {tg.WinningUserName}";

                            if (tg.WinningUserName == userName1)
                            {
                                numOfWinsUser1++;
                            }
                            else
                            {
                                numOfWinsUser2++;
                            }
                        }

                        gamesBetweenTwoClients.Add(someString);
                    }/*end of loop*/

                    string someOtherString = "\n           wins ratio (percentage)   \n";

                    someOtherString += $"{userName1}: {String.Format("{0:0.00}", Convert.ToDecimal(numOfWinsUser1) / thoseGames.Count * 100)}%      " +
                                       $"{userName2}: {String.Format("{0:0.00}", Convert.ToDecimal(numOfWinsUser2) / thoseGames.Count * 100)}%";

                    gamesBetweenTwoClients.Add(someOtherString);

                    return(gamesBetweenTwoClients);
                }/*end of using*/
            }
            catch (DbException dex)
            {
                throw new FaultException <DbException>(dex);
            }
            catch (Exception ex)
            {
                throw new FaultException <Exception>(ex);
            }
        }