//////////////////////////////////////////////////////////////////////////////
//
// Asura_PS2_MemoryCard_SubSystem.h
//
// Created by Neil Massey.
//
// Copyright (c) 2002 Rebellion. All rights reserved.
//
// Sub system for handling state of memory card and command processing
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ___ASURA_PS2_MEMORYCARD_SUBSYSTEM_H___
#define ___ASURA_PS2_MEMORYCARD_SUBSYSTEM_H___ 1

#include <libmc.h>

struct Asura_PS2_MemoryCard_Command
{
	int  iCommand;
	int  iParameters[32];
};

struct Asura_PS2_MemoryCard_Info
{
	int iMemoryCardType;
	int iFreeKiloBytes;
	int iFormatted;		// 1=formatted, 0=not formatted
};

enum Asura_PS2_MemoryCard_State
{
	ASURA_PS2_MEMORY_CARD_INIT,
	ASURA_PS2_MEMORY_CARD_READY,
	ASURA_PS2_MEMORY_CARD_BUSY,
};

class Asura_PS2_MemoryCard_SubSystem
{
friend class Asura_PS2_MemoryCard_System;
friend class Asura_PS2_MemoryCard_Icon;
friend class Asura_PS2_MemoryCard_ErrorSystem;

private:
	// Max number of directories in root - equivalent to max save games per card
	enum {MAX_SAVE_GAMES = 127};

	// Private so only the memory card system can call them

	// Initialise, Shutdown, Update
	static void Initialise();
	static void Shutdown();
	static void Update();
	static void AddGetInfoCommand(const int iPortNumber, const int iSlotNumber);// Used enough to warrant a function

	// Command functions
	static void  AddCommand(const Asura_PS2_MemoryCard_Command& iCommand);
	static const Asura_PS2_MemoryCard_Command GetNextCommand(void);

	// Internal data variables
	static sceMcTblGetDir s_xTableDir[MAX_SAVE_GAMES] __attribute__((aligned (64)));
	static int	 s_iNSlots[2];
	static int	 s_iCurrentFileID;
	static Asura_PS2_MemoryCard_Info s_xMemoryCardInfo[2][4];	// 8 memory cards when two multitaps plugged in

	// Output to user set buffer
	static char* s_pcOutputBuffer;

	// State machine variables
	static Asura_PS2_MemoryCard_State s_xState[2];	// current state and next state
	static int	 s_iAsyncFunctionNumber;
	static int	 s_iAsyncFunctionResult;
	enum		 {NUMBER_OF_COMMANDS = 32};
	static Asura_PS2_MemoryCard_Command	 s_xCommandList[NUMBER_OF_COMMANDS];
	static int	 s_iCurrentNumberOfCommands;
	static int   s_iRetryCardCommand;				// need to retry for signal noise
	static int   s_iPortToRetry;
	static int   s_iSlotToRetry;
	static int	 s_iNumberOfEntries;

	// Helper Functions
	static void ProcessEndMessage(void);
	static void ProcessCardInfoEnd(void);
	static void ProcessOpenEnd(void);
	static void ProcessCloseEnd(void);
	static void ProcessSeekEnd(void);
	static void ProcessReadEnd(void);
	static void ProcessWriteEnd(void);
	static void ProcessFlushEnd(void);
	static void ProcessMkDirEnd(void);
	static void ProcessChDirEnd(void);
	static void ProcessGetDirEnd(void);
	static void ProcessFileInfoEnd(void);
	static void ProcessDeleteEnd(void);
	static void ProcessFormatEnd(void);
	static void ProcessUnformatEnd(void);
	static void ProcessEntSpaceEnd(void);
	static void ProcessRenameEnd(void);
	static void ProcessChgPriorEnd(void);

	static void ProcessCommand(const Asura_PS2_MemoryCard_Command iCommand);
	static void ProcessCardInfoCommand(const int* piParameters);
	static void ProcessOpenCommand(const int* piParameters);
	static void ProcessCloseCommand(const int* piParameters);
	static void ProcessSeekCommand(const int* piParameters);
	static void ProcessReadCommand(const int* piParameters);
	static void ProcessWriteCommand(const int* piParameters);
	static void ProcessFlushCommand(const int* piParameters);
	static void ProcessMkDirCommand(const int* piParameters);
	static void ProcessChDirCommand(const int* piParameters);
	static void ProcessGetDirCommand(const int* piParameters);
	static void ProcessFileInfoCommand(const int* piParameters);
	static void ProcessDeleteCommand(const int* piParameters);
	static void ProcessFormatCommand(const int* piParameters);
	static void ProcessUnformatCommand(const int* piParameters);
	static void ProcessEntSpaceCommand(const int* piParameters);
	static void ProcessRenameCommand(const int* piParameters);
	static void ProcessChgPriorCommand(const int* piParameters);	
};


// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

#endif // #ifndef ___ASURA_PS2_MEMORYCARD_SUBSYSTEM_H___
