Esempio n. 1
0
 /// <summary>
 /// Finds the enclosing private area.
 /// </summary>
 /// <param name="enclosedSharedObject">The enclosed shared object.</param>
 /// <returns>null or the enclosing shared object if found.</returns>
 public SharedObject FindEnclosingPrivateArea(SharedObject enclosedSharedObject)
 {
     foreach (var sharedObject in ZOrderListOfSharedObjects)
     {
         if (sharedObject.PrivateOwnerName != null &&
             sharedObject.Rectangle.Contains(enclosedSharedObject.Rectangle))
         {
             return(sharedObject);
         }
     }
     return(null);
 }
Esempio n. 2
0
 /// <summary>
 /// Tries to stack the grabbedSharedObject on another shared object.
 /// The grabbedShared object has to be composed of stackable elements and to be brought to front.
 /// The first shared object found under the grabbed shared object has also to be composed of stackable
 /// elements of the same kind and must be placed at the same location.
 /// </summary>
 /// <param name="grabbedSharedObject">The grabbed shared object.</param>
 /// <param name="stackObject">The stack object.</param>
 /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
 public bool TryToStackOnAnotherSharedObject(SharedObject grabbedSharedObject, out SharedObject stackObject)
 {
     stackObject = null;
     if (!(grabbedSharedObject.GameElements.First() is IStackable))
     {
         return(false);
     }
     if (ZOrderListOfSharedObjects.First() != grabbedSharedObject)
     {
         return(false);
     }
     foreach (SharedObject sharedObject in ZOrderListOfSharedObjects)
     {
         if (sharedObject.Rectangle.IntersectsWith(grabbedSharedObject.Rectangle) && sharedObject != grabbedSharedObject)
         {
             // sharedObject is the first shared object found under the grabbed one.
             Point centerSharedObject = new Point(sharedObject.Location.X + sharedObject.Rectangle.Width / 2,
                                                  sharedObject.Location.Y + sharedObject.Rectangle.Height / 2);
             Point centerGrabbedObject = new Point(grabbedSharedObject.Location.X + grabbedSharedObject.Rectangle.Width / 2,
                                                   grabbedSharedObject.Location.Y + grabbedSharedObject.Rectangle.Height / 2);
             if (centerSharedObject.Equals(centerGrabbedObject) &&
                 sharedObject.GameElements.First() is IStackable &&
                 sharedObject.GameElements.First().GetType() == grabbedSharedObject.GameElements.First().GetType())
             {
                 // stacking is possible:
                 stackObject = sharedObject;
             }
             break;
         }
     }
     if (stackObject != null)
     {
         if (stackObject.GameElements.Count < 2 && stackObject.GameElements.First() is Card)
         {
             // The stack object was a single card. Change its size for a stack of cards:
             stackObject.Rectangle = new Rectangle(stackObject.Rectangle.X, stackObject.Rectangle.Y, DimXStackOfCards, DimYStackOfCards);
             // and apply again magnetic grid:
             stackObject.Rectangle = new Rectangle(GetMagneticLocation(stackObject.Rectangle), stackObject.Rectangle.Size);
         }
         // Stack the elements
         for (int i = grabbedSharedObject.GameElements.Count - 1; i >= 0; i--)
         {
             GameElement gameElement = grabbedSharedObject.GameElements[i];
             stackObject.GameElements.Insert(0, gameElement);
         }
         // Remove the grabbed shared object from the ZList:
         ZOrderListOfSharedObjects.RemoveAt(0);
         return(true);
     }
     return(false);
 }
Esempio n. 3
0
        /// <summary>
        /// Creates a private area for the given client.
        /// </summary>
        /// <param name="clientName">Name of the client.</param>
        /// <param name="newSharedObject">if set to <c>true</c> the private area was created; otherwise it was already existing.</param>
        /// <returns>SharedObject.</returns>
        public SharedObject CreatePrivateArea(string clientName, out bool newSharedObject)
        {
            newSharedObject = false;
            var foundSharedObject = FindPrivateArea(clientName);

            if (foundSharedObject == null)
            {
                newSharedObject = true;
                var id = GetFreeId();
                var theNewSharedObject = new SharedObject(ZOrderListOfSharedObjects, id,
                                                          new Rectangle(3, 3, 180, 100), clientName, new List <GameElement>(new[] { new GameElement("wood") }));
                ZOrderListOfSharedObjects.Insert(id, theNewSharedObject);
                theNewSharedObject.BringToFront();
                return(theNewSharedObject);
            }
            return(foundSharedObject);
        }
Esempio n. 4
0
        /// <summary>
        /// Gathers the cards in the specified rectangle.
        /// </summary>
        /// <param name="gatheringRectangle">The gathering rectangle.</param>
        public void GatherCards(Rectangle gatheringRectangle)
        {
            SharedObject gatheringStackSharedObject = null;

            for (int i = ZOrderListOfSharedObjects.Count - 1; i >= 0; i--)
            {
                SharedObject sharedObject = ZOrderListOfSharedObjects[i];
                if (gatheringRectangle.Contains(sharedObject.Rectangle) && sharedObject.GrabberName == null &&
                    sharedObject.GameElements.First() is Card)
                {
                    gatheringStackSharedObject = sharedObject;
                    break;
                }
            }
            if (gatheringStackSharedObject != null)
            {
                gatheringStackSharedObject.SetAllCardsSameFace(false);
                List <SharedObject> listSharedObjectsToGather = new List <SharedObject>();
                for (int i = ZOrderListOfSharedObjects.Count - 1; i >= 0; i--)
                {
                    SharedObject sharedObject = ZOrderListOfSharedObjects[i];
                    if (gatheringRectangle.Contains(sharedObject.Rectangle) && sharedObject.GrabberName == null &&
                        sharedObject.GameElements.First() is Card && sharedObject != gatheringStackSharedObject)
                    {
                        sharedObject.SetAllCardsSameFace(false);
                        listSharedObjectsToGather.Add(sharedObject);
                    }
                }
                foreach (SharedObject sharedObject in listSharedObjectsToGather)
                {
                    GatherCards(sharedObject, gatheringStackSharedObject);
                }

                // gatheringStackSharedObject.Shuffle();

                // Broadcast the gathering shared object move event:
                StateChangeEventDataType stateChangeEventDataType = new StateChangeEventDataType();
                stateChangeEventDataType.StateChangeEventType    = StateChangeEventType.SharedObjectMove;
                stateChangeEventDataType.SharedObjectId          = gatheringStackSharedObject.Id;
                stateChangeEventDataType.NewSharedObjectLocation = gatheringStackSharedObject.Location;
                stateChangeEventDataType.SharedObjectSize        = gatheringStackSharedObject.Rectangle.Size;
                stateChangeEventDataType.NewSharedObjectPicture  = gatheringStackSharedObject.Picture;
                ScgBroadcastorService.BroadcastStateChange(stateChangeEventDataType, null, null);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Removes one client's private area of the ZOrderList of shared objects.
        /// </summary>
        /// <param name="clientName">Name of the client.</param>
        /// <returns>System.Int32.</returns>
        public int RemovePrivateArea(string clientName)
        {
            SharedObject foundSharedObject = null;

            foreach (var sharedObject in ZOrderListOfSharedObjects)
            {
                if (sharedObject.PrivateOwnerName == clientName)
                {
                    foundSharedObject = sharedObject;
                    break;
                }
            }
            if (foundSharedObject != null)
            {
                ZOrderListOfSharedObjects.RemoveAt(ZOrderListOfSharedObjects.IndexOf(foundSharedObject));
                return(foundSharedObject.Id);
            }
            return(-1);
        }
Esempio n. 6
0
        /// <summary>
        /// Checks if the given private area contains other shared objects.
        /// </summary>
        /// <param name="privateArea">The private area.</param>
        /// <returns>true if the given private area contains other shared objects</returns>
        public bool PrivateAreaIsNotEmpty(SharedObject privateArea)
        {
            if (privateArea.PrivateOwnerName == null)
            {
                return(true); // Not a private area
            }

            foreach (var sharedObject in ZOrderListOfSharedObjects)
            {
                if (sharedObject == privateArea)
                {
                    return(false);
                }
                if (sharedObject != privateArea && privateArea.Rectangle.Contains(sharedObject.Rectangle))
                {
                    return(true);
                }
            }
            return(false);
        }
Esempio n. 7
0
        /// <summary>
        /// Gathers the cards of sharedObject in the GameElments of gatheringObject.
        /// </summary>
        /// <param name="sharedObject">The shared object.</param>
        /// <param name="gatheringObject">The gathering object.</param>
        public void GatherCards(SharedObject sharedObject, SharedObject gatheringObject)
        {
            if (sharedObject.GameElements.First() is Card && gatheringObject.GameElements.First() is Card)
            {
                if (gatheringObject.GameElements.Count == 1)
                {
                    // The gathering object was a single card. Change its size for a stack of cards:
                    gatheringObject.Rectangle = new Rectangle(gatheringObject.Rectangle.X, gatheringObject.Rectangle.Y, DimXStackOfCards, DimYStackOfCards);
                    // and apply again magnetic grid:
                    gatheringObject.Rectangle = new Rectangle(GetMagneticLocation(gatheringObject.Rectangle), gatheringObject.Rectangle.Size);
                }
                // Transfer the cards:
                try
                {
                    foreach (Card card in sharedObject.GameElements)
                    {
                        gatheringObject.GameElements.Insert(0, card);
                    }
                }
                catch (Exception ex)
                {
                    ScgBroadcastorService.LogError(string.Format("Unexpected exception '{0}' in GameState.GatherCards in foreach loop doing gatheringObject.GameElements.Add(card);", ex.Message), 97);
                    throw;
                }

                // Broadcast the gathering shared object move event:
                StateChangeEventDataType stateChangeEventDataType = new StateChangeEventDataType();
                stateChangeEventDataType.StateChangeEventType    = StateChangeEventType.SharedObjectMove;
                stateChangeEventDataType.SharedObjectId          = gatheringObject.Id;
                stateChangeEventDataType.NewSharedObjectLocation = gatheringObject.Location;
                stateChangeEventDataType.SharedObjectSize        = gatheringObject.Rectangle.Size;
                stateChangeEventDataType.NewSharedObjectPicture  = gatheringObject.Picture;
                ScgBroadcastorService.BroadcastStateChange(stateChangeEventDataType, null, null);

                // Remove the source shared object and broadcast the dispose event:
                ZOrderListOfSharedObjects.Remove(sharedObject);
                stateChangeEventDataType.StateChangeEventType = StateChangeEventType.DisposeSharedObject;
                stateChangeEventDataType.SharedObjectId       = sharedObject.Id;
                ScgBroadcastorService.BroadcastStateChange(stateChangeEventDataType, null, null);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Checks if the given private area contains other shared objects.
        /// </summary>
        /// <param name="privateArea">The private area.</param>
        /// <returns>true if the given private area contains other shared objects</returns>
        public bool PrivateAreaIsNotEmpty(SharedObject privateArea)
        {
            if (privateArea.PrivateOwnerName == null)
            {
                return true; // Not a private area
            }

            foreach (var sharedObject in ZOrderListOfSharedObjects)
            {
                if (sharedObject == privateArea)
                {
                    return false;
                }
                if (sharedObject != privateArea && privateArea.Rectangle.Contains(sharedObject.Rectangle))
                {
                    return true;
                }
            }
            return false;
        }
Esempio n. 9
0
 /// <summary>
 /// Tries to stack the grabbedSharedObject on another shared object.
 /// The grabbedShared object has to be composed of stackable elements and to be brought to front.
 /// The first shared object found under the grabbed shared object has also to be composed of stackable 
 /// elements of the same kind and must be placed at the same location.
 /// </summary>
 /// <param name="grabbedSharedObject">The grabbed shared object.</param>
 /// <param name="stackObject">The stack object.</param>
 /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
 public bool TryToStackOnAnotherSharedObject(SharedObject grabbedSharedObject, out SharedObject stackObject)
 {
     stackObject = null;
     if (!(grabbedSharedObject.GameElements.First() is IStackable))
     {
         return false;
     }
     if (ZOrderListOfSharedObjects.First() != grabbedSharedObject)
     {
         return false;
     }
     foreach (SharedObject sharedObject in ZOrderListOfSharedObjects)
     {
         if (sharedObject.Rectangle.IntersectsWith(grabbedSharedObject.Rectangle) && sharedObject != grabbedSharedObject)
         {
             // sharedObject is the first shared object found under the grabbed one.
             Point centerSharedObject = new Point(sharedObject.Location.X + sharedObject.Rectangle.Width / 2,
                 sharedObject.Location.Y + sharedObject.Rectangle.Height / 2);
             Point centerGrabbedObject = new Point(grabbedSharedObject.Location.X + grabbedSharedObject.Rectangle.Width / 2,
                 grabbedSharedObject.Location.Y + grabbedSharedObject.Rectangle.Height / 2);
             if (centerSharedObject.Equals(centerGrabbedObject) &&
                 sharedObject.GameElements.First() is IStackable &&
                 sharedObject.GameElements.First().GetType() == grabbedSharedObject.GameElements.First().GetType())
             {
                 // stacking is possible:
                 stackObject = sharedObject;
             }
             break;
         }
     }
     if (stackObject != null)
     {
         if (stackObject.GameElements.Count < 2 && stackObject.GameElements.First() is Card)
         {
             // The stack object was a single card. Change its size for a stack of cards:
             stackObject.Rectangle = new Rectangle(stackObject.Rectangle.X, stackObject.Rectangle.Y, DimXStackOfCards, DimYStackOfCards);
             // and apply again magnetic grid:
             stackObject.Rectangle = new Rectangle(GetMagneticLocation(stackObject.Rectangle),stackObject.Rectangle.Size);
         }
         // Stack the elements
         for (int i = grabbedSharedObject.GameElements.Count - 1; i >= 0; i--)
         {
             GameElement gameElement = grabbedSharedObject.GameElements[i];
             stackObject.GameElements.Insert(0, gameElement);
         }
         // Remove the grabbed shared object from the ZList:
         ZOrderListOfSharedObjects.RemoveAt(0);
         return true;
     }
     return false;
 }
Esempio n. 10
0
        /// <summary>
        /// Gathers the cards of sharedObject in the GameElments of gatheringObject.
        /// </summary>
        /// <param name="sharedObject">The shared object.</param>
        /// <param name="gatheringObject">The gathering object.</param>
        public void GatherCards(SharedObject sharedObject, SharedObject gatheringObject)
        {
            if (sharedObject.GameElements.First() is Card && gatheringObject.GameElements.First() is Card)
            {
                if (gatheringObject.GameElements.Count == 1)
                {
                    // The gathering object was a single card. Change its size for a stack of cards:
                    gatheringObject.Rectangle = new Rectangle(gatheringObject.Rectangle.X, gatheringObject.Rectangle.Y, DimXStackOfCards, DimYStackOfCards);
                    // and apply again magnetic grid:
                    gatheringObject.Rectangle = new Rectangle(GetMagneticLocation(gatheringObject.Rectangle), gatheringObject.Rectangle.Size);

                }
                // Transfer the cards:
                try
                {
                    foreach (Card card in sharedObject.GameElements)
                    {
                        gatheringObject.GameElements.Insert(0, card);
                    }
                }
                catch (Exception ex)
                {
                    ScgBroadcastorService.LogError(string.Format("Unexpected exception '{0}' in GameState.GatherCards in foreach loop doing gatheringObject.GameElements.Add(card);", ex.Message), 97);
                    throw;
                }

                // Broadcast the gathering shared object move event:
                StateChangeEventDataType stateChangeEventDataType = new StateChangeEventDataType();
                stateChangeEventDataType.StateChangeEventType = StateChangeEventType.SharedObjectMove;
                stateChangeEventDataType.SharedObjectId = gatheringObject.Id;
                stateChangeEventDataType.NewSharedObjectLocation = gatheringObject.Location;
                stateChangeEventDataType.SharedObjectSize = gatheringObject.Rectangle.Size;
                stateChangeEventDataType.NewSharedObjectPicture = gatheringObject.Picture;
                ScgBroadcastorService.BroadcastStateChange(stateChangeEventDataType, null, null);

                // Remove the source shared object and broadcast the dispose event:
                ZOrderListOfSharedObjects.Remove(sharedObject);
                stateChangeEventDataType.StateChangeEventType = StateChangeEventType.DisposeSharedObject;
                stateChangeEventDataType.SharedObjectId = sharedObject.Id;
                ScgBroadcastorService.BroadcastStateChange(stateChangeEventDataType, null, null);
            }
        }
Esempio n. 11
0
 /// <summary>
 /// Finds the enclosing private area.
 /// </summary>
 /// <param name="enclosedSharedObject">The enclosed shared object.</param>
 /// <returns>null or the enclosing shared object if found.</returns>
 public SharedObject FindEnclosingPrivateArea(SharedObject enclosedSharedObject)
 {
     foreach (var sharedObject in ZOrderListOfSharedObjects)
     {
         if (sharedObject.PrivateOwnerName != null &&
             sharedObject.Rectangle.Contains(enclosedSharedObject.Rectangle))
         {
             return sharedObject;
         }
     }
     return null;
 }
Esempio n. 12
0
 /// <summary>
 /// Creates a private area for the given client.
 /// </summary>
 /// <param name="clientName">Name of the client.</param>
 /// <param name="newSharedObject">if set to <c>true</c> the private area was created; otherwise it was already existing.</param>
 /// <returns>SharedObject.</returns>
 public SharedObject CreatePrivateArea(string clientName, out bool newSharedObject)
 {
     newSharedObject = false;
     var foundSharedObject = FindPrivateArea(clientName);
     if (foundSharedObject == null)
     {
         newSharedObject = true;
         var id = GetFreeId();
         var theNewSharedObject = new SharedObject(ZOrderListOfSharedObjects, id,
             new Rectangle(3, 3, 180, 100), clientName, new List<GameElement>(new[] {new GameElement("wood")}));
         ZOrderListOfSharedObjects.Insert(id, theNewSharedObject);
         theNewSharedObject.BringToFront();
         return theNewSharedObject;
     }
     return foundSharedObject;
 }
        /// <summary>
        /// Notifies the server command.
        /// (Will be remotely called by the clients)
        /// </summary>
        /// <param name="clientCommandData">The client command data.</param>
        public void NotifyServerCmd(ClientCommandDataType clientCommandData)
        {
            // Handle the received mouseEventData and update the State of the Shared Card Game:
            switch (clientCommandData.ClientCommandType)
            {
                case ClientCommandType.LeavingCmd:
                    lock (ClientsLocker)
                    {
                        LogInfo(
                            string.Format("NotifyServerCmd (LeavingCmd, clientCommandData.ClientName = '{0}')",
                                clientCommandData.ClientName), 10);
                        Client leavingClient;
                        var foundTheClient = Clients.TryGetValue(clientCommandData.ClientName, out leavingClient);
                        if (foundTheClient)
                        {
                            // Free a possible grabbed object by the leaving client:
                            if (leavingClient.GrabbedSharedObject != null)
                            {
                                leavingClient.GrabbedSharedObject.GrabberName = null;
                                leavingClient.GrabbedSharedObject. ContextualMenuOpened = false;
                            }

                            Clients.Remove(leavingClient.Name);
                            LogInfo(string.Format("_clients.Remove(leavingClient.Name = '{0}')", leavingClient.Name), 11);
                            // Remove the private area of the inactive client
                            var removedSharedObjectId = _gameState.RemovePrivateArea(leavingClient.Name);
                            // Note: The removedSharedObjectId should be >= 0
                            if (removedSharedObjectId >= 0)
                            {
                                // Inform other existing clients of the disposed PrivateArea id:
                                foreach (var client in Clients)
                                {
                                    // Prepare StateChangeEventDataType:
                                    var stateChangeEventDataType =
                                        new StateChangeEventDataType();
                                    stateChangeEventDataType.StateChangeEventType =
                                        StateChangeEventType.DisposeSharedObject;
                                    stateChangeEventDataType.SharedObjectId = removedSharedObjectId;
                                    stateChangeEventDataType.PrivateOwnerClientName = leavingClient.Name;
                                    // Send the StateChangeEventDataType to the client:
                                    client.Value.ScgBroadcastorCallBack.BroadcastToClient(
                                        stateChangeEventDataType);
                                    LogInfo(
                                        string.Format(
                                            "BroadcastToClient'{0}'(DisposeSharedObject, removedSharedObjectId = '{1}')",
                                            client.Value.Name, removedSharedObjectId), 12);
                                }
                            }
                        }
                    }
                    break;
                case ClientCommandType.GatheringCmd:
                    lock (GameStateLocker)
                    {
                        Rectangle gatheringRectangle = clientCommandData.TargetRectangle;
                        LogInfo(string.Format("NotifyServerCmd (GatheringCmd, clientCommandData.ClientName = '{0} gatheringRectangle = [Location={1},Size={2}]')",
                            clientCommandData.ClientName, gatheringRectangle.Location, gatheringRectangle.Size), 20);
                        try
                        {
                            _gameState.GatherCards(gatheringRectangle);
                        }
                        catch (Exception ex)
                        {
                            LogError(string.Format("Unexpected exception '{0}' raised in NotifyServerCmd(GatheringCmd) handling when calling _gameState.GatherCards(gatheringRectangle)", ex.Message), 98);
                            throw;
                        }

                    }
                    break;
                case ClientCommandType.RequestDealingParametersCmd:
                    lock (GameStateLocker)
                    {
                        SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId);
                        LogInfo(
                            string.Format(
                                "NotifyServerCmd (RequestDealingParametersCmd, clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')",
                                clientCommandData.ClientName, clientCommandData.SharedObjectId), 31);
                        if (stackOfCards != null && stackOfCards.GameElements.First() is Card && stackOfCards.GrabberName == null)
                        {
                            Client theClient;
                            bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName,
                                out theClient);
                            if (foundTheClient && theClient != null)
                            {
                                // Do the specific stuff here:

                                // Prepare and send state change for the clicked stack of cards shared object:
                                StateChangeEventDataType stateChange = new StateChangeEventDataType();
                                stateChange.StateChangeEventType = StateChangeEventType.OpenDealingParametersDialog;
                                stateChange.SharedObjectId = stackOfCards.Id;
                                stateChange.GrabbingClientName = clientCommandData.ClientName;
                                stateChange.ReleasingClientName = null;
                                stateChange.PrivateOwnerClientName = null;
                                stateChange.DealingClockwise = DealingClockwise;
                                stateChange.NumberOfCardsToDeal = NumberOfCardsToDeal;
                                LogInfo(
                                    "Broadcasting state change (OpenDealingParametersDialog) for the clicked shared object (stackOfCard)",
                                    95);
                                BroadcastStateChange(stateChange, null, null);

                                // Prepare and send state change for the clicked stack of cards shared object:
                                stateChange = new StateChangeEventDataType();
                                stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove;
                                stateChange.SharedObjectId = stackOfCards.Id;
                                stateChange.NewSharedObjectPicture = stackOfCards.Picture;
                                stateChange.NewSharedObjectLocation = stackOfCards.Location;
                                stateChange.SharedObjectSize = stackOfCards.Rectangle.Size;
                                stateChange.GrabbingClientName = clientCommandData.ClientName;
                                stateChange.ReleasingClientName = null;
                                stateChange.PrivateOwnerClientName = null;
                                LogInfo(
                                    "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)",
                                    95);
                                BroadcastStateChange(stateChange, null, null);

                                // The stackOfCards is again grabbed:
                                stackOfCards.GrabberName = clientCommandData.ClientName;
                                stackOfCards.ContextualMenuOpened = false;
                                theClient.GrabbedSharedObject = stackOfCards;
                            }
                        }
                    }
                    break;
                case ClientCommandType.CancelDealingParametersDialogCmd:
                    lock (GameStateLocker)
                    {
                        SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId);
                        LogInfo(
                            string.Format(
                                "NotifyServerCmd (CancelDealingParametersDialogCmdl, clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')",
                                clientCommandData.ClientName, clientCommandData.SharedObjectId), 31);
                        if (stackOfCards != null && stackOfCards.GameElements.First() is Card)
                        {
                            Client theClient;
                            bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName,
                                out theClient);
                            if (foundTheClient && theClient != null)
                            {
                                // Do the specific stuff here:

                                // Prepare and send state change for the clicked stack of cards shared object:
                                StateChangeEventDataType stateChange = new StateChangeEventDataType();
                                stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove;
                                stateChange.SharedObjectId = stackOfCards.Id;
                                stateChange.NewSharedObjectPicture = stackOfCards.Picture;
                                stateChange.NewSharedObjectLocation = stackOfCards.Location;
                                stateChange.SharedObjectSize = stackOfCards.Rectangle.Size;
                                stateChange.GrabbingClientName = null;
                                stateChange.ReleasingClientName = clientCommandData.ClientName;
                                stateChange.PrivateOwnerClientName = null;
                                LogInfo(
                                    "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)",
                                    95);
                                BroadcastStateChange(stateChange, null, null);

                                // The stackOfCards is no more grabbed:
                                stackOfCards.GrabberName = null;
                                stackOfCards.ContextualMenuOpened = false;
                                theClient.GrabbedSharedObject = null;
                            }
                        }
                    }
                    break;
                case ClientCommandType.ExtractFirstCardCmd:
                    lock (GameStateLocker)
                    {
                        SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId);
                        LogInfo(
                            string.Format("NotifyServerCmd (ExtractFirstCardCmd, clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')",
                                clientCommandData.ClientName, clientCommandData.SharedObjectId), 31);
                        if (stackOfCards != null && stackOfCards.GameElements.First() is Card)
                        {
                            // Check that no card is already present at the extraction location;
                            Point extractLocation = new Point(stackOfCards.Location.X + stackOfCards.Rectangle.Width / 2 - ScgGameState.MagneticGridStep - ScgGameState.DimXCard,
                                stackOfCards.Location.Y + stackOfCards.Rectangle.Height / 2 - ScgGameState.MagneticGridStep - ScgGameState.DimYCard);
                            // Vérifier l'extract location !!!

                            SharedObject otherObject =
                                _gameState.GetSharedObjectAt(extractLocation);
                            if (!(otherObject != null &&
                                  otherObject.GameElements.First() is Card &&
                                  otherObject.Location.Equals(extractLocation)))
                            {
                                LogInfo(string.Format("OK, the extraction Location is free ! clientCommandData.ClientName='{0}'", clientCommandData.ClientName), 97);
                                Client theClient;
                                bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName,
                                    out theClient);
                                if (foundTheClient && theClient != null)
                                {
                                    // Extract the top most card and create a new shared object:
                                    Card extractedCard = (Card) stackOfCards.GameElements.First();
                                    stackOfCards.GameElements.RemoveAt(0);

                                    // Create a new shared object for the extracted card:
                                    SharedObject newSharedObject =
                                        new SharedObject(_gameState.ZOrderListOfSharedObjects,
                                            _gameState.GetFreeId(),
                                            new Rectangle(
                                                new Point(
                                                    stackOfCards.Location.X -
                                                    ScgGameState.MagneticGridStep,
                                                    stackOfCards.Location.Y -
                                                    ScgGameState.MagneticGridStep),
                                                new Size(ScgGameState.DimXCard, ScgGameState.DimYCard)),
                                            null, new List<GameElement>());
                                    newSharedObject.GameElements.Add(extractedCard);
                                    if (stackOfCards.GameElements.Count == 1)
                                    {
                                        // Resize the clickedSharedObject which owns now a single card:
                                        stackOfCards.Rectangle =
                                            new Rectangle(stackOfCards.Location,
                                                new Size(ScgGameState.DimXCard, ScgGameState.DimYCard));
                                        // Apply magnetic grid:
                                        stackOfCards.Rectangle =
                                            new Rectangle(
                                                ScgGameState.GetMagneticLocation(
                                                    stackOfCards.Rectangle),
                                                stackOfCards.Rectangle.Size);
                                    }

                                    // The stackOfCards is no more grabbed:
                                    stackOfCards.GrabberName = null;
                                    stackOfCards.ContextualMenuOpened = false;

                                    // Prepare and send state change for the clicked shared object:
                                    StateChangeEventDataType stateChange = new StateChangeEventDataType();
                                    stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove;
                                    stateChange.SharedObjectId = stackOfCards.Id;
                                    stateChange.NewSharedObjectPicture = stackOfCards.Picture;
                                    stateChange.NewSharedObjectLocation = stackOfCards.Location;
                                    stateChange.SharedObjectSize = stackOfCards.Rectangle.Size;
                                    stateChange.GrabbingClientName = null;
                                    stateChange.ReleasingClientName = clientCommandData.ClientName;
                                    stateChange.PrivateOwnerClientName = null;
                                    LogInfo(
                                        "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)",
                                        95);
                                    BroadcastStateChange(stateChange, null, null);

                                    // Add the new Shared object to the ZOrderList:
                                    _gameState.ZOrderListOfSharedObjects.Insert(0, newSharedObject);

                                    // Prepare sending the state change for the new Shared object:
                                    stateChange.StateChangeEventType =
                                        StateChangeEventType.NewSharedObject;
                                    stateChange.SharedObjectId = newSharedObject.Id;
                                    stateChange.NewSharedObjectPicture =
                                        newSharedObject.Picture;
                                    stateChange.NewSharedObjectLocation =
                                        newSharedObject.Location;
                                    stateChange.SharedObjectSize =
                                        newSharedObject.Rectangle.Size;
                                    stateChange.GrabbingClientName = null;
                                    stateChange.PrivateOwnerClientName = null;
                                    LogInfo(
                                        string.Format("Broadcasting state change (NewSharedObject) for the extracted card shared object (newSharedObject.Id ={0})",newSharedObject.Id),95);
                                    BroadcastStateChange(stateChange, null, null);

                                    // Mark the new object as not grabbed:
                                    newSharedObject.GrabberName = null;
                                    theClient.GrabbedSharedObject = null;
                                    newSharedObject.BringToFront();
                                }
                            }
                            else
                            {
                                LogWarning(string.Format("NOT OK, the extraction Location is not free ! clientCommandData.ClientName='{0}'", clientCommandData.ClientName), 97);
                            }
                        }
                    }
                    break;
                case ClientCommandType.CountCardsCmd:
                    lock (GameStateLocker)
                    {
                        SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId);
                        LogInfo(
                            string.Format(
                                "NotifyServerCmd (CountCardsCmd clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')",
                                clientCommandData.ClientName, clientCommandData.SharedObjectId), 31);
                        if (stackOfCards != null && stackOfCards.GameElements.First() is Card)
                        {
                            Client theClient;
                                bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName,
                                    out theClient);
                            if (foundTheClient && theClient != null)
                            {
                                // Do the specific stuff here:
                                StateChangeEventDataType stateChange = new StateChangeEventDataType();
                                stateChange.StateChangeEventType = StateChangeEventType.ShowMessage;
                                stateChange.SharedObjectId = stackOfCards.Id;
                                stateChange.RecipientClientName = clientCommandData.ClientName;
                                stateChange.ToEveryone = false;
                                stateChange.MessageToDisplay = string.Format("This deck includes {0} cards.", stackOfCards.GameElements.Count);
                                stateChange.MessageBoxTitle = "Deck Card Count";
                                LogInfo(
                                    "Broadcasting state change (ShowMessage) for the clicked shared object (stackOfCard)",
                                    95);
                                BroadcastStateChange(stateChange, null, null);

                                // Prepare and send state change for the clicked stack of cards shared object:
                                stateChange = new StateChangeEventDataType();
                                stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove;
                                stateChange.SharedObjectId = stackOfCards.Id;
                                stateChange.NewSharedObjectPicture = stackOfCards.Picture;
                                stateChange.NewSharedObjectLocation = stackOfCards.Location;
                                stateChange.SharedObjectSize = stackOfCards.Rectangle.Size;
                                stateChange.GrabbingClientName = null;
                                stateChange.ReleasingClientName = clientCommandData.ClientName;
                                stateChange.PrivateOwnerClientName = null;
                                LogInfo(
                                    "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)",
                                    95);
                                BroadcastStateChange(stateChange, null, null);

                                // The stackOfCards is no more grabbed:
                                stackOfCards.GrabberName = null;
                                stackOfCards.ContextualMenuOpened = false;
                                theClient.GrabbedSharedObject = null;
                            }
                        }
                    }
                    break;
                case ClientCommandType.DealCmd:
                    lock (GameStateLocker)
                    {
                        SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId);
                        LogInfo(
                            string.Format(
                                "NotifyServerCmd (DealCmd, clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')",
                                clientCommandData.ClientName, clientCommandData.SharedObjectId), 31);
                        if (stackOfCards != null && stackOfCards.GameElements.First() is Card)
                        {
                            Client theDealerClient;
                                bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName,
                                    out theDealerClient);
                            if (foundTheClient && theDealerClient != null)
                            {
                                // Do the specific stuff here:
                                DealingClockwise = clientCommandData.DealingClockwise;
                                NumberOfCardsToDeal = clientCommandData.NumberOfCardsToDeal;

                                //DO THE DEALING: TO BE COMPLETED

                                // Code issued from ExtractFirstCard as reference
                                // Extract the top most card and create a new shared object:
                                Card extractedCard = (Card)stackOfCards.GameElements.First();
                                stackOfCards.GameElements.RemoveAt(0);

                                // Create a new shared object for the extracted card:
                                SharedObject newSharedObject =
                                    new SharedObject(_gameState.ZOrderListOfSharedObjects,
                                        _gameState.GetFreeId(),
                                        new Rectangle(
                                            new Point(
                                                stackOfCards.Location.X -
                                                ScgGameState.MagneticGridStep,
                                                stackOfCards.Location.Y -
                                                ScgGameState.MagneticGridStep),
                                            new Size(ScgGameState.DimXCard, ScgGameState.DimYCard)),
                                        null, new List<GameElement>());
                                newSharedObject.GameElements.Add(extractedCard);
                                if (stackOfCards.GameElements.Count == 1)
                                {
                                    // Resize the clickedSharedObject which owns now a single card:
                                    stackOfCards.Rectangle =
                                        new Rectangle(stackOfCards.Location,
                                            new Size(ScgGameState.DimXCard, ScgGameState.DimYCard));
                                    // Apply magnetic grid:
                                    stackOfCards.Rectangle =
                                        new Rectangle(
                                            ScgGameState.GetMagneticLocation(
                                                stackOfCards.Rectangle),
                                            stackOfCards.Rectangle.Size);
                                }

                                // The stackOfCards is no more grabbed:
                                stackOfCards.GrabberName = null;
                                stackOfCards.ContextualMenuOpened = false;

                                // Prepare and send state change for the clicked shared object:
                                StateChangeEventDataType stateChange = new StateChangeEventDataType();
                                stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove;
                                stateChange.SharedObjectId = stackOfCards.Id;
                                stateChange.NewSharedObjectPicture = stackOfCards.Picture;
                                stateChange.NewSharedObjectLocation = stackOfCards.Location;
                                stateChange.SharedObjectSize = stackOfCards.Rectangle.Size;
                                stateChange.GrabbingClientName = null;
                                stateChange.ReleasingClientName = clientCommandData.ClientName;
                                stateChange.PrivateOwnerClientName = null;
                                LogInfo(
                                    "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)",
                                    95);
                                BroadcastStateChange(stateChange, null, null);

                                // Add the new Shared object to the ZOrderList:
                                _gameState.ZOrderListOfSharedObjects.Insert(0, newSharedObject);

                                // Prepare sending the state change for the new Shared object:
                                stateChange.StateChangeEventType =
                                    StateChangeEventType.NewSharedObject;
                                stateChange.SharedObjectId = newSharedObject.Id;
                                stateChange.NewSharedObjectPicture =
                                    newSharedObject.Picture;
                                stateChange.NewSharedObjectLocation =
                                    newSharedObject.Location;
                                stateChange.SharedObjectSize =
                                    newSharedObject.Rectangle.Size;
                                stateChange.GrabbingClientName = null;
                                stateChange.PrivateOwnerClientName = null;
                                LogInfo(
                                    string.Format("Broadcasting state change (NewSharedObject) for the extracted card shared object (newSharedObject.Id ={0})", newSharedObject.Id), 95);
                                BroadcastStateChange(stateChange, null, null);

                                // Prepare and send state change for the clicked stack of cards shared object:
                                stateChange = new StateChangeEventDataType();
                                stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove;
                                stateChange.SharedObjectId = stackOfCards.Id;
                                stateChange.NewSharedObjectPicture = stackOfCards.Picture;
                                stateChange.NewSharedObjectLocation = stackOfCards.Location;
                                stateChange.SharedObjectSize = stackOfCards.Rectangle.Size;
                                stateChange.GrabbingClientName = null;
                                stateChange.ReleasingClientName = clientCommandData.ClientName;
                                stateChange.PrivateOwnerClientName = null;
                                LogInfo(
                                    "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)",
                                    95);
                                BroadcastStateChange(stateChange, null, null);

                                // The stackOfCards is no more grabbed:
                                stackOfCards.GrabberName = null;
                                stackOfCards.ContextualMenuOpened = false;
                                theDealerClient.GrabbedSharedObject = null;
                            }
                        }
                    }
                    break;
                case ClientCommandType.ShuffleUpCmd:
                    lock (GameStateLocker)
                    {
                        SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId);
                        LogInfo(
                            string.Format(
                                "NotifyServerCmd (ShuffleUpCmd, clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')",
                                clientCommandData.ClientName, clientCommandData.SharedObjectId), 31);
                        if (stackOfCards != null && stackOfCards.GameElements.First() is Card)
                        {
                            Client theClient;
                                bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName,
                                    out theClient);
                            if (foundTheClient && theClient != null)
                            {
                                // Do the specific stuff here:

                                stackOfCards.Shuffle();

                                // Prepare and send state change for the clicked stack of cards shared object:
                                StateChangeEventDataType stateChange = new StateChangeEventDataType();
                                stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove;
                                stateChange.SharedObjectId = stackOfCards.Id;
                                stateChange.NewSharedObjectPicture = stackOfCards.Picture;
                                stateChange.NewSharedObjectLocation = stackOfCards.Location;
                                stateChange.SharedObjectSize = stackOfCards.Rectangle.Size;
                                stateChange.GrabbingClientName = null;
                                stateChange.ReleasingClientName = clientCommandData.ClientName;
                                stateChange.PrivateOwnerClientName = null;
                                LogInfo(
                                    "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)",
                                    95);
                                BroadcastStateChange(stateChange, null, null);

                                // The stackOfCards is no more grabbed:
                                stackOfCards.GrabberName = null;
                                stackOfCards.ContextualMenuOpened = false;
                                theClient.GrabbedSharedObject = null;
                            }
                        }
                    }
                    break;
                case ClientCommandType.ContextualMenuClosedCmd:
                    lock (GameStateLocker)
                    {
                        SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId);
                        LogInfo(
                            string.Format(
                                "NotifyServerCmd (ContextualMenuClosedCmd, clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')",
                                clientCommandData.ClientName, clientCommandData.SharedObjectId), 31);
                        if (stackOfCards != null && stackOfCards.GameElements.First() is Card)
                        {
                            Client theClient;
                            bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName,
                                out theClient);
                            if (foundTheClient && theClient != null &&
                                theClient.GrabbedSharedObject != null &&
                                theClient.GrabbedSharedObject.Id == stackOfCards.Id)
                            {
                                // Do the specific stuff here:

                                // Nothing to do.

                                // Prepare and send state change for the clicked stack of cards shared object:
                                StateChangeEventDataType stateChange = new StateChangeEventDataType();
                                stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove;
                                stateChange.SharedObjectId = stackOfCards.Id;
                                stateChange.NewSharedObjectPicture = stackOfCards.Picture;
                                stateChange.NewSharedObjectLocation = stackOfCards.Location;
                                stateChange.SharedObjectSize = stackOfCards.Rectangle.Size;
                                stateChange.GrabbingClientName = null;
                                stateChange.ReleasingClientName = clientCommandData.ClientName;
                                stateChange.PrivateOwnerClientName = null;
                                LogInfo(
                                    "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)",
                                    95);
                                BroadcastStateChange(stateChange, null, null);

                                // The stackOfCards is no more grabbed:
                                stackOfCards.GrabberName = null;
                                stackOfCards.ContextualMenuOpened = false;
                                theClient.GrabbedSharedObject = null;
                            }
                        }
                    }
                    break;
            }
        }
        /// <summary>
        /// Broadcasts the state change to all clients.
        /// </summary>
        /// <param name="stateChangeEventDataType">Type of the state change event data.</param>
        /// <param name="enclosingPrivateArea">The enclosing private area.</param>
        /// <param name="otherFaceCardPicture">The other face card picture.</param>
        public void BroadcastStateChange(StateChangeEventDataType stateChangeEventDataType, SharedObject enclosingPrivateArea, string otherFaceCardPicture)
        {
            // if required, Broadcast The state change to each client:
            if (stateChangeEventDataType.StateChangeEventType != StateChangeEventType.NoStateChange)
            {
                lock (ClientsLocker)
                {
                    var inactiveClients = new List<string>();
                    foreach (var client in Clients)
                    {
                        try
                        {
                            // Change the NewSharedObjectPicture information for card on private area for the PrivateAreaOwner client only:
                            if (stateChangeEventDataType.StateChangeEventType == StateChangeEventType.SharedObjectMove
                                && enclosingPrivateArea != null
                                && otherFaceCardPicture != null
                                && client.Value.Name == enclosingPrivateArea.PrivateOwnerName)
                            {
                                var savedPicture = stateChangeEventDataType.NewSharedObjectPicture;
                                stateChangeEventDataType.NewSharedObjectPicture = otherFaceCardPicture;
                                (client.Value).ScgBroadcastorCallBack.BroadcastToClient(stateChangeEventDataType);
                                stateChangeEventDataType.NewSharedObjectPicture = savedPicture;
                            }
                            else
                            {
                                (client.Value).ScgBroadcastorCallBack.BroadcastToClient(stateChangeEventDataType);
                            }
                        }
                        catch (Exception ex)
                        {
                            LogError(string.Format("Exception '{0}' raised in ScgBroadcastorService.BroadcastStateChange when calling (client.Value).ScgBroadcastorCallBack.BroadcastToClient(). client.Value.Name = '{1}')", ex.Message , client.Value.Name), 99);
                            inactiveClients.Add(client.Key);
                        }
                    }
                    if (inactiveClients.Count > 0)
                    {
                        foreach (var inactiveClient in inactiveClients)
                        {
                            // Search the leavingClient (Client) corresponding to the inactiveClient (name):
                            Client leavingClient;
                            var foundTheClient = Clients.TryGetValue(inactiveClient, out leavingClient);
                            if (foundTheClient)
                            {
                                // Free a possible grabbed object by the leaving client:
                                if (leavingClient.GrabbedSharedObject != null)
                                {
                                    leavingClient.GrabbedSharedObject.GrabberName = null;
                                    leavingClient.GrabbedSharedObject.ContextualMenuOpened = false;
                                }
                            }

                            // Remove the inactive client from the clients list:
                            Clients.Remove(inactiveClient);
                            LogInfo(string.Format("_clients.Remove(inactiveClient = '{0}')", inactiveClient), 13);

                            // Remove the private area of the inactive client
                            var removedSharedObjectId = _gameState.RemovePrivateArea(inactiveClient);
                            // Note: The removedSharedObjectId should be >= 0
                            if (removedSharedObjectId >= 0)
                            {
                                // Inform other existing clients of the disposed PrivateArea id:
                                foreach (var client in Clients)
                                {
                                    // Prepare StateChangeEventDataType:
                                    var aStateChangeEventDataType =
                                        new StateChangeEventDataType();
                                    aStateChangeEventDataType.StateChangeEventType =
                                        StateChangeEventType.DisposeSharedObject;
                                    aStateChangeEventDataType.SharedObjectId = removedSharedObjectId;
                                    stateChangeEventDataType.PrivateOwnerClientName = inactiveClient;
                                    // Send the StateChangeEventDataType to the client:
                                    client.Value.ScgBroadcastorCallBack.BroadcastToClient(
                                        aStateChangeEventDataType);
                                    LogInfo(
                                        string.Format(
                                            "BroadcastToClient'{0}'(DisposeSharedObject, removedSharedObjectId = '{1}')",
                                            client.Value.Name, removedSharedObjectId), 14);
                                }
                            }
                        }
                    }
                }
            }
        }