// process all endgame related events
void multi_endgame_process()
{
	if ( Multi_endgame_processing )
		return;

	Multi_endgame_processing = 1;

	// check to see if we need to be warping out (strange transition possibilities)
	multi_endgame_check_for_warpout();
	
	// if we're the server of the game
	if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
		// if we're not waiting for clients to leave, do nothing
		if(!Multi_endgame_server_waiting){
			Multi_endgame_processing = 0;
			return;
		}

		// if a popup is already active, do nothing		
		if(popup_active()){
			Multi_endgame_processing = 0;
			return;
		}

		// otherwise popup until things are hunky-dory
		if(!multi_endgame_server_ok_to_leave()){
			if(Game_mode & GM_STANDALONE_SERVER){
				while(!multi_endgame_server_ok_to_leave()){
					// run networking, etc.
					game_set_frametime(-1);
					game_do_state_common(gameseq_get_state());
				}
			} else {
				popup_till_condition( multi_endgame_server_ok_to_leave , XSTR("&Cancel",645), XSTR("Waiting for clients to disconnect",646));		
			}
		}

		// mark myself as not waiting and get out
		multi_endgame_cleanup();	
	} else {
		// if we're not waiting to leave the game, do nothing
		if(!Multi_endgame_client_waiting){
			Multi_endgame_processing = 0;
			return;
		}

		// otherwise, check to see if there is a popup active
		if(popup_active()){
			Multi_endgame_processing = 0;
			return;
		}

		// if not, then we are good to leave		
		multi_endgame_cleanup();
	}

	Multi_endgame_processing = 0;
}
// pause do frame - will handle running multiplayer operations if necessary
void pause_do()
{
	int k;
	const char *pause_str = XSTR("Paused", 767);
	int str_w, str_h;
	// next two are for view resetting
	static int previous_Viewer_mode = -1;
	static int previous_hud_state = -1;

	Assert( !(Game_mode & GM_MULTIPLAYER) );
	
	//	RENDER A GAME FRAME HERE AS THE BACKGROUND (if normal pause)

	if(Pause_type == PAUSE_TYPE_NORMAL)	{			
		// Fall back to viewer just incase saved screen is invalid
		if(Pause_saved_screen == -1){
			Pause_type = PAUSE_TYPE_VIEWER;
		}
		else if(Pause_type == PAUSE_TYPE_NORMAL)	{
			gr_restore_screen(Pause_saved_screen);
		}
	}

	if(Pause_type == PAUSE_TYPE_NORMAL){
		if (Pause_background_bitmap >= 0) {
			gr_set_bitmap(Pause_background_bitmap);

			// draw the bitmap
			gr_bitmap(Please_wait_coords[gr_screen.res][0], Please_wait_coords[gr_screen.res][1], GR_RESIZE_MENU);
			
			// draw "Paused" on it
			gr_set_color_fast(&Color_normal);
			gr_set_font(FONT2);
			gr_get_string_size(&str_w, &str_h, pause_str);
			gr_string((gr_screen.max_w_unscaled - str_w) / 2, (gr_screen.max_h_unscaled - str_h) / 2, pause_str, GR_RESIZE_MENU);
			gr_set_font(FONT1);
		}
	}

	if (Pause_type == PAUSE_TYPE_VIEWER) {
		if (previous_Viewer_mode < 0)
			previous_Viewer_mode = Viewer_mode;

		if (previous_hud_state < 0)
			previous_hud_state = hud_disabled();
	}

	// process the ui window here
	k = Pause_win.process() & ~KEY_DEBUGGED;
	switch (k)
	{ 
		case KEY_TAB:
			hud_toggle_draw();
			break;

		// view from outside of the ship
	   	case KEY_ENTER:
			if (Pause_type == PAUSE_TYPE_VIEWER) {
				button_function_demo_valid(VIEW_EXTERNAL);
			}
			break;

		// view from target
		case KEY_PADDIVIDE:
			if (Pause_type == PAUSE_TYPE_VIEWER) {
				button_function_demo_valid(VIEW_OTHER_SHIP);
			}
			break;

		// change target
		case KEY_PADMULTIPLY:
			if (Pause_type == PAUSE_TYPE_VIEWER) {
				button_function(TARGET_NEXT);
			}
			break;

		case KEY_ESC:
		case KEY_ALTED + KEY_PAUSE:
		case KEY_PAUSE:
			// reset previous view if we happened to be playing around with it during pause
			if (Pause_type == PAUSE_TYPE_VIEWER) {
				if (previous_Viewer_mode >= 0) {
					Viewer_mode = previous_Viewer_mode;
				}

				// NOTE remember that hud state is reversed here (0 == on, 1 == off)
				if ( (previous_hud_state >= 0) && (hud_disabled() != previous_hud_state) ) {
					hud_set_draw( !previous_hud_state );
				}
			}

			gameseq_post_event(GS_EVENT_PREVIOUS_STATE);		
			break;
	}	// end switch

	// draw the background window
	Pause_win.draw();

	// a very unique case where we shouldn't be doing the page flip because we're inside of popup code
	if(!popup_active()){
		if(Pause_type == PAUSE_TYPE_NORMAL) {
			gr_flip();
		}
	} else {
		// this should only be happening in a very unique multiplayer case
		Int3();
	}
}
// throw up a popup with the given notification code and optional winsock code
void multi_endgame_popup(int notify_code,int error_code,int wsa_error)
{
	char err_msg[255];
	int flags = PF_USE_AFFIRMATIVE_ICON;	

	// if there is a popup already active, just kill it
	if(popup_active()){
		// if there is already a popup active, kill it
		popup_kill_any_active();

		Int3();
	} else {
		// if there is a winsock error code, stick it on the end of the text
		if(wsa_error != -1){		
			sprintf(err_msg,NOX("WSAERROR : %d\n\n"),wsa_error);
			flags |= PF_TITLE_RED;
		} else {
			strcpy_s(err_msg,"");
		}

		// setup the error message string
		if(notify_code != MULTI_END_NOTIFY_NONE){
			switch(notify_code){
			case MULTI_END_NOTIFY_KICKED :
				strcat_s(err_msg,XSTR("You have been kicked",651));
				break;
			case MULTI_END_NOTIFY_SERVER_LEFT:
				strcat_s(err_msg,XSTR("The server has left the game",652));
				break;
			case MULTI_END_NOTIFY_FILE_REJECTED:
				strcat_s(err_msg,XSTR("Your mission file has been rejected by the server",653));
				break;
			case MULTI_END_NOTIFY_EARLY_END:
				strcat_s(err_msg,XSTR("The game has ended while you were ingame joining",654));
				break;
			case MULTI_END_NOTIFY_INGAME_TIMEOUT:
				strcat_s(err_msg,XSTR("You have waited too long to select a ship",655));
				break;
			case MULTI_END_NOTIFY_KICKED_BAD_XFER:
				strcat_s(err_msg,XSTR("You were kicked because mission file xfer failed",998));
				break;
			case MULTI_END_NOTIFY_KICKED_CANT_XFER:
				strcat_s(err_msg,XSTR("You were kicked because you do not have the builtin mission",999));
				strcat_s(err_msg, NOX(" "));
				strcat_s(err_msg, Game_current_mission_filename);
				break;
			case MULTI_END_NOTIFY_KICKED_INGAME_ENDED:
				strcat_s(err_msg,XSTR("You were kicked because you were ingame joining a game that has ended",1000));
				break;
			default : 
				Int3();
			}		
		} else {	
			switch(error_code){
			case MULTI_END_ERROR_CONTACT_LOST :
				strcat_s(err_msg,XSTR("Contact with server has been lost",656));
				break;
			case MULTI_END_ERROR_CONNECT_FAIL :
				strcat_s(err_msg,XSTR("Failed to connect to server on reliable socket",657));
				break;
			case MULTI_END_ERROR_LOAD_FAIL :
				strcat_s(err_msg,XSTR("Failed to load mission file properly",658));
				break;						
			case MULTI_END_ERROR_INGAME_SHIP :
				strcat_s(err_msg,XSTR("Unable to create ingame join player ship",659));
				break;
			case MULTI_END_ERROR_INGAME_BOGUS :
				strcat_s(err_msg,XSTR("Recevied bogus packet data while ingame joining",660));
				break;
			case MULTI_END_ERROR_STRANS_FAIL :
				strcat_s(err_msg,XSTR("Server transfer failed (obsolete)",661));
				break;
			case MULTI_END_ERROR_SHIP_ASSIGN:
				strcat_s(err_msg,XSTR("Server encountered errors trying to assign players to ships",662));
				break;
			case MULTI_END_ERROR_HOST_LEFT:
				strcat_s(err_msg,XSTR("Host has left the game, aborting...",663));
				break;			
			case MULTI_END_ERROR_XFER_FAIL:
				strcat_s(err_msg,XSTR("There was an error receiving the mission file!",665));
				break;
			case MULTI_END_ERROR_WAVE_COUNT:
				strcat_s(err_msg,XSTR("The player wings Alpha, Beta, Gamma, and Zeta must have only 1 wave.  One of these wings currently has more than 1 wave.", 987));
				break;
			// Karajorma - both of these should really be replaced with new strings in strings.tbl but for now this one has much the same meaning
			case MULTI_END_ERROR_TEAM0_EMPTY:
				strcat_s(err_msg,XSTR("All players from team 1 have left the game", 664));
				break;
			case MULTI_END_ERROR_TEAM1_EMPTY:
				strcat_s(err_msg,XSTR("All players from team 2 have left the game", 664));
				break;
			case MULTI_END_ERROR_CAPTAIN_LEFT:
				strcat_s(err_msg,XSTR("Team captain(s) have left the game, aborting...",664));
				break;
			default :
				Int3();
			}		
		}

		// show the popup
		popup(flags,1,POPUP_OK,err_msg);	
	}
}
void multi_pause_do()
{
	int k;
	
	// make sure we don't enter this state unless we're in the mission itself	
	Netgame.game_state = NETGAME_STATE_PAUSED;

	// server of the game should periodically be sending pause packets for good measure
	if (Net_player->flags & NETINFO_FLAG_AM_MASTER) {		
	}

	if (!(Game_mode & GM_STANDALONE_SERVER)) {
		// restore saved screen data if any
		if (Multi_paused_screen_id >= 0) {
			gr_restore_screen(Multi_paused_screen_id);
		}

		// set the background image
		if (Multi_paused_background >= 0) {
			gr_set_bitmap(Multi_paused_background);
			gr_bitmap(0, 0, GR_RESIZE_MENU);
		}

		// if we're inside of popup code right now, don't process the window
		if(!popup_active()){
			// process chatbox and window stuff
			k = chatbox_process();
			k = Multi_paused_window.process(k);	
		
			switch (k) {
			case KEY_ESC:			
			case KEY_PAUSE:									
				multi_pause_request(0);
				break;
			}
		}

		// check for any button presses
		multi_pause_check_buttons();

		// render the callsign of the guy who paused
		multi_pause_render_callsign();
				
		// render the chatbox
		chatbox_render();
		
		// draw tooltips
		// Multi_paused_window.draw_tooltip();
		Multi_paused_window.draw();

		// display the voice status indicator
		multi_common_voice_display_status();

		// don't flip screen if we are in the popup code right now
		if (!popup_active()) {
			gr_flip();
		}
	}
	// standalone pretty much does nothing here
	else {
		os_sleep(1);
	}
}