/// <summary>
 /// Checks whether credentials provided by client are valid.
 /// </summary>
 /// <param name="userName">Name of the player who wants to sign in.</param>
 /// <param name="password">Password which is used to sign into account.</param>
 /// <param name="formLogin">Form used to display information whether logging was successfull.</param>
 /// <remarks>
 /// Returns true if user has entered valid credentials and managed to sing in.
 /// False if user entered wrong credentials.
 /// </remarks>
 /// <returns>
 /// True if user has entered valid credentials and managed to sing in.
 /// False if user entered wrong credentials.
 /// </returns>
 public bool LogInToExistingAccount(string userName, string password, FormLogin formLogin)
 {
     using (var dataBase = new DataClassesBettingParlorDataContext())
     {
         if (!formLogin.CheckIfTextBoxesAreEmpty())
         {
             Player player = dataBase.Players.SingleOrDefault(p => p.UserName == userName && p.Password == password);
             if (player != null)
             {
                 result = FormLogin.Result.LoginToDataBaseSuccessful;
                 formLogin.ShowResult(result);
                 return(true);
             }
             else
             {
                 result = FormLogin.Result.LoginToDataBaseFailed;
                 formLogin.ShowResult(result);
                 return(false);
             }
         }
         else
         {
             return(false);
         }
     }
 }
        /// <summary>
        /// Handles the process of placing bet by clients.
        /// Adds new bet which was created to database and respectively places it in client object stored on server.
        /// </summary>
        /// <param name="connectionId">Id of client which wants to place a bet.</param>
        /// <param name="betValue">Value of the bet which should be placed.</param>
        /// <param name="dogToWin">Number of the dog on which bet should be placed.</param>
        /// <param name="isStandard">Specifies whether standard bet or handicap should be placed.</param>
        /// <returns>
        /// True if bet was successsfully created.
        /// False if client is not able to place bet which he requested.
        /// </returns>
        /// <remarks>
        /// Returns true if bet was successsfully created.
        /// False if client is not able to place bet which he requested.
        /// Returend parameter is used on client side in <see cref="Client"/> class to show him result whether he can or not place bet he requested.
        /// </remarks>
        public bool PlaceClientBet(string connectionId, decimal betValue, int dogToWin, bool isStandard)
        {
            using (var dataBase = new DataClassesBettingParlorDataContext())
            {
                var currentUserRowInDictionary = GetCurrentClientRow(connectionId);

                var searchUserAccountInDatabase = (from player in dataBase.Players
                                                   where player.UserName == currentUserRowInDictionary.Value.Name
                                                   select player).SingleOrDefault();

                if (currentUserRowInDictionary.Value.Cash >= betValue)                              //check if client has enough cash to place this bet.
                {
                    searchUserAccountInDatabase.CurrentAccountBalance -= betValue;                  //substract money from client account in database.

                    if (isStandard)                                                                 //check what sort of bet it is.
                    {
                        CurrentBet currentBet = new CurrentBet                                      //create bet in dataBase to display it in dataGriedView
                        {
                            Bettor_name = currentUserRowInDictionary.Value.Name,
                            Amount_bet  = betValue,
                            Dog_to_win  = dogToWin
                        };

                        currentUserRowInDictionary.Value.PlaceBet(BetFactory.BetSort.standartBet, betValue, dogToWin);      //place bet in user object.
                        dataBase.CurrentBets.InsertOnSubmit(currentBet);
                    }
                    else
                    {
                        var searchCurrentBetRow = dataBase.CurrentBets.SingleOrDefault(p => p.Bettor_name == currentUserRowInDictionary.Value.Name); //Check if client has placed standardBet

                        if (searchCurrentBetRow != null)                                                                                             //If user has placed standard bet.
                        {
                            searchCurrentBetRow.Amount_bet += betValue;
                            searchCurrentBetRow.Dog_to_win  = dogToWin;
                        }
                        else                                       //If user has not placed standard bet.
                        {
                            CurrentBet currentBet = new CurrentBet //create bet in dataBase to display it in dataGriedView
                            {
                                Bettor_name = currentUserRowInDictionary.Value.Name,
                                Amount_bet  = betValue,
                                Dog_to_win  = dogToWin
                            };

                            dataBase.CurrentBets.InsertOnSubmit(currentBet);
                        }
                        currentUserRowInDictionary.Value.PlaceBet(BetFactory.BetSort.handicapBet, betValue, dogToWin);
                    }
                    dataBase.SubmitChanges();       //submit all changes made to database.

                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }
        /// <summary>
        /// Returns the current account balance of player stored in database.
        /// </summary>
        /// <param name="userName">Name of the player which current account balance should be returned.</param>
        /// <remarks>
        /// Returns current account balance of specified player.
        /// </remarks>
        /// <returns>Current account balance of specified player.</returns>
        public decimal GetCurrentClientAccountBalance(string userName)
        {
            using (var dataBase = new DataClassesBettingParlorDataContext())
            {
                var searchUserAccount = (from player in dataBase.Players
                                         where player.UserName == userName
                                         select player).SingleOrDefault();

                return(searchUserAccount.CurrentAccountBalance);
            }
        }
        /// <summary>
        /// Updates administrator cash stored in database.
        /// </summary>
        /// <param name="adminName">Name of the administrator.</param>
        /// <param name="moneyTransfer">Amount of cash which should be added to administrator account in database.</param>
        public void AddCashToAdminAccount(string adminName, decimal moneyTransfer)
        {
            using (var dataBase = new DataClassesBettingParlorDataContext())
            {
                var adminAccount = dataBase.Players.Where(p => p.UserName == adminName).SingleOrDefault();

                adminAccount.CurrentAccountBalance += moneyTransfer;

                dataBase.SubmitChanges();
            }
        }
        /// <summary>
        /// Searches for current user and sends his current cash to update money stored in database.
        /// </summary>
        /// <param name="userNameOfTheCurrentBettor">Name of the player which cash should be updated.</param>
        /// <param name="amount">Amount of cash which represents current account balance of player.</param>
        /// <remarks>
        /// Updates account balance stored in database to actual stored in application which was changed after the race.
        /// </remarks>
        public void SendCashToDatabase(string userNameOfTheCurrentBettor, decimal amount)
        {
            using (var dataBase = new DataClassesBettingParlorDataContext())
            {
                var searchCurrentUserAccount = (from currentBettor in dataBase.Players
                                                where currentBettor.UserName == userNameOfTheCurrentBettor
                                                select currentBettor).SingleOrDefault();

                searchCurrentUserAccount.CurrentAccountBalance = amount;
                dataBase.SubmitChanges();
            }
        }
        /// <summary>
        /// Runs collect bet method for each user who placed a bet and sends cash to database.
        /// </summary>
        /// <param name="winner">Number of the dog which won the race.</param>
        /// <remarks>
        /// Resets all bets to default value.
        /// At the end truncates table with bets from previous game to prepare it for next race.
        /// </remarks>
        public void CollectClientBets(int winner)
        {
            foreach (var user in connectedClients)
            {
                user.Value.CollectBet(winner);                                      //collect client bet.

                SendCashToDatabase(user.Value.Name, user.Value.Cash);               //send his cash to databse.

                user.Value.ClearBet();                                              //place dummy bet (simply clear object).
            }
            using (var dataBase = new DataClassesBettingParlorDataContext())
            {
                dataBase.ExecuteCommand("TRUNCATE TABLE CurrentBets");              //resets SQL table
            }
        }
        /// <summary>
        /// Updates cash in database and in current user object in the programm.
        /// </summary>
        /// <param name="connectionId">Id of the client who transfered money.</param>
        /// <param name="moneyTransfer">Amount of cash which should be added to user account in database.</param>
        public void AddCashToClientAccount(string connectionId, decimal moneyTransfer)
        {
            using (var dataBase = new DataClassesBettingParlorDataContext())
            {
                var currentuserRowInDictionary = GetCurrentClientRow(connectionId);

                var searchUserAccountInDatabase = (from player in dataBase.Players
                                                   where player.UserName == currentuserRowInDictionary.Value.Name
                                                   select player).SingleOrDefault();

                searchUserAccountInDatabase.CurrentAccountBalance += moneyTransfer;

                dataBase.SubmitChanges();

                currentuserRowInDictionary.Value.AddCashToMyAccount(moneyTransfer);
            }
        }
        /// <summary>
        /// Handles the process of placing bet by administrator.
        /// Adds new bet which was created to database.
        /// </summary>
        /// <param name="adminName">Name of the administrator.</param>
        /// <param name="betValue">Value of the bet which should be placed.</param>
        /// <param name="dogToWin">Number of dog on which bet should be placed.</param>
        /// <param name="betSort">What sort of bet should be placed.</param>
        /// <remarks>
        /// Only database operations are stored here because admin object (<see cref="Parlor"/>) is already on server so whenever he places bet his object is instantly updated.
        /// </remarks>
        public void PlaceAdminBet(string adminName, decimal betValue, int dogToWin, BetFactory.BetSort betSort)
        {
            using (var dataBase = new DataClassesBettingParlorDataContext())
            {
                var searchAdminAccount = (from player in dataBase.Players
                                          where player.UserName == adminName
                                          select player).SingleOrDefault();

                searchAdminAccount.CurrentAccountBalance -= betValue;     //substract money from database.

                if (betSort == BetFactory.BetSort.standartBet)
                {
                    CurrentBet currentBet = new CurrentBet
                    {
                        Bettor_name = adminName,
                        Amount_bet  = betValue,
                        Dog_to_win  = dogToWin
                    };

                    dataBase.CurrentBets.InsertOnSubmit(currentBet);
                }
                else
                {
                    var searchCurrentBetRow = dataBase.CurrentBets.SingleOrDefault(p => p.Bettor_name == adminName); //Check if admin has placed standardBet.

                    if (searchCurrentBetRow != null)                                                                 //If admin has placed standard bet.
                    {
                        searchCurrentBetRow.Amount_bet += betValue;
                        searchCurrentBetRow.Dog_to_win  = dogToWin;
                    }
                    else                                       //If admin has not placed standard bet.
                    {
                        CurrentBet currentBet = new CurrentBet //create bet in dataBase to display it in dataGriedView.
                        {
                            Bettor_name = adminName,
                            Amount_bet  = betValue,
                            Dog_to_win  = dogToWin
                        };

                        dataBase.CurrentBets.InsertOnSubmit(currentBet);
                    }
                }
                dataBase.SubmitChanges();
            }
        }
        /// <summary>
        /// Registers new player by creating new account in dataBase which stores his credentials.
        /// </summary>
        /// <param name="userName">Name of the player who wants to create new account.</param>
        /// <param name="password">Password which is used to sign into account.</param>
        /// <param name="formLogin">Form used to display information whether registration was successfull.</param>
        /// <remarks>
        /// Returns true if client account with given user name has been created.
        /// False if client account has not been created because username is already taken.
        /// </remarks>
        /// <returns>
        /// True if client account with given user name has been created.
        /// False if client account has not been created because username is already taken.
        /// </returns>
        public bool RegisterNewPlayer(string userName, string password, FormLogin formLogin)
        {
            using (var dataBase = new DataClassesBettingParlorDataContext())
            {
                if (!formLogin.CheckIfTextBoxesAreEmpty())
                {
                    Player player = dataBase.Players.SingleOrDefault(p => p.UserName == userName);

                    if (player == null)
                    {
                        Player newPlayer = new Player()
                        {
                            UserName = userName,
                            Password = password,
                            CurrentAccountBalance = 0,
                            UserTypeID            = 1
                        };
                        dataBase.Players.InsertOnSubmit(newPlayer);
                        dataBase.SubmitChanges();

                        result = FormLogin.Result.RegistrationSuccessful;
                        formLogin.ShowResult(result);
                        return(true);
                    }
                    else
                    {
                        result = FormLogin.Result.RegistrationFailed;
                        formLogin.ShowResult(result);
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }
        }