/// <summary>
        /// Return: my_payout_for_single_bet_str
        /// Return a string that is to be used to to show how much the payout will be for a single bet.  Decimal places will only be shown if 
        /// non-zero e.g. "Pays £3",  "Pays £1.50"
        /// 
        /// Notes / Requirement
        /// The function uses generates the string that it returns from 'p_pays_amount'.  If this value is not set this function will return an
        /// empty string.
        /// </summary>
        public String f_get_payout_string(enum_betting_stage stage_index, int a_player_index)
        {
            // This is the string that will be returned.
            String my_payout_for_single_bet_str = "NOT SET YET";
            double my_previous_bet_payout_if_wins = 0;
                
            // Determine the odds for this hand at this stage.  
            // If zero, no bets could have been placed so return with empty payout string
            double my_offered_odds = _offered_odds[(int)stage_index];
            if (my_offered_odds == 0){
                return "";
            }

            // Determine the bets placed on this hand at this stage.  
            // If zero, no bets could have been placed so return with empty payout string
            double my_bet_double = _players_bets[(int)stage_index, 0];
            if (my_bet_double == 0){
                return "";
            }
            
            // If code gets here a bet must have been made so calculate the payout.
            // Note if the odd are -ve this implies odds are of format 1:n  instead of n:1 
            // (i.e. a favourite that has more chance of winning than of losing.
            // Display Payout for single bet.
            double my_payout_for_single_bet = 0;

            if (my_offered_odds > 0){
                my_previous_bet_payout_if_wins = (my_bet_double * my_offered_odds) + my_bet_double;
            }else{
                my_payout_for_single_bet = my_offered_odds * -1;
                my_payout_for_single_bet = 1 + (1 / my_payout_for_single_bet);
                my_previous_bet_payout_if_wins = (my_bet_double * my_payout_for_single_bet) ;
            }

            // Now that we have calucalted payout, format text to nice human friendly presentation
            string my_stage_str = f_get_stage_as_string(stage_index);

            // Calculate the payout for a single bet taking into consideration -ve odds implies favourite
            


            // Only show two decimal places if needed (i.e. if hand is a favourite and you get let that
            // £1 payout for each £1 bet. 
            // Note my_payout_for_single_bet will have decimal places between 1 and 2 
            if (my_payout_for_single_bet > 1 && my_payout_for_single_bet < 2)
            {
                my_payout_for_single_bet_str = String.Format("£{0:#0.00}", my_previous_bet_payout_if_wins);
            }
            else
            {
                my_payout_for_single_bet_str = String.Format("£{0:#0}", my_previous_bet_payout_if_wins);

            }



            
            return my_payout_for_single_bet_str;
            
        }
    /// Context / Background reading
    /// ----------------------------
    /// You must understand the following before understanding this function
    /// + What the HedgeEmHandStageInfo class is and what its purpose is.
    /// 
    /// History
    /// -----------
    /// Original Author: Simon Hewins Jul 2014
    /// Last edit:       Simon Hewins Aug 2014
    /// 
    /// Description
    /// -----------
    /// 
    /// Gets a LIST of HedgeEmHandStageInfo objects for any given hand (index) at any given stage.
    /// </summary>
    /// <param name="a_enum_game_state"></param>
    /// <param name="a_hand_index"></param>
    /// <returns></returns>
    public double f_get_total_previous_bets_for_stage_and_hand_player(enum_betting_stage a_enum_betting_stage, int a_hand_index, int a_player_id)
    {
        /// xxx hack until Bet contains player id
        a_player_id = 0;

        List<HedgeEmBet> my_previous_bets_list = new List<HedgeEmBet>();

        HedgeEmBet myHedgeEmBet = null;
        double my_bet_total = -666;

        try
        {
            my_previous_bets_list = (from handsstage_objects in _global_game_state_object.p_recorded_bets
                                     where handsstage_objects.p_enum_betting_stage == a_enum_betting_stage
                         && handsstage_objects.p_hand_index == a_hand_index
                         && handsstage_objects.p_seat_index == a_player_id
                                     select handsstage_objects).ToList();

            my_bet_total = (from handsstage_objects in _global_game_state_object.p_recorded_bets
                            where handsstage_objects.p_enum_betting_stage == a_enum_betting_stage
                && handsstage_objects.p_hand_index == a_hand_index
                && handsstage_objects.p_seat_index == a_player_id
                            select handsstage_objects.p_bet_amount).Sum();

            /*if (my_previous_bets_list.Count > 1)
            {
                String my_err_msg = String.Format("Expected only one 'Bet' for state [{0}], hand [{1}] object got [{1}] ",
                    a_enum_betting_stage.ToString(),
                    a_hand_index,
                    my_previous_bets_list.Count);

                throw new Exception(my_err_msg);
            }*/

            //myHedgeEmBet = my_previous_bets_list[0];

        }
        catch (Exception ex)
        {
            string my_error_popup = "alert('Error in f_get_previous_bets_for_stage_and_hand" + ex.Message.ToString() + "');";
            ClientScript.RegisterClientScriptBlock(this.GetType(), "Alert", my_error_popup, true);
            HedgeEmLogEvent my_log = new HedgeEmLogEvent();
            my_log.p_message = "Exception caught in f_get_hand_stage_info_object_for_stage_and_hand function " + ex.Message;
            my_log.p_method_name = "f_get_hand_stage_info_object_for_stage_and_hand";
            my_log.p_player_id = f_get_player_id();
            my_log.p_game_id = game_id;
            my_log.p_table_id = _table_id;
            log.Error(my_log.ToString());
        }
        return my_bet_total;
    }
        /// <summary>
        /// 
        /// </summary>
        public String f_get_stage_as_string(enum_betting_stage a_betting_stage)
        {

                string my_stage_as_string = "";

                switch (a_betting_stage)
                {
                    case enum_betting_stage.HOLE_BETS:
                       
                        return "Hole";
                        
                    case enum_betting_stage.FLOP_BETS:
                        return "Flop";
                        
                    case enum_betting_stage.TURN_BETS:
                        return "Turn";
                        
                    case enum_betting_stage.NON_BETTING_STAGE:
                        //f_activate_deal_next_button_and_hide_others();
                        break;
                

                
            }
                return my_stage_as_string; 
            
        }
    private enum_game_state f_convert_hedgeem_stage_to_state(enum_betting_stage a_betting_stage)
    {
        enum_game_state my_enum_game_state_HACK = enum_game_state.UNCHANGED;
        switch (a_betting_stage)
        {
            case enum_betting_stage.HOLE_BETS:
                my_enum_game_state_HACK = enum_game_state.STATUS_HOLE;
                break;
            case enum_betting_stage.FLOP_BETS:
                my_enum_game_state_HACK = enum_game_state.STATUS_FLOP;
                break;
            case enum_betting_stage.TURN_BETS:
                my_enum_game_state_HACK = enum_game_state.STATUS_TURN;
                break;

            default:
                break;
        }

        return my_enum_game_state_HACK;
    }
    //#region f_activate_deal_hole_button_and_hide_others
    //private void f_activate_deal_hole_button_and_hide_others()
    //{
    //    /*----- This function only shown Deal Display Random others are invisible------*/
    //    btnDealHole.Visible = true;
    //    btnDealFlop.Visible = false;
    //    btnDealTurn.Visible = false;
    //    btnDealRiver.Visible = false;
    //    btnNextGame.Visible = false;
    //}
    //#endregion

    //#region f_activate_deal_flop_button_and_hide_others
    //private void f_activate_deal_flop_button_and_hide_others()
    //{
    //    /*----- This function only shown Deal Flop others are invisible------*/
    //    btnDealHole.Visible = false;
    //    btnDealFlop.Visible = true;
    //    btnDealTurn.Visible = false;
    //    btnDealRiver.Visible = false;
    //    btnNextGame.Visible = false;
    //    btnLobby.Visible = true;
    //}
    //#endregion

    //#region f_activate_deal_turn_button_and_hide_others
    //private void f_activate_deal_turn_button_and_hide_others()
    //{
    //    /*----- This function only shown Deal Turn others are invisible------*/
    //    btnDealHole.Visible = false;
    //    btnDealFlop.Visible = false;
    //    btnDealTurn.Visible = true;
    //    btnDealRiver.Visible = false;
    //    btnNextGame.Visible = false;
    //    btnLobby.Visible = true;
    //}
    //#endregion Visible_Deal_Turn_Buttons

    //#region f_activate_deal_river_button_and_hide_others
    //private void f_activate_deal_river_button_and_hide_others()
    //{
    //    /*----- This function only shown Deal River others are invisible------*/
    //    btnDealHole.Visible = false;
    //    btnDealFlop.Visible = false;
    //    btnDealTurn.Visible = false;
    //    btnDealRiver.Visible = true;
    //    btnLobby.Visible = true;
    //}
    //#endregion Visible_Deal_River_Buttons

    //#region f_activate_deal_next_button_and_hide_others
    //private void f_activate_deal_next_button_and_hide_others()
    //{
    //    /*----- This function only shown Deal Next others are invisible------*/
    //    btnDealHole.Visible = false;
    //    btnDealFlop.Visible = false;
    //    btnDealTurn.Visible = false;
    //    btnDealRiver.Visible = false;
    //    btnNextGame.Visible = true;
    //}
    //#endregion Visible_Deal_Next_Buttons

    /// Context / Background reading
    /// ----------------------------
    /// You must understand the following before understanding this function
    /// + What the HedgeEmHandStageInfo class is and what its purpose is.
    /// 
    /// History
    /// -----------
    /// Original Author: Simon Hewins Jul 2014
    /// Last edit:       Simon Hewins Aug 2014
    /// 
    /// Description
    /// -----------
    /// 
    /// Gets a LIST of HedgeEmHandStageInfo objects for any given hand (index) at any given stage.
    /// </summary>
    /// <param name="a_enum_game_state"></param>
    /// <param name="a_hand_index"></param>
    /// <returns></returns>
    public List<HedgeEmBet> f_get_previous_bets_for_stage_and_hand_player_list(enum_betting_stage a_enum_betting_stage, int a_hand_index, int a_player_id)
    {
        /// xxx hack until Bet contains player id
        a_player_id = 0;

        List<HedgeEmBet> my_previous_bets_list = new List<HedgeEmBet>();
        try
        {
            my_previous_bets_list = (from handsstage_objects in _global_game_state_object.p_recorded_bets
                                     where handsstage_objects.p_enum_betting_stage == a_enum_betting_stage
                         && handsstage_objects.p_hand_index == a_hand_index
                         && handsstage_objects.p_seat_index == a_player_id
                                     select handsstage_objects).ToList();
        }
        catch (Exception ex)
        {
            string my_error_popup = "alert('Error in f_get_previous_bets_for_stage_and_hand" + ex.Message.ToString() + "');";
            ClientScript.RegisterClientScriptBlock(this.GetType(), "Alert", my_error_popup, true);
            HedgeEmLogEvent my_log = new HedgeEmLogEvent();
            my_log.p_message = "Exception caught in f_get_hand_stage_info_object_for_stage_and_hand function " + ex.Message;
            my_log.p_method_name = "f_get_hand_stage_info_object_for_stage_and_hand";
            my_log.p_player_id = f_get_player_id();
            my_log.p_game_id = game_id;
            my_log.p_table_id = _table_id;
            log.Error(my_log.ToString());
        }
        return my_previous_bets_list;
    }
    DC_bet_acknowledgement f_place_bet(enum_betting_stage a_betting_stage, int a_hand_index, double a_amount)
    {
        // Create a 'log event' object to audit execution
        HedgeEmLogEvent my_log = new HedgeEmLogEvent();
        my_log.p_message = "";
        my_log.p_method_name = "f_place_bet";
        my_log.p_player_id = f_get_player_id();
        my_log.p_game_id = game_id;
        my_log.p_table_id = _table_id;

        // Create a new 'Bet Acknowledgement' object that will be used to Ackknowledge the success (ACK) or failure (NACK) of the placed bet.
        DC_bet_acknowledgement my_ack = null;

        try
        {
            // Log the entry to this method
            my_log.p_message = String.Format("f_place_bet called. Args Stage[{0}], Hand [{1}], Amount[{2}]", a_betting_stage.ToString(), a_hand_index, a_amount);
            log.Debug(my_log.p_message);

            // Call the Hedge'Em Webservices (via helper function) to place the bet.
            string place_bet_endpoint = String.Format("ws_place_bet/{0},{1},{2},{3},{4}",
                                                        _table_id.ToString(),
                                                        a_hand_index.ToString(),
                                                        a_amount.ToString(),
                                                        a_betting_stage.ToString(),
                                                        f_get_player_id().ToString());
            my_ack = (DC_bet_acknowledgement)f_get_object_from_json_call_to_server(place_bet_endpoint, typeof(DC_bet_acknowledgement));

            // Return the Acknowledgement message to the caller to indicate success or failure.
            return my_ack;
        }
        catch (Exception e)
        {
            string strScript = "alert('Unable to place bet. Reason..." + e.Message.ToString() + "');";
            ClientScript.RegisterClientScriptBlock(this.GetType(), "Alert", strScript, true);
            my_log.p_message = "Exception caught in f_place_bet function " + e.Message;

            log.Error(my_log.ToString());
            return my_ack;
        }
    }
    /// Context / Background reading
    /// ----------------------------
    /// You must understand the following before understanding this function
    /// + What the HedgeEmHandStageInfo class is and what its purpose is.
    /// 
    /// History
    /// -----------
    /// Original Author: Simon Hewins Jul 2014
    /// Last edit:       Simon Hewins Aug 2014
    /// 
    /// Description
    /// -----------
    /// 
    /// Gets a LIST of HedgeEmHandStageInfo objects for any given hand (index) at any given stage.
    /// </summary>
    /// <param name="a_enum_game_state"></param>
    /// <param name="a_hand_index"></param>
    /// <returns></returns>
    public double f_get_total_previous_bets_for_stage_and_hand_player(enum_betting_stage a_enum_betting_stage, int a_hand_index, int a_player_id)
    {
        // Create a 'log event' object to audit execution
        HedgeEmLogEvent my_log_event = new HedgeEmLogEvent();
        my_log_event.p_method_name = System.Reflection.MethodBase.GetCurrentMethod().ToString();
        my_log_event.p_message = "Method Entered.";
        my_log_event.p_player_id = p_session_player_id;
        my_log_event.p_table_id = p_session_personal_table_id;
        log.Debug(my_log_event.ToString());

        /// xxx hack until Bet contains player id
        a_player_id = 0;

        List<HedgeEmBet> my_previous_bets_list = new List<HedgeEmBet>();

        double my_bet_total = -666;

        try
        {
            my_previous_bets_list = (from handsstage_objects in _global_game_state_object.p_recorded_bets
                                     where handsstage_objects.p_enum_betting_stage == a_enum_betting_stage
                         && handsstage_objects.p_hand_index == a_hand_index
                         && handsstage_objects.p_seat_index == a_player_id
                                     select handsstage_objects).ToList();

            my_bet_total = (from handsstage_objects in _global_game_state_object.p_recorded_bets
                            where handsstage_objects.p_enum_betting_stage == a_enum_betting_stage
                && handsstage_objects.p_hand_index == a_hand_index
                && handsstage_objects.p_seat_index == a_player_id
                            select handsstage_objects.p_bet_amount).Sum();



        }
        catch (Exception ex)
        {
            string my_error_popup = "Error in f_get_previous_bets_for_stage_and_hand" + ex.Message.ToString();
           // ClientScript.RegisterClientScriptBlock(this.GetType(), "Alert", my_error_popup, true);
            HedgeEmLogEvent my_log = new HedgeEmLogEvent();
            my_log_event.p_message = String.Format("Exception caught [{0}] ", ex.Message);
            my_log.p_player_id = Convert.ToInt32(Session["p_session_player_id"]);
            my_log.p_game_id = game_id;
            my_log.p_table_id = p_session_personal_table_id;
            log.Error(my_log.ToString());
            HedgeemerrorPopup my_popup_message = new HedgeemerrorPopup();
            my_popup_message.p_detailed_message_str = "";
            my_popup_message.p_is_visible = false;

            //ClientScript.RegisterClientScriptBlock(this.GetType(), "Alert", my_error_popup, true);
            my_popup_message.p_detailed_message_str = my_error_popup;
            my_popup_message.p_is_visible = true;
            Place_Holder_Popup_Message.Controls.Add(my_popup_message);
        }
        return my_bet_total;
    }
    DC_bet_acknowledgement f_place_bet(enum_betting_stage a_betting_stage, int a_hand_index, double a_amount)
    {
        // Create a 'log event' object to audit execution
        HedgeEmLogEvent my_log_event = new HedgeEmLogEvent();
        my_log_event.p_method_name = System.Reflection.MethodBase.GetCurrentMethod().ToString();
        my_log_event.p_message = "Method Entered.";
        my_log_event.p_player_id = p_session_player_id;
        my_log_event.p_table_id = p_session_personal_table_id;
        log.Debug(my_log_event.ToString());
        my_log_event.p_game_id = game_id;
        
        // Create a new 'Bet Acknowledgement' object that will be used to Ackknowledge the success (ACK) or failure (NACK) of the placed bet.
        DC_bet_acknowledgement my_ack = null;

        try
        {
            // Log the entry to this method
            my_log_event.p_message = String.Format("f_place_bet called. Args Stage[{0}], Hand [{1}], Amount[{2}]", a_betting_stage.ToString(), a_hand_index, a_amount);
            log.Debug(my_log_event.p_message);

            // Call the Hedge'Em Webservices (via helper function) to place the bet.
            string place_bet_endpoint = String.Format("ws_place_bet/{0},{1},{2},{3},{4}",
                                                        p_session_personal_table_id.ToString(),
                                                        a_hand_index.ToString(),
                                                        a_amount.ToString(),
                                                        a_betting_stage.ToString(),
                                                        Convert.ToInt32(Session["p_session_player_id"]).ToString());
            my_ack = (DC_bet_acknowledgement)f_get_object_from_json_call_to_server(place_bet_endpoint, typeof(DC_bet_acknowledgement));

            // Return the Acknowledgement message to the caller to indicate success or failure.
            return my_ack;
        }
        catch (Exception e)
        {
            string strScript = "Unable to place bet. Reason..." + e.Message.ToString();
           // ClientScript.RegisterClientScriptBlock(this.GetType(), "Alert", strScript, true);
            HedgeemerrorPopup my_popup_message = new HedgeemerrorPopup();
            my_popup_message.p_detailed_message_str = "";
            my_popup_message.p_is_visible = false;

            //ClientScript.RegisterClientScriptBlock(this.GetType(), "Alert", my_error_popup, true);
            my_popup_message.p_detailed_message_str = strScript;
            my_popup_message.p_is_visible = true;
            Place_Holder_Popup_Message.Controls.Add(my_popup_message);
            my_log_event.p_message = "Exception caught in f_place_bet function " + e.Message;

            log.Error(my_log_event.ToString());
            return my_ack;
        }
    }