private void OnTriggerEnter(Collider collider)
        {
            CueController cueController = collider.gameObject.transform.parent.GetComponent <CueController>();

            // confirm if the ball is actually hit by a ball
            if (cueController != null)
            {
                // ball is hit by the cue
                if (_ballType == CueBallType.White)
                {
                    // notify that the ball is hit
                    EventManager.Notify(typeof(CueBallActionEvent).Name, this, new CueBallActionEvent()
                    {
                        State = CueBallActionEvent.States.Striked
                    });

                    // set the current state
                    _currState = CueBallActionEvent.States.Striked;

                    // whats the force gathered to hit
                    float forceGatheredToHit = cueController.ForceGatheredToHit;

                    // set the ball rolling with gathered force
                    OnStriked(forceGatheredToHit);
                }
            }
        }
        /// <summary>
        /// this function is been called whenever there is a reset of p
        /// </summary>
        public void PlaceBallInInitialPos()
        {
            // place it a bit from top so that balls dont get placed within each other
            transform.position = new Vector3(_initialPos.x, _initialPos.y + 0.2f, _initialPos.z);

            // this flag resets after the completion of one complete round,
            // since the function is reused, and whenever there is a reset, it is safe to reset the flag here
            IsPocketedInPrevTurn = false;

            _currState = CueBallActionEvent.States.Placing;
            GameManager.Instance.NumOfBallsStriked = 0;
        }
        private void OnCueBallEvent(object sender, IGameEvent gameEvent)
        {
            CueBallActionEvent actionEvent = (CueBallActionEvent)gameEvent;

            switch (actionEvent.State)
            {
            case CueBallActionEvent.States.Stationary:
            {
                // change the curr state to default now
                _currState = CueBallActionEvent.States.Default;
            }
            break;
            }
        }
        /// <summary>
        /// ball goes through various lifecycle from default, placing to the coming back to stationary state after been striked
        /// </summary>
        private void FixedUpdate()
        {
            Rigidbody rigidbody = gameObject.GetComponent <Rigidbody>();

            if ((_currState == CueBallActionEvent.States.Placing) && rigidbody.IsSleeping())
            {
                _currState = CueBallActionEvent.States.Default;
            }
            else if ((_currState == CueBallActionEvent.States.Default) && (!rigidbody.IsSleeping()))
            {
                // number of balls striked in Play mode
                if (GameManager.Instance.CurrGameState == GameManager.GameState.Play)
                {
                    GameManager.Instance.NumOfBallsStriked++;
                }

                _currState = CueBallActionEvent.States.Striked;
            }
            else if ((_currState == CueBallActionEvent.States.Striked) && (!rigidbody.IsSleeping()))
            {
                _currState = CueBallActionEvent.States.InMotion;
            }
            else if ((_currState == CueBallActionEvent.States.Striked) && (rigidbody.IsSleeping()))
            {
                _currState = CueBallActionEvent.States.InMotion;
            }
            else if ((_currState == CueBallActionEvent.States.InMotion) && rigidbody.IsSleeping())
            {
                // ball is come to rest after been striked, check for the status
                GameManager.Instance.ReadyForNextRound();

                _currState = CueBallActionEvent.States.Stationary;
            }
            else
            {
                // do nothing
            }
        }