//
// Data Transfer Class, Used for Saving/Loading/Cloning object data (or checking size)
//
// by Jonathan Kreuzer
//
#ifndef DataTransfer_h
#define DataTransfer_h

class CDataTransfer 
{
public:
	enum { FILE_SAVE, FILE_LOAD, MEM_SAVE, MEM_LOAD, GET_SIZE };

	CDataTransfer( int nType ) {  // Used only with GET_SIZE
		SetMode( nType ); 
		}
	CDataTransfer( void *pData, int nType, int nMax) { // MEM_SAVE or MEM_LOAD
		m_pData = (unsigned char *)pData;
		m_nMaxSize = nMax;
		SetMode( nType ); 
		}
	CDataTransfer( struct _iobuf *pFile, int nType ) { // FILE_SAVE or FILE_LOAD
		m_pFile = pFile;
		SetMode( nType ); 
		}
	bool IsRead( ) {
		if (m_nType == FILE_LOAD || m_nType == MEM_LOAD) return true;
		return false;
		}
	void SetMode( int nType )
		{
		m_nType = nType;
		m_nCount = 0;
		m_bReadOnly = false;
		}
	int NumBytes( )	{	return m_nCount;    }

	// If read only is set, read pointers are advanced but no data is written
	void SetReadOnly( int bOn ) {	m_bReadOnly = bOn;	}

	// This function does all the data transfer
	void Data( void *pData, int nSize )
		{
		switch ( m_nType ) {
			case FILE_SAVE: 
				fwrite( pData, nSize, 1, m_pFile ); 
				break;
			case FILE_LOAD: 
				if ( !m_bReadOnly ) fread( pData, nSize, 1, m_pFile ); 
				else fseek ( m_pFile, nSize, SEEK_CUR);
				break;
			case MEM_SAVE: 	
				if (m_nCount + nSize > m_nMaxSize) return; 
				memcpy (m_pData+m_nCount, pData, nSize); 
				break;
			case MEM_LOAD:
				if (m_nCount + nSize > m_nMaxSize) return; 
				memcpy (pData, m_pData+m_nCount, nSize);
				break;
			}
		m_nCount += nSize;
		}

	// Overload Var for any type often used
	void Var( int &n )  		{Data( &n, sizeof(int) ); }
	void Var( short &n )		{Data( &n, sizeof(short) ); }
	void Var( unsigned int &n )	{Data( &n, sizeof(unsigned int) ); }
	void Var( float &f )		{Data( &f, sizeof(float) ); }
	// The four functions below are Kingdom Creator specific
	void Var( CVector3 &V )		{Data( &V, sizeof(CVector3) ); }
	void Var( quat &q ) 		{Data( &q, sizeof(quat) ); }
	//void Asset( class CAssetManager *pAssetMan, int &nId );
	//void String( char *s, int nMaxLen );

private:
	int m_nType, m_nCount, m_nMaxSize;
	int m_bReadOnly;
	struct _iobuf *m_pFile;
	unsigned char *m_pData;
};

#endif