/********************************************************************
 *  Shinobi Library Sample
 *  Copyright (c) 1998-2000 SEGA
 *
 *  Library : Backup Library
 *  Module  : Library Sample
 *  File    : buptest.c
 *  Date    : 2000-06-30
 *  Version : 2.01
 *
 ********************************************************************/

#include <shinobi.h>
#include <ninja.h>
#include "nj.h"
#include "backup.h"
#include "dbgcons.h"

/*-------------------------------------------------------------------------*/
/* マクロ定義 */

#define TEXT_W   36           /* コンソールの横幅 Console width  */
#define TEXT_H   16           /* コンソールの行数 Console height */

#define S_NOT_READY 0
#define S_READY     1
#define S_SAVE      2
#define S_LOAD      3
#define S_DELETE    4
#define S_COMPLETE  5

#define FNAME "SAVEDATA_001"  /* Save filename */
#define SAVEBUFFER SaveData   /* Save data address */
#define SAVEBLOCKS 4          /* Number of blocks to save */


/*-------------------------------------------------------------------------*/
/* グローバル変数宣言 */
Uint32 gState;
Sint32 gDrive;

char TextBuf[TEXT_W * TEXT_H];

extern Uint8 SaveData[];

/*-------------------------------------------------------------------------*/
/* スタティック変数宣言 */

/*-------------------------------------------------------------------------*/
/* スタティック関数プロトタイプ */
static void DispBackupRAMInfo(Sint32 x, Sint32 y, Sint32 drive);
static void save_callback(Sint32 drive, Sint32 op, Sint32 stat);
static void load_callback(Sint32 drive, Sint32 op, Sint32 stat);
static void delete_callback(Sint32 drive, Sint32 op, Sint32 stat);

/*-------------------------------------------------------------------------*/
/* 初期化 */
void bup_init(void)
{
	gState = S_NOT_READY;
	gDrive = 0;

	ConInit(2, 10, TEXT_W, TEXT_H, TextBuf);

	BupInit();
}

/*-------------------------------------------------------------------------*/
/* 終了 */
void bup_exit(void)
{
	BupExit();
}

/*-------------------------------------------------------------------------*/
/* メイン */
void bup_main(void)
{
	const PDS_PERIPHERAL* per;
	const BACKUPINFO *binfo;

	per = pdGetPeripheral(PDD_PORT_A0);

	if (per->press & PDD_DGT_TL) {
		gDrive--;
		gDrive &= 7;
		ConPrintf("CURRENT DRIVE IS %d\n", gDrive);
	}
	if (per->press & PDD_DGT_TR) {
		gDrive++;
		gDrive &= 7;
		ConPrintf("CURRENT DRIVE IS %d\n", gDrive);
	}


	binfo = BupGetInfo(gDrive);

	DispBackupRAMInfo(2, 26, gDrive);

	switch (gState) {
		case S_NOT_READY:
			njPrintC(NJM_LOCATION(4, 4), "CONNECT MEMORY CARD");
			njPrintC(NJM_LOCATION(4, 5), "PRESS L/R TO CHANGE DRIVE");
			if (binfo->Ready) gState = S_READY;
			break;
		case S_READY:
			njPrintC(NJM_LOCATION(4, 4), "PRESS A BUTTON TO SAVE FILE");
			njPrintC(NJM_LOCATION(4, 5), "PRESS B BUTTON TO LOAD FILE");
			njPrintC(NJM_LOCATION(4, 6), "PRESS X BUTTON TO DELETE FILE");
			njPrintC(NJM_LOCATION(4, 7), "PRESS L/R TO CHANGE DRIVE");
			if (per->press & PDD_DGT_TA) {
				BupSave(gDrive, FNAME, SAVEBUFFER, SAVEBLOCKS, save_callback);
				gState = S_SAVE;
			}
			if (per->press & PDD_DGT_TB) {
				BupLoad(gDrive, FNAME, SAVEBUFFER, load_callback);
				gState = S_LOAD;
			}
			if (per->press & PDD_DGT_TX) {
				BupDelete(gDrive, FNAME, delete_callback);
				gState = S_DELETE;
			}
			if (!binfo->Ready) gState = S_NOT_READY;
			break;
		case S_SAVE:
			njPrint(NJM_LOCATION(4, 4), "NOW SAVING...(%03d%%)",
			binfo->ProgressCount * 100 / binfo->ProgressMax);
			if (buStat(gDrive) == BUD_STAT_READY) {
				gState = S_COMPLETE;
			}
			break;
		case S_LOAD:
			njPrint(NJM_LOCATION(4, 4), "NOW LOADING...(%03d%%)",
			binfo->ProgressCount * 100 / binfo->ProgressMax);
			if (buStat(gDrive) == BUD_STAT_READY) {
				gState = S_COMPLETE;
			}
			break;
		case S_DELETE:
			njPrint(NJM_LOCATION(4, 4), "NOW DELETING...(%03d%%)",
			binfo->ProgressCount * 100 / binfo->ProgressMax);
			if (buStat(gDrive) == BUD_STAT_READY) {
				gState = S_COMPLETE;
			}
			break;
		case S_COMPLETE:
			njPrint(NJM_LOCATION(4, 4), "COMPLETE[%s]",
			BupGetErrorString(buGetLastError(gDrive)));
			njPrintC(NJM_LOCATION(4, 5), "PRESS BUTTON");
			if (per->press) {
				gState = S_READY;
			}
			break;
		default:
			break;
	}


	/* メモリーカードに書き込み中であればソフトリセット禁止にする */
	bExitEnable = !BupIsWriting();


	ConMain();
	ConDispCursor();
}


/*===============================================================*/
/* メモリーカードの状態を表示する                                */
/* 接続されていなければ「---」を、フォーマットされていなければ   */
/* 「UNFORMAT」を、フォーマットされている場合は空き容量と最大    */
/* 容量を表示します。                                            */
/* Display information of memory card.                           */
/* If memory card is not connected, "---" is displayed.          */
/* If memory card is not formatted, "UNFORMAT", is displayed.    */
/* if memory card is formatted, free volume and maximum volume   */
/* is displayed.                                                 */
/*===============================================================*/

static void DispBackupRAMInfo(Sint32 x, Sint32 y, Sint32 drive)
{
	const BACKUPINFO* binfo;
	BUS_DISKINFO* diskinfo;

	binfo = BupGetInfo(drive);
	diskinfo = &binfo->DiskInfo;

	njPrint(NJM_LOCATION(x, y), "MEMORY CARD #%d",drive);

	if (binfo->Ready) {
		if (binfo->IsFormat) {
			njPrint(NJM_LOCATION(x + 15, y), "%04d/%04d BLOCKS",
				diskinfo->free_user_blocks,
				diskinfo->total_user_blocks);
		} else {
			njPrint(NJM_LOCATION(x + 15, y), "UNFORMAT        ");
		}
	} else {
		if (binfo->Operation == BUD_OP_MOUNT) {
			njPrint(NJM_LOCATION(x + 15, y), "CHECKING...     ");
		} else {
			njPrint(NJM_LOCATION(x + 15, y), "----------------");
		}
	}
}

/*-------------------------------------------------------------------------*/
/* セーブ終了コールバック関数 */
static void save_callback(Sint32 drive, Sint32 op, Sint32 stat)
{
	ConPrintf("%s FINISHED\nDRIVE%d ERR=%s[%08X]\n\n",
		BupGetOperationString(op),
		drive,
		BupGetErrorString(stat),
		stat);
}

/*-------------------------------------------------------------------------*/
/* ロード終了コールバック関数 */
static void load_callback(Sint32 drive, Sint32 op, Sint32 stat)
{
	ConPrintf("%s FINISHED\nDRIVE%d ERR=%s[%08X]\n\n",
		BupGetOperationString(op),
		drive,
		BupGetErrorString(stat),
		stat);
}

/*-------------------------------------------------------------------------*/
/* 削除終了コールバック関数 */
static void delete_callback(Sint32 drive, Sint32 op, Sint32 stat)
{
	ConPrintf("%s FINISHED\nDRIVE%d ERR=%s[%08X]\n\n",
		BupGetOperationString(op),
		drive,
		BupGetErrorString(stat),
		stat);
}

