/*---------------------------------------------------------------------------*
  Project:  NitroSDK - WM - demos - wireless-all
  File:     wh_download.c

  Copyright 2006 Nintendo.  All rights reserved.

  These coded instructions, statements, and computer programs contain
  proprietary information of Nintendo of America Inc. and/or Nintendo
  Company Ltd., and are protected by Federal copyright law.  They may
  not be disclosed to third parties or copied or duplicated in any form,
  in whole or in part, without the prior written consent of Nintendo.

  $Log: wh_download.c,v $
  Revision 1.2  04/10/2006 13:37:12  yosizaki
  beautify source code indent.

  Revision 1.1  04/10/2006 13:07:32  yosizaki
  initial upload.

  $NoKeywords: $
 *---------------------------------------------------------------------------*/


#include <nitro.h>

#include "common.h"


/*****************************************************************************/
/* constant*/

/* download program data (clone boot)*/
/* *INDENT-OFF**/
const MBGameRegistry mbGameList =
{
    NULL,
    (u16 *)L"wireless-all",
    (u16 *)L"all of the wireless demo(cloneboot, dataSharing, WFS)",
    "/icon.char", "/icon.plt",
    WH_GGID,
    WH_CHILD_MAX + 1,
};
/* *INDENT-ON**/


/*****************************************************************************/
/* function*/

/*****************************************************************************/
/* Start the definition range of the .parent section parent device exclusive region*/
#include <nitro/parent_begin.h>
/*****************************************************************************/

/*---------------------------------------------------------------------------*
  Name:         ConnectMain

  Description:  Connect with multiboot.

  Arguments:    None.

  Returns:      If transfer to the child is successful, returns TRUE;
                If transfer fails or is cancelled, FALSE.
 *---------------------------------------------------------------------------*/
static BOOL ConnectMain(void)
{
    for (;;)
    {
        /* frame standby*/
        (void)WaitNextFrame();

        PrintString(4, 22, PLTT_YELLOW, " MB Parent ");

        switch (MBP_GetState())
        {
            //-----------------------------------------
            // Accepting entry from the child
        case MBP_STATE_ENTRY:
            {
                PrintString(4, 22, PLTT_WHITE, " Now Accepting            ");

                if (IS_PAD_TRIGGER(PAD_BUTTON_B))
                {
                    // Cancel multiboot with B Button
                    MBP_Cancel();
                    break;
                }

                // If there is at least one child in entry, start is possible.
                if (MBP_GetChildBmp(MBP_BMPTYPE_ENTRY) ||
                    MBP_GetChildBmp(MBP_BMPTYPE_DOWNLOADING) ||
                    MBP_GetChildBmp(MBP_BMPTYPE_BOOTABLE))
                {
                    PrintString(4, 22, PLTT_WHITE, " Push START Button to start   ");

                    if (IS_PAD_TRIGGER(PAD_BUTTON_START))
                    {
                        // Start download
                        MBP_StartDownloadAll();
                    }
                }
            }
            break;

            //-----------------------------------------
            // Program distribution process
        case MBP_STATE_DATASENDING:
            {

                // If everyone has completed download, start is possible.
                if (MBP_IsBootableAll())
                {
                    // Start boot
                    MBP_StartRebootAll();
                }
            }
            break;

            //-----------------------------------------
            // Reboot process
        case MBP_STATE_REBOOTING:
            {
                PrintString(4, 22, PLTT_WHITE, " Rebooting now                ");
            }
            break;

            //-----------------------------------------
            // Reconnect process
        case MBP_STATE_COMPLETE:
            {
                // Once all members have successfully connected, the multi-boot processing ends,
                // and restarts the wireless as an normal parent.
                PrintString(4, 22, PLTT_WHITE, " Reconnecting now             ");

                OS_WaitVBlankIntr();
                return TRUE;
            }
            break;

            //-----------------------------------------
            // Error occurred
        case MBP_STATE_ERROR:
            {
                // Cancel communications.
                MBP_Cancel();
            }
            break;

            //-----------------------------------------
            // Communication cancellation processing
        case MBP_STATE_CANCEL:
            // None
            break;

            //-----------------------------------------
            // Communications abnormal end
        case MBP_STATE_STOP:
            OS_WaitVBlankIntr();
            return FALSE;
        }

        // Display child state
        {
            static const char *STATE_NAME[] = {
                "NONE       ",
                "CONNECTING ",
                "REQUEST    ",
                "ENTRY      ",
                "DOWNLOADING",
                "BOOTABLE   ",
                "BOOTING    ",
            };
            enum
            {
                STATE_DISP_X = 2,
                INFO_DISP_X = 15,
                BASE_DISP_Y = 2
            };

            u16     i;

            /* display list of children*/
            for (i = 1; i < WH_PLAYER_MAX; i++)
            {
                const MBPChildInfo *childInfo;
                MBPChildState childState = MBP_GetChildState(i);
                const u8 *macAddr;
                // State display
                PrintString(STATE_DISP_X, i + BASE_DISP_Y, PLTT_WHITE, STATE_NAME[childState]);
                // User information display
                childInfo = MBP_GetChildInfo(i);
                macAddr = MBP_GetChildMacAddress(i);
                if (macAddr)
                {
                    PrintString(INFO_DISP_X, i + BASE_DISP_Y, PLTT_WHITE,
                                "%02x%02x%02x%02x%02x%02x",
                                macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
                                macAddr[5]);
                }
            }
        }
    }
}

/*---------------------------------------------------------------------------*
  Name:         ExecuteDownloadServer

  Description:  DS Single-Card play parent processing.

  Arguments:    None.

  Returns:      None.
 *---------------------------------------------------------------------------*/
void ExecuteDownloadServer(void)
{
    WH_SetGgid(WH_GGID);

    for (;;)
    {
        /* wireless initialization*/
        (void)WH_Initialize();
        WaitWHState(WH_SYSSTATE_IDLE);
        while (!IS_PAD_TRIGGER(PAD_BUTTON_A))
        {
            (void)WaitNextFrame();
            PrintString(4, 22, PLTT_WHITE, " Press A Button to start   ");
        }
        /* Search for a channel with little traffic*/
        SetCurrentChannel(MeasureChannel());

        /* DS Download Play begins*/
#if !defined(MBP_USING_MB_EX)
        (void)WH_End();
        WaitWHState(WH_SYSSTATE_STOP);
#endif
        MBP_Init(WH_GGID, WM_GetNextTgid());
        MBP_Start(&mbGameList, GetCurrentChannel());

        if (ConnectMain())
        {
            /* Multiboot child startup is successful*/
            break;
        }
        else
        {
            /* Exit the WH module and repeat*/
            WH_Finalize();
            (void)WH_End();
        }
    }

}


/*****************************************************************************/
/* End the definition boundary of the .parent section parent device exclusive region*/
#include <nitro/parent_end.h>
/*****************************************************************************/
