//////////////////////////////////////////////////////////////////////////////
//
// Asura_PS2_MemoryCard.h
//
// Created by Neil Massey.
//
// Copyright (c) 2002 Rebellion. All rights reserved.
//
// Memory card read / write
//
// PLEASE read section 12 of the TRC when using memory cards
//
//////////////////////////////////////////////////////////////////////////////

// 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_H___
#define ___ASURA_PS2_MEMORYCARD_H___ 1

#include "Core/Asura_Maths.h"
#include "MemoryCard/Asura_PS2_MemoryCard_SubSystem.h"

enum Asura_PS2_MemoryCard_IconType 
{
	ASURA_PS2_MEMORYCARD_ICON_FILE,
	ASURA_PS2_MEMORYCARD_ICON_DELETE,
	ASURA_PS2_MEMORYCARD_ICON_COPY,
};

enum Asura_PS2_MemoryCard_Sync
{
	ASURA_PS2_MEMORYCARD_SYNC_WAIT = 0,
	ASURA_PS2_MEMORYCARD_SYNC_NOWAIT = 1,
};

struct tm;

class Asura_PS2_MemoryCard_Icon
{
	// These will write to the s_xIconSysFile in Asura_PS2_MemoryCard_System through friend
	// Bundled up here to keep related things in the same place and for ease (?) of use
public:
	enum Asura_PS2_MemoryCard_Icon_BackgroundPosition
	{
		TOP_LEFT = 0,
		TOP_RIGHT,
		BOTTOM_LEFT,
		BOTTOM_RIGHT,
		NUMBER_POSITIONS,
	};

	static void Initialise(void);
	static void Shutdown(void);

	// Icon file names are maximum of 64 characters
	static void SetFileName(const Asura_PS2_MemoryCard_IconType iIconType, 
							const char* pcIconFileName, int iSize);

	// The colour is a 24 bit value in R, G, B (i.e. R << 16 | G << 8 | B)
	static void SetBackgroundColour(const Asura_PS2_MemoryCard_Icon_BackgroundPosition iBackPos, 
					   				const unsigned int uRGB);

	static void SetBackgroundColour(const Asura_PS2_MemoryCard_Icon_BackgroundPosition iBackPos, 
									const unsigned char ucR, 
									const unsigned char ucG, 
									const unsigned char ucB);

	// Background transparency range is 0 (fully transparent) to 0x80 (fully opaque)
	static void SetBackgroundTransparency(const unsigned char ucTrans);

	// 3 lightsources allowed - colour in 0..1
	static void SetLightSource(const int iLightSourceNumber, 
							   const Asura_Vector_3& xLightSourcePosition,
							   const Asura_Vector_3& xLightSourceColour);
	// Ambient colour / light
	static void SetAmbient(const float fR, 
						   const float fG, 
						   const float fB);

	// HACK - this will go when dynamic loading is in
	static int		s_iIconBufferSize[3];
	static char*	s_pcIconBuffer[3];
	static sceMcIconSys   s_xIconSysFile;
};

class Asura_PS2_MemoryCard_System
{
friend class Asura_PS2_MemoryCard_SubSystem;
public:

	enum {MAX_SAVE_GAMES = Asura_PS2_MemoryCard_SubSystem::MAX_SAVE_GAMES,
		  DATE_STRING_LENGTH = 22};

	// Initialise, Shutdown, Update
	static void Initialise();
	static void Shutdown();
	static void Update();

	// Scan for changes
	static void Rescan(const int iMemoryCardPort, const int iMemoryCardSlot);

	// Set up data header
	static void SetProductCode(const char* pcProductCode);
	static void SetSaveName(const char* pcSaveName);
    static void SetBrowserName(const char* pcDirectoryName, u_short usLineBreakPos = 16);
	static void SetSaveNumber(const int iSaveNumber);

	// Simple accessors
	static int GetSaveNumber(void) { return s_iSaveNumber; }

	// Icon data
	static Asura_PS2_MemoryCard_Icon s_xIcon;

	// Format and unformat
	static void Format(const int iMemoryCardPort, const int iMemoryCardSlot);

#ifdef _DEBUG		// Don't want to encourage use of this in commercial release
	static void Unformat(const int iMemoryCardPort, const int iMemoryCardSlot);
#endif

	// Data Functions
    static void GetPrimaryName(char* szPrimaryNameOutput);
	// Write the primary file in the directory, the one with the same name as the directory that is created
	static void WritePrimary(const int iMemoryCardPort, const int iMemoryCardSlot, 
							 const void* pcDataBuffer,  const int iDataSize,
                             bool bWriteChecksum = false);	// iDataSize in bytes
	// Write secondary files, such as replays, extra saves etc.
	static void WriteSecondary(const int iMemoryCardPort, const int iMemoryCardSlot, 
							   const void* pcDataBuffer,  const char* pcFileName,
							   const int iDataSize,
                               bool bWriteChecksum = false);

	// Write out the directory of the current save (by default, WriteIcon will call this)
	static void WriteDirectory(const int iMemoryCardPort, const int iMemoryCardSlot);

	// Write icon.sys into the directory of the current save (Directory created by default)
	static void WriteIcon(const int iMemoryCardPort, const int iMemoryCardSlot, bool bMakeDir=true);

	// Read in the data
    static void ReadPrimary(const int iMemoryCardPort, const int iMemoryCardSlot, 
							void* pcDataBuffer,  const int iDataSize,
                            u_char* pucChecksum = NULL);	// iDataSize in bytes
                        
	static void Read(const int iMemoryCardPort, const int iMemoryCardSlot, 
					 const char* pcFileName, void* pcDataBuffer,
					 const int iDataSize,
                     u_char* pucChecksum = NULL);	// iDataSize in bytes

	// Get the title for the file name - use to display to the user
	static void GetFileTitle(const int iMemoryCardPort, const int iMemoryCardSlot, 
							 const char* pcFileName, char* pcFileTitle);
	
	// Get the time the file was last created / written to - call this after a call to GetDirList has completed
	static void GetTimeStamp(const char* pcFileName, tm* pxTime);

    // Get the number of entries on the card
    static int GetNumberOfEntries(void);

	// Delete a file - use with caution - double check with user!
	static void Delete(const int iMemoryCardPort, const int iMemoryCardSlot, 
					   const char* pcFileName);

	// Change to a directory - use UNIX style paths i.e. "../" "./" etc.
	static void ChangeDir(const int iMemoryCardPort, const int iMemoryCardSlot,
						  const char* pcDirectory);
	static void ChangeToProductDir(const int iMemoryCardPort, const int iMemoryCardSlot);

	// Rename a file or directory
	static void Rename(const int iMemoryCardPort, const int iMemoryCardSlot,
					   const char* pcOriginalName, const char* pcNewName);

	// Query functions
	static bool Available(const int iMemoryCardPort, const int iMemoryCardSlot);
	static bool Formatted(const int iMemoryCardPort, const int iMemoryCardSlot);
	static bool Sync(const int iSyncMode);	// see Asura_PS2_MemoryCard_Sync above
	static void	GetDirList(const int iMemoryCardPort, const int iMemoryCardSlot, 
						   	      char* pcOutputBuffer, const bool bProjectOnlyEntries = false);
	// Return the number of bytes free on the memory card
	static int GetFreeSpace(const int iMemoryCardPort, const int iMemoryCardSlot);
    static int GetProjectFileSize(void);
	// Get the card type
	static int GetCardType(const int iMemoryCardPort, const int iMemoryCardSlot);

	// Get whether the attributes of the files are correct
	static bool AttributesOfProjectFilesCorrect(void);

private:

    static void MakeDirectoryName(void);

	// User set data
	static char  s_acProductCode[13];
	static char	 s_acFileName[7];		// first six characters of save name
	static char  s_acSaveName[21];		// key code then product model number then save name then save number
	static int	 s_iSaveNumber;

	static char*	    s_pcFileTitleOutput;
	static sceMcIconSys s_xTempIconSysHeader;
	static int			s_iPendingOperation;
};

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

#endif // #ifndef ___ASURA_PS2_MEMORYCARD_H___
