/*------------------------------------------------------------------------------*
 * File Name: file_utils.h															*
 * Creation: 06/27/2006															*
 * Purpose: Origin C header	for File class and other related functions			*
 * Copyright (c) OriginLab Corp.2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013	*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * Sim 07-10-2006 v8.0440 GENERAL_WAVFILE_IMPORT								*
 * Sim 07-17-2006 ADD_FILE_NAME_TO_COL_AS_LONG_NAME								*
 * Sim 04-29-2007 FIX_WAVE_FORMAT_STRUCTURE										*
 *------------------------------------------------------------------------------*/
 
#ifndef _FILE_UTILS_H
#define _FILE_UTILS_H

#include <Origin.h>


/// AW 07/19/06 WAV_UNDEPENDENT_IMPOT_UTIL
/// SY 08/06/2004 QA70-6780 v8.0116 LLOC_FOR_IMPORT
typedef struct {		// 8-byte RIFF header, 
	DWORD id;			// identifier
	DWORD len;			// remaining length after this header = file_length - 8
} RIFFHDR;

typedef struct {
	DWORD id;			// WAVE file identifier
} WAVEHDR;

#define CHUNKHDR RIFFHDR

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// PCM format, we only support PCM format now
typedef struct {			// Microsoft WAVE FORMAT PCM format
	// format common field
	WORD wFormatTag;		// format category { 0001 = PCM }
	WORD wChannels;			// number of channels, { 1 = mono | 2 = stereo }
	DWORD dwSamplesPerSec;	// sampling rate
	DWORD dwAvgBytesPerSec;	// for buffer estimation
	WORD wBlockAlign;		// block alignment ( in bytes) { 1 | 2 | 4 }
	// PCM format special
	WORD wBitsPerSample;	// Sample size { 8 | 16 }
/// AW 07/11/06 MORE_ON_WAVE  
//} FMTWAVEFORMAT;
	//WORD wExtraFormat;		// EXtra format bytes, ///---Sim 04-29-2007 FIX_WAVE_FORMAT_STRUCTURE
} FMTWAVEFORMAT;
/// END MORE_ON_WAVE

///---Sim 01-16-2007 FOR_SHOW_ORGANIZER_TO_USER
typedef struct {			// Microsoft WAVE FORMAT PCM format
	// format common field
	WORD Format;		// format category { 0001 = PCM }
	WORD Channels;			// number of channels, { 1 = mono | 2 = stereo }
	DWORD SamplesPerSecond;	// sampling rate
	DWORD AverageBytesPerSecond;	// for buffer estimation
	WORD BlockAlign;		// block alignment ( in bytes) { 1 | 2 | 4 }
	// PCM format special
	WORD BitsPerSample;	// Sample size { 8 | 16 }
	//WORD ExtraFormat;		// EXtra format bytes, ///---Sim 04-29-2007 FIX_WAVE_FORMAT_STRUCTURE
} FMTWAVEFORMAT_SHOW_USER;
///---END FOR_SHOW_ORGANIZER_TO_USER

////////////////////////////////////////////////////////////////////////////////
// WAVE form wFormatTag IDs, we only support PCM format now
// flags for wFormatTag field of WAVEFORMAT
///---Sim 01-16-2007 WAV_FORMAT_ID
//#define WAVE_FORMAT_PCM     0x0001

//0 (0x0000) Unknown 
//1 (0x0001) PCM/uncompressed 
//2 (0x0002) Microsoft ADPCM 
//6 (0x0006) ITU G.711 a-law 
//7 (0x0007) ITU G.711 ?-law 
//17 (0x0011) IMA ADPCM 
//20 (0x0016) ITU G.723 ADPCM (Yamaha) 
//49 (0x0031) GSM 6.10 
//64 (0x0040) ITU G.721 ADPCM 
//80 (0x0050) MPEG 
//65,536 (0xFFFF) Experimental 
enum{
	WAVE_FORMAT_UNKNOW = 0x0000,
	WAVE_FORMAT_PCM = 0x0001,	
};
///---END WAV_FORMAT_ID
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
enum {
	IMPERR_FILE_NONE = 0,
	IMPERR_FILE_OPEN,
	IMPERR_FILE_READ,
	IMPERR_FILE_TYPE,
	IMPERR_FILE_SIZE,
	///---Sim 11-07-2006 REMOVE_TO_ERROR_DLL
	/*
	IMPERR_FILE_PCM,
	IMPERR_FILE_DUPLICA_FMT,
	IMPERR_FILE_CHUNK_SYN,
	IMPERR_FILE_SAMPLE_BIT,
	IMPERR_WRONG_COL,	/// AW 06/20/06 QA80-8767 v8.0432 SET_EVEN_SPACED_X
	*/
	///---END REMOVE_TO_ERROR_DLL
};
#define idFOURCC( ch0, ch1, ch2, ch3 )				\
		( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) |	\
		( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )

////////////////////////////////////////////////////////////////////////////
//              WAVE FILE IDS
#define RIFF_ID 		idFOURCC('R', 'I', 'F', 'F')	//0x46464952 'FFIR'
#define WAVE_ID			idFOURCC('W', 'A', 'V', 'E')	//0x45564157 'EVAW'
////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
//              RIFF CHUNKS IDS
#define RIFFCHUNK_FMT	idFOURCC('f', 'm', 't', ' ')	//0x20746d66 ' tmf'
#define RIFFCHUNK_DATA	idFOURCC('d', 'a', 't', 'a')	//0x61746164 'atad'
#define RIFFCHUNK_LIST	idFOURCC('L', 'I', 'S', 'T')	//0x5453494c 'TSIL'
////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
//              LIST SUBCHUNKS IDS
#define RIFFLIST_INFO	idFOURCC('I', 'N', 'F', 'O')	//INFO list
////////////////////////////////////////////////////////////////////////////
/// END WAV_UNDEPENDENT_IMPOT_UTIL

#define READ_DATA(_buf, _size, _errno) if (Read(_buf, _size) != _size) {return _errno;}
#define ENSURE(_a, _b, _errno) if (_a != _b) { return _errno; }

/// AW 07/24/06 TEMP_FIXING_MULTI_CHANNEL_BUG
#define IMPORT_WKS_FOR_ROW_CONTINUE(_TYPE_, _WKS_, _NROWSTART_, _NCOLSTART_, _NROWS_, _NCOLS_) \
	matrix<_TYPE_> _mTemp_(_NROWS_, _NCOLS_);\
	_TYPE_ *_lp_ = _mTemp_;\
	UINT _nBytesToRead_ = _NROWS_ * _NCOLS_ * sizeof(_TYPE_); \
	if ( _nBytesToRead_ != Read(_lp_, _nBytesToRead_) )\
		return IMPERR_FILE_READ; \ 
	_mTemp_.CopyTo(_WKS_, 0, 0, _NROWS_ - 1, _NCOLS_ - 1, _NROWSTART_, _NCOLSTART_, false, false);\
	break;
/// END TEMP_FIXING_MULTI_CHANNEL_BUG


/** ???
	Read data to Column or MatrixObject directly
Parameters:
	ff = [input] source file;
	dd = [input] Target Column or MatrixObject;
	nInternalTYpe = [input] one of FSI type, used to set object type;
	nBufferSize = [input] used as the size(byte) of space to be read to the object
Return:
	Return -1 when read file failed, return return -2, when the size of the object is not big enough, 
	return 0, when it is success.
*/
int file_read_data(file& ff, DataObject& dd, int nInternalType, UINT nBufferSize);

///---Sim 07-10-2006 v8.0440 GENERAL_WAVFILE_IMPORT
class BinFile : public file
{
public:
	BinFile(BOOL bImport = true);
	BinFile(LPCSTR lpcszFileName, BOOL bImport = true); 

	~BinFile(); // should close file if IsOpen
protected:
	bool Open(LPCSTR lpcszFileName);
public:
	DataRange GetDataRange() { return m_orng; } /// AW 08/01/06 ADD_DATA_RANGE_IN_XF_IMPORT_FILE
protected:
	bool m_bImport;
	string m_strFileName; ///---Sim 07-17-2006 ADD_FILE_NAME_TO_COL_AS_LONG_NAME
	DataRange m_orng;	/// AW 08/01/06 ADD_DATA_RANGE_IN_XF_IMPORT_FILE
};
///---end GENERAL_WAVFILE_IMPORT

#endif  // _FILE_UTILS_H
