void iphoneMainMenu() {	
	if ( !btnResumeGame.texture ) {
		// initial setup
		#ifdef IPAD
		SetButtonPics( &btnResumeGame, "iphone/resume_game.tga", "Resume Game", 216, 338 );
		SetButtonPics( &btnNewGame, "iphone/new_game.tga", "New Game", 446, 338 );
		SetButtonPics( &btnWWW, "iphone/website.tga",  "Website", 676, 338 );
		SetButtonPics( &btnMultiplayer, "iphone/multiplay.tga",  "Multiplayer", 347-17, 568 );
		SetButtonPics( &btnControls, "iphone/controls.tga", "Options", 545+17, 568 );	
		
		SetButtonPics( &btnLabel1, "iphone/label1.tga", "", 0,   20 );
		SetButtonPics( &btnLabel2, "iphone/label2.tga", "", 256, 20 );
		SetButtonPics( &btnLabel3, "iphone/label3.tga", "", 512, 20 );
		SetButtonPics( &btnLabel4, "iphone/label4.tga", "", 768, 20 );

		btnLabel1.buttonFlags = BF_INACTIVE;
		btnLabel2.buttonFlags = BF_INACTIVE;
		btnLabel3.buttonFlags = BF_INACTIVE;
		btnLabel4.buttonFlags = BF_INACTIVE;
		
		#else
		SetButtonPics( &btnResumeGame, "iphone/resume_game.tga", "Resume Game", 16, 4 );
		SetButtonPics( &btnNewGame, "iphone/new_game.tga", "New Game", 176, 4 );
		SetButtonPics( &btnDemo, "iphone/demo.tga", "Demos", 336, 4 );
		SetButtonPics( &btnMultiplayer, "iphone/multiplay.tga",  "Multiplayer", 16, 168 );
		SetButtonPics( &btnWWW, "iphone/website.tga",  "Website", 176, 168 );
		SetButtonPics( &btnControls, "iphone/controls.tga", "Options", 336, 168 );
		#endif
	}
		
		
	#ifdef IPAD
	HandleButton(&btnLabel1);
	HandleButton(&btnLabel2);
	HandleButton(&btnLabel3);
	HandleButton(&btnLabel4);
	#endif
	
	
	if ( netgame ) {
		// disable buttons if we are already in a netgame
		btnNewGame.buttonFlags = BF_INACTIVE | BF_TRANSPARENT;
		btnMultiplayer.buttonFlags = BF_INACTIVE | BF_TRANSPARENT;
		btnWWW.buttonFlags = BF_INACTIVE | BF_TRANSPARENT;
		#ifndef IPAD
		btnDemo.buttonFlags = BF_INACTIVE | BF_TRANSPARENT;
		#endif
	}

	if ( HandleButton( &btnResumeGame ) ) {
		ResumeGame();
	}

	if ( HandleButton( &btnNewGame ) ) {
		menuState = IPM_MAPS;
	}
		
	if ( HandleButton( &btnControls ) ) {
		menuState = IPM_CONTROLS;
	}
	
	if ( !NetworkAvailable() ) {
		// disable multiplayer if we don't have a good device
		//btnMultiplayer.buttonFlags = BF_INACTIVE | BF_TRANSPARENT;
		btnMultiplayer.buttonFlags = BF_TRANSPARENT;
	} else if ( netgame ) {
		// disable multiplayer if we are already in a netgame
		btnMultiplayer.buttonFlags = BF_INACTIVE | BF_TRANSPARENT;
	} else if ( NetworkServerAvailable() ) {
		// blink the multiplayer button if a local server is available
		btnMultiplayer.buttonFlags = BF_GLOW;
	} else {
		btnMultiplayer.buttonFlags = 0;
	}
	
	if ( HandleButton( &btnMultiplayer )) {
		if (NetworkAvailable()) {
			// get the address for the local service, which may
			// start up a bluetooth personal area network
			boolean serverResolved = ResolveNetworkServer( &netServer.address );
		
			// open our socket now that the network interfaces have been configured
			// Explicitly open on interface 1, which is en0.  If bluetooth ever starts
			// working better, we can handle multiple interfaces.
			if ( gameSocket <= 0 ) {
				gameSocket = UDPSocket( "en0", DOOM_PORT );
			}
		
			// get the address for the local service
			if ( !serverResolved ) {
				// nobody else is acting as a server, so start one here
				RegisterGameService();
				SetupEmptyNetGame();
			}		
			menuState = IPM_MULTIPLAYER;
		} else {
			SysShowAlert("Attention:", "Multiplayer requires a WiFi connection that doesn't block UDP port 14666");
		}
	}
	// draw the available interfaces over the blinking net button
	if ( NetworkServerAvailable() ) {
 		iphoneCenterText( btnMultiplayer.x + btnMultiplayer.drawWidth / 2, 
						 btnMultiplayer.y + btnMultiplayer.drawHeight/2, 0.75,
								 NetworkServerTransport() );
	}
	
	if ( HandleButton( &btnWWW ) ) {
//		menuState = IPM_PACKET_TEST;	// !@# debug
		SysIPhoneOpenURL( "http://doomsday.generalarcade.com/" );
		
	}
	#ifndef IPAD
	if ( HandleButton( &btnDemo ) ) {
		StartDemoGame( btnDemo.twoFingerPress );
	}
	
	if ( btnDemo.twoFingerPress ) {
		strcpy( timeDemoResultString, "TIMEDEMO" );
	}
	// draw the timedemo results on top of the button
	if ( timeDemoResultString[0] ) {
		iphoneCenterText( btnDemo.x + btnDemo.drawWidth / 2, btnDemo.y + btnDemo.drawHeight/2, 0.75,
						 timeDemoResultString );
	}
	#endif
}
void CBOINCDialUpManager::OnPoll() {
    CMainDocument*      pDoc = wxGetApp().GetDocument();
    CBOINCBaseFrame*    pFrame = wxGetApp().GetFrame();
    static bool         bAlreadyRunningLoop = false;
    bool                bIsOnline = false;
    bool                bWantConnection = false;
    bool                bWantDisconnect = false;
    wxString            strDialogMessage = wxEmptyString;
    CC_STATUS           cc_status;


    // We are ready to rock and roll.
    if (!bAlreadyRunningLoop && pDoc) {
        wxASSERT(wxDynamicCast(pDoc, CMainDocument));
        wxASSERT(wxDynamicCast(pFrame, CBOINCBaseFrame));

        bAlreadyRunningLoop = true;

        // cache the various states

        // The dialup manager tells us if we are still dialing or if we have
        //   successfully connected.  IsNetworkAlive/IsOnline both report the
        //   success or failure of the dialup device to establish a connection
        //   to the outside world.
        pDoc->GetCoreClientStatus(cc_status);

        bIsOnline = (cc_status.network_status == NETWORK_STATUS_ONLINE);
        bWantConnection = (cc_status.network_status == NETWORK_STATUS_WANT_CONNECTION);
        bWantDisconnect = (cc_status.network_status == NETWORK_STATUS_WANT_DISCONNECT);

        // The timers are used to keep from spamming the user with the same
        //   messages over each iteration of the poll loop.  we only need to
        //   reset them during a connect event in case we randomly loose
        //   a connection.
        if (m_bResetTimers) {
            wxLogTrace(wxT("Function Status"), wxT("CBOINCDialUpManager::poll - Resetting dial-up notification timers"));

            m_bResetTimers = false;
            m_bSetConnectionTimer = false;
            ResetReminderTimers();
        }

        // Log out the trace information for debugging purposes.
        /*
        wxLogTrace(wxT("Function Status"), wxT("CBOINCDialUpManager::poll - Dialup Flags"));
        wxLogTrace(wxT("Function Status"),
            wxT("CBOINCDialUpManager::poll - -- bIsOnline = '%d', bIsDialing = '%d', m_bWasDialing = '%d', iNetworkStatus = '%d', bWantConnection = '%d'"),
            bIsOnline, bIsDialing, m_bWasDialing, iNetworkStatus, bWantConnection
        );
        wxLogTrace(wxT("Function Status"),
            wxT("CBOINCDialUpManager::poll - -- m_bResetTimers = '%d', m_bNotifyConnectionAvailable = '%d', m_bConnectedSuccessfully = '%d'"),
            m_bResetTimers, m_bNotifyConnectionAvailable, m_bConnectedSuccessfully
        );
        wxLogTrace(wxT("Function Status"),
            wxT("CBOINCDialUpManager::poll - -- confirm_before_connecting = '%d', hangup_if_dialed = '%d'"),
            pDoc->state.global_prefs.confirm_before_connecting, pDoc->state.global_prefs.hangup_if_dialed
        );
        */

#ifndef __WXMSW__           // notification logic for non MS-Windows systems
        if (!bIsOnline && bWantConnection) {
            // Make sure window is visable and active, don't want the message box
            // to pop up on top of anything else
            wxLogTrace(wxT("Function Status"), wxT("CBOINCDialUpManager::poll - Notify need Internet Connection"));
            if (pFrame->IsShown() && wxGetApp().IsActive()) {
                NotifyUserNeedConnection(false);
            }
            /*
            // this section commented out until taskbar/systray notification alerts are implemented
                          else {
                            // window is not visible, show alert
                            if (pTaskbar && pTaskbar->IsBalloonsSupported()) {
                                NotifyUserNeedConnection(true);
                            }
                        }
            */
        }
#else               // dialer stuff for MS-Windows systems
        bool  bIsDialing = m_pDialupManager->IsDialing();
        if (!bIsOnline && !bIsDialing && !m_bWasDialing && bWantConnection) {
            wxLogTrace(wxT("Function Status"), wxT("CBOINCDialUpManager::poll - !bIsOnline && !bIsDialing && !m_bWasDialing && bWantConnection"));
            if (!pFrame->IsShown()) {
                // BOINC Manager is hidden and displaying a dialog might interupt what they
                //   are doing.
                NotifyUserNeedConnection(true);
            } else {
                // BOINC Manager is visable and can process user input.
                m_bSetConnectionTimer = true;
                Connect();
            }
        } else if (!bIsDialing && !m_bWasDialing) {
            // We are not doing anything now, were we up to something before?
            if (bIsOnline && m_bConnectedSuccessfully && m_bNotifyConnectionAvailable) {
                // Ah ha, we are online and we initiated the connection, so we need to
                //   notify the CC that the network is available.
                wxLogTrace(wxT("Function Status"), wxT("CBOINCDialUpManager::poll - bIsOnline && m_bConnectedSuccessfully && m_bNotifyConnectionAvailable"));
                NetworkAvailable();
            } else if (bWantDisconnect && m_bConnectedSuccessfully) {
                // We are online, and the CC says it is safe to disconnect.  Since we
                //   initiated the connection we need to disconnect now.
                wxLogTrace(wxT("Function Status"), wxT("CBOINCDialUpManager::poll - bWantDisconnect && m_bConnectedSuccessfully"));
                Disconnect();
            }
        } else if (!bIsDialing && m_bWasDialing) {
            // We initiated a connection attempt and now we are either online or failed to
            //   connect because of a modem error or a users credentials were wrong.
            wxLogTrace(wxT("Function Status"), wxT("CBOINCDialUpManager::poll - !bIsDialing && m_bWasDialing"));

            if (m_bSetConnectionTimer) {
                m_bSetConnectionTimer = false;
                m_dtDialupConnectionTimeout = wxDateTime::Now();
                m_iConnectAttemptRetVal = ERR_NO_NETWORK_CONNECTION;
            }

            wxTimeSpan tsTimeout = wxDateTime::Now() - m_dtDialupConnectionTimeout;
            if (30 > tsTimeout.GetSeconds()) {
                if(m_iConnectAttemptRetVal != BOINC_SUCCESS) {
                    return;
                }
            }

            m_bWasDialing = false;
            m_bResetTimers = true;
            if (!m_iConnectAttemptRetVal) {
                ConnectionSucceeded();
            } else {
                ConnectionFailed();
            }
        } else if (bIsDialing && !m_bWasDialing) {
            // Setup the state machine so that it knows when we have finished the connection
            //   attempt.
            wxLogTrace(wxT("Function Status"), wxT("CBOINCDialUpManager::poll - bIsDialing && !m_bWasDialing"));
            m_bWasDialing = true;
        }
#endif
        bAlreadyRunningLoop = false;
    }
}