/*------------------------------------------------------------------------------*
 * File Name: HPFFile.cpp	 													*
 * Creation: 																	*
 * Purpose: OriginC Source C file												*
 * Copyright (c) Originlab Corp.	2006, 2007, 2008, 2009, 2010				*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA					*
 *	Cheney 2007-1-27 SHOULD_SET_ALL_COLUMNS_BE_Y								*
 *	Hong 07/17/08 v8.0903 FIX_SOME_IMPORT_HAVE_DUPLICATE_SHEET_NAME_NO_AUTO_ENUM*
 *	Sim 02-04-2010 QA81-15063 MOVE_IMP_FILE_INFO_OUT_FROM_COL_USER_INFO_TREE	*
 *	Sim 02-05-2010 QA81-15063 ROLL_BACK_MOVE_COL_INFO_OUT_OF_USER_TREE			*
 *------------------------------------------------------------------------------*/
 
////////////////////////////////////////////////////////////////////////////////////
// Including the system header file Origin.h should be sufficient for most Origin
// applications and is recommended. Origin.h includes many of the most common system
// header files and is automatically pre-compiled when Origin runs the first time.
// Programs including Origin.h subsequently compile much more quickly as long as
// the size and number of other included header files is minimized. All NAG header
// files are now included in Origin.h and no longer need be separately included.
//
// Right-click on the line below and select 'Open "Origin.h"' to open the Origin.h
// system header file.
#include <Origin.h>
////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////
// Include your own header files here.

#include <..\originlab\hpfFile.h>
#include <..\Originlab\fu_utils.h> ///---Sim 02-04-2010 QA81-15063 MOVE_IMP_FILE_INFO_OUT_FROM_COL_USER_INFO_TREE
////////////////////////////////////////////////////////////////////////////////////
// Start your functions here.


typedef enum {
	DT_HEADER		=	0x1000,
	DT_CHANNEL_INFO	=	0x2000,
	DT_DATA			=	0x3000,
	DT_EVENT_DEF	=	0x4000,
	DT_EVENT_DATA	=	0x5000,
	DT_INDEX		=	0x6000,
//	DT_TRIGGER_INFO	= 	0x7000, // Data translation said this part is removed
} DT_CHUNK_ID;

#define COMMON_CHUNK_PART_SIZE			16
#define CHUNK_PADDING_SIZE				0x10000
	
#define  STR_CHANNEL_GROUP				"ChannelGroup"
#define  STR_CHANNEL_INFO_DATA			"ChannelInformationData"
///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
#define  STR_CHANNEL_INFO				"ChannelInformation"
#define  STR_CHANNEL_INFO_CHUNK			"ChannelInformationChunk"
///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
#define  STR_EVEN_DEF					"EvenDef"
#define  STR_DATA_CHUNK_OFFSET			"Offset"
#define  STR_DATA_CHUNK_START			"StartIndex"
#define  STR_DATA_CHUNK_TAG_NAME		"DataChunk"
#define  STR_CHANNEL_INFO_TAG_NAME		"ChannelInformation"
///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
#define  STR_CHANNEL_INFO_CHUNK_TAG_NAME "ChannelInformationChunk"
///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
#define  STR_CHANNEL_INFO_DATA_TAG_NAME	"ChannelInformationData"


//////////////////////////////////////
typedef struct tagDTHeader {
	char CreatedId[4];
	int FileVersion;
	int Reserver1;				// origin not support 64bit int
	int IndexChunkOffset;
	int Reserver2;				// origin not support 64bit int
}DTHeader, *PDTHeader;

typedef struct tagDTChInfo {
	int GroupID;
	int NumberOfChannels;
}DTCHInfo, *PDTCHInfo;

typedef struct tagDTData {
	int GroupID;
	int DataStartIndex;
	int Reserver1;				// origin not support 64bit int
	int nDataCount;
} DTData, *PDTData;

typedef struct tagDTIndex {
	int dataStartIndex;
	int Reserver1;				// origin not support 64bit int
	int perChannelDataLengthInSamples;
	int Reserver2;				// origin not support 64bit int
	int chunkID;
	int Reserver3;				// origin not support 64bit int
	int groupID;
	int Reserver4;				// origin not support 64bit int
	int fileOffset;
	int Reserver5;				// origin not support 64bit int
} DTIndex, *PDTIndex;
/////////////////////////////////////////
#define CHK_VALID_RETURN(__func__) if ( nRet = __func__ )\
	return nRet;
#define FILE_CLOSE_RETURN(_ret) {	\
		Close();					\
		return (_ret);					\
	}
#define _read_part_chunk_struct(_tr_, _struct_ ) _struct_ _stTemp;\
	int _nTempStructSize = sizeof(_stTemp);\
	int _iBytesRead = Read(&_stTemp, _nTempStructSize); \
	if( _iBytesRead != _nTempStructSize ) \
		return IMPERR_FAILED_READ; \
	Tree _TrXML; \
	_tr_= _stTemp; \
	arrChunkCommon[2] -= COMMON_CHUNK_PART_SIZE; \
	CHK_VALID_RETURN( read_chunk_xml(_TrXML, arrChunkCommon[2] - _nTempStructSize) ) \
	_tr_.AddNode(_TrXML);\

	
	
	
//////////////////////////////////////////////////	

///// this class used to free memory automatically
class ReadDataArrayInFile
{
public:
	ReadDataArrayInFile(int nSize, int nElementSize, file& fid) 
	{
		m_pBuff = calloc(nSize, nElementSize);	
		uint iBytesRead = nSize * nElementSize;
		if( m_pBuff && fid.IsOpen())
		{
			if ( iBytesRead != fid.Read(m_pBuff, iBytesRead) )
				m_pBuff = NULL;	
		} 
	}
	~ReadDataArrayInFile() 
	{
		if ( m_pBuff )
		{
			free(m_pBuff);
			m_pBuff = NULL;
		}
	}
public:
	void* GetBuffer() {return m_pBuff; }
protected:
	void* m_pBuff;
};

static int dt_get_data_type(TreeNode& trnCh)
{
	int nDataType = FSI_MIXED;

	if( trnCh )
	{
		string strDataType = trnCh.DataType.strVal;
		if( strDataType.CompareNoCase("Float") == 0 )
			nDataType = FSI_REAL;
		else if( strDataType.CompareNoCase("Double") == 0 )
			nDataType = FSI_DOUBLE;
		else if( strDataType.CompareNoCase("Int16") == 0 )
			nDataType = FSI_SHORT;
		else if( strDataType.CompareNoCase("Uint16") == 0 )
			nDataType = FSI_USHORT;
		else if( strDataType.CompareNoCase("Int32") == 0 )
			nDataType = FSI_LONG;
		else if( strDataType.CompareNoCase("Uint32") == 0 )
			nDataType = FSI_ULONG;
		else
			ASSERT(FALSE);
	}
	return nDataType;
}

	
///////////////////////////////////////////////////////////////////////////
////////////			Class HPFFile
////////////
HPFFile::HPFFile()
{
	//m_bValid = false;
}

HPFFile::~HPFFile()
{
	Close();	
}
/*
int HPFFile::Import(Worksheet& wks, LPCSTR lpcszFileName, TreeNode& trInfo)
{
	int nRet;
	WorksheetPage pg;
	wks.GetParent(pg);
	
	CHK_VALID_RETURN(OpenFile(lpcszFileName, trInfo))
	
	CHK_VALID_RETURN(readData(pg, trInfo, dwOption))
	
	return 0;
}
*/

///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA	
/// Hong 07/17/08 v8.0903 FIX_SOME_IMPORT_HAVE_DUPLICATE_SHEET_NAME_NO_AUTO_ENUM
//int HPFFile::Import(LPCSTR lpcszFileName, Worksheet& wks, TreeNode& trInfo, int nC1)
int HPFFile::Import(LPCSTR lpcszFileName, Worksheet& wks, TreeNode& trInfo, int nC1, DWORD dwOptions) // = 0, HPF_RENAME_SHEET_BY_FILENAME
/// end FIX_SOME_IMPORT_HAVE_DUPLICATE_SHEET_NAME_NO_AUTO_ENUM
{
	m_lpcszFileName = lpcszFileName;
	int nError = ReadHeader(lpcszFileName, trInfo);
	if(nError != HPF_NO_ERRER)
		return nError;
	
	nError = ReadData(wks, trInfo, nC1); 
	if(nError != HPF_NO_ERRER)
		return nError;

	/// Hong 07/17/08 v8.0903 FIX_SOME_IMPORT_HAVE_DUPLICATE_SHEET_NAME_NO_AUTO_ENUM
	//wks.SetName(GetFileName(lpcszFileName, true));
	if ( HPF_RENAME_SHEET_BY_FILENAME & dwOptions )
		wks.SetName(GetFileName(lpcszFileName, true), OCD_ENUM_NEXT | OCD_ENUM_ADD_SEPARATOR);
	/// end FIX_SOME_IMPORT_HAVE_DUPLICATE_SHEET_NAME_NO_AUTO_ENUM
	return HPF_NO_ERRER;
}
///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA


int HPFFile::ReadHeader(LPCSTR lpcszFileName, TreeNode& trInfo)
{
	int nRet;
	m_nGroupID = -1;
	m_nDataSize = 0;;

	if( !Open(lpcszFileName, file::modeRead) )
		FILE_CLOSE_RETURN(IMPERR_FAILED_OPEN)
	
	int arrChunkCommon[4];
	
	/// the first chunk must be Header chunk
	/// read header chunk
	if ( COMMON_CHUNK_PART_SIZE != Read(arrChunkCommon, COMMON_CHUNK_PART_SIZE))
		FILE_CLOSE_RETURN(IMPERR_FAILED_READ)
	
	if ( DT_HEADER != arrChunkCommon[0] )
		FILE_CLOSE_RETURN(HPF_ERR_INVLAID_FILE)
		
	TreeNode trHeader;
	trHeader = trInfo.AddNode(IMPTREE_NODE_HEADER);
	_read_part_chunk_struct(trHeader, DTHeader)
	
	/// read Index chunk
	CHK_VALID_RETURN(readIndexChunk(_stTemp.IndexChunkOffset, trInfo, 0))
}

int HPFFile::readIndexChunk(int nFileOffset, TreeNode& trInfo, DWORD dwOption)
{
	int nRet;
	Seek(nFileOffset, file::begin);
	int arrData[6];
	if ( 24 != Read(arrData, 24))
		FILE_CLOSE_RETURN(IMPERR_FAILED_READ)

	if ( DT_INDEX != arrData[0] )
		return HPF_ERR_INVLAID_FILE;
	
	int nIndexSize = arrData[4];
	ReadDataArrayInFile IndexDess(nIndexSize, sizeof(DTIndex), *this);
	PDTIndex pDTIndex = (PDTIndex)IndexDess.GetBuffer();
	
	TreeNode trData;
	trData = trInfo.AddNode(IMPTREE_NODE_DATA);
	///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
	TreeNode trChannel = trInfo.AddNode(STR_CHANNEL_INFO);
	///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
		
	if ( NULL == pDTIndex )
		return HPF_ERR_ALLOCATE_MEMORY_FAILED;
	
	for ( int ii = 0; ii < nIndexSize; ii++, pDTIndex++ )
	{
		switch ( pDTIndex->chunkID )
		{
		case DT_HEADER:
			continue;
		case DT_CHANNEL_INFO:
			///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
			//CHK_VALID_RETURN(readChannelInfo(pDTIndex->fileOffset, trInfo))
			CHK_VALID_RETURN(readChannelInfo(pDTIndex->fileOffset, trChannel))
			///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
			continue;
		case DT_DATA:
			if ( m_nDataSize != pDTIndex->dataStartIndex || m_nGroupID != pDTIndex->groupID)
				return HPF_ERR_INVALID_DATA_CHUNK;
			m_nDataSize += pDTIndex->perChannelDataLengthInSamples;
			CHK_VALID_RETURN(readdataInfo(trData, pDTIndex->fileOffset, pDTIndex->dataStartIndex))
			continue;
		case DT_EVENT_DEF:
			//CHK_VALID_RETURN(readEventInfo(pDTIndex->fileOffset, trInfo))
			continue;
		case DT_EVENT_DATA:
			//CHK_VALID_RETURN(readDataInfo(pDTIndex->fileOffset, trInfo))
			continue;
		case DT_INDEX:
			continue;
		default:
			ASSERT(false);
		}
	}
	return HPF_NO_ERRER;	
}

int HPFFile::readChannelInfo(int nFileOffset, TreeNode& trInfo )
{
	int arrChunkCommon[4];
	int nRet;
	
	Seek(nFileOffset, file::begin);
	if ( COMMON_CHUNK_PART_SIZE != Read(arrChunkCommon, COMMON_CHUNK_PART_SIZE))
		FILE_CLOSE_RETURN(IMPERR_FAILED_READ)
	if ( DT_CHANNEL_INFO != arrChunkCommon[0] )
		return HPF_ERR_INVLAID_FILE;
	
	TreeNode trChInfo = trInfo.AddNode(STR_CHANNEL_INFO_CHUNK);
	_read_part_chunk_struct(trChInfo, DTCHInfo)
	ASSERT( m_nGroupID < 0 ); // only one Channel info chunk supported
	m_nGroupID = _stTemp.GroupID;
	return HPF_NO_ERRER;
}
int HPFFile::readdataInfo(TreeNode& trData, int fileOffset, int nStartIndex)
{
	TreeNode trSubData;
	trSubData = trData.AddNode(STR_DATA_CHUNK_TAG_NAME);
	trSubData = trData.GetNode(STR_DATA_CHUNK_TAG_NAME);
	trSubData.SetAttribute(STR_DATA_CHUNK_OFFSET, fileOffset);
	trSubData.SetAttribute(STR_DATA_CHUNK_START, nStartIndex);
	
//	trTemp = *pDTIndex;
//	m_trDataInfo.AddNode(trTemp);
	return HPF_NO_ERRER;
}
int HPFFile::read_chunk_xml(Tree& trXML, int nBufferLength)
{
	int	iBytesRead = 0;
	
	// Read chunk XML data part
	string strXMLdata;
	LPSTR lpXMLdata = strXMLdata.GetBuffer(nBufferLength);
	iBytesRead = Read((void *)lpXMLdata, nBufferLength);
	strXMLdata.ReleaseBuffer();
	
	if( iBytesRead != nBufferLength )
		return IMPERR_FAILED_READ;
	
	trXML.XML = strXMLdata;
	return HPF_NO_ERRER;
}

///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
//int	HPFFile::initWorksheet(Worksheet& wks, TreeNode& trChInfoChunk)
int	HPFFile::prepareWorksheet(Worksheet& wks, TreeNode& trChInfoChunk, int& nTotalCols, int nColIndex)
///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
{
	///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
	TreeNode trChInfoData = trChInfoChunk.GetNode(STR_CHANNEL_INFO_DATA_TAG_NAME);
	int nCol = trChInfoData.GetNodeCount();
	
	int nColEnd = nColIndex + nCol;
	//for( int nLoop = wks.GetNumCols(); nLoop < nColEnd; nLoop = wks.GetNumCols() ) 
		//wks.AddCol();
	if(nColEnd > wks.GetNumCols())
		wks.SetSize(-1, nColEnd);
	
	nTotalCols = nColEnd;
	//int nCol = trChInfoData.GetNodeCount();
	//wks.SetSize(-1, nCol);
	//int nColIndex = 0;
	///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
	foreach (TreeNode trnCh in trChInfoData.Children)
	{
		Column cc(wks, nColIndex++);
		cc.SetFormat(OKCOLTYPE_NUMERIC);
		///Cheney 2007-1-27 SHOULD_SET_ALL_COLUMNS_BE_X
		//according doc, but may be not right, need more research
		cc.SetType(OKDATAOBJ_DESIGNATION_X);
		///end SHOULD_SET_ALL_COLUMNS_BE_X
		cc.SetInternalData(dt_get_data_type(trnCh));
		cc.SetLongName(trnCh.Name.strVal);
		cc.SetUnits(trnCh.Unit.strVal);
	}
	return HPF_NO_ERRER;
}

int HPFFile::ReadData(Worksheet& wks, TreeNode& trInfo, int nC1)   
{
	int nRet;
	int nSize = sizeof(tagDTData);
	///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA	
//	TreeNode trChInfoData = trInfo.GetNode(STR_CHANNEL_INFO_TAG_NAME).GetNode(STR_CHANNEL_INFO_DATA_TAG_NAME);
	TreeNode trChInfoData = trInfo.GetNode(STR_CHANNEL_INFO_TAG_NAME);
	///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
	TreeNode trData = trInfo.GetNode(IMPTREE_NODE_DATA);
	
	///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
	//CHK_VALID_RETURN(initWorksheet(wks, trChInfoData))
	///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
	int nFileOffset, nStartIndex;
	int nIndex 		= 0;
	int nTotalCols 	= 0;
	int nMaxRows	= 0; //for set wks size
	int nColIndex 	= nC1; //for set col data
	foreach( TreeNode trNode in trData.Children )
	{
		if ( !trNode.GetAttribute( STR_DATA_CHUNK_OFFSET, nFileOffset ) || !trNode.GetAttribute( STR_DATA_CHUNK_START, nStartIndex ) ) 
		{
			return HPF_ERR_INVALID_DATA_CHUNK;
		}
		///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
		//one channel chunk for one data chunk
		TreeNode trChannelChunk = tree_get_node(trChInfoData, nIndex);
		CHK_VALID_RETURN(prepareWorksheet(wks, trChannelChunk, nTotalCols, nColIndex))
		///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
		///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
		//CHK_VALID_RETURN(readOneDataChunk(wks, nFileOffset, nStartIndex))
		CHK_VALID_RETURN(readOneDataChunk(wks, nFileOffset, nStartIndex, trChannelChunk.GetNode(STR_CHANNEL_INFO_DATA_TAG_NAME), nMaxRows, nColIndex))
		///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
		nIndex++;
	}
	//wks.SetSize(-1, nTotalCols);
	return HPF_NO_ERRER;
}

static int file_read_data(file& ff, DataObject& dd, int nInternalType, UINT nBufferSize)
{
	dd.SetInternalDataType(nInternalType, 0);
	int nElementSize;				
	UINT nNumElements;				
	LPVOID lpData = dd.GetInternalDataBuffer(&nElementSize, &nNumElements);
	if ( nNumElements * nElementSize < nBufferSize )
		return -2;
	if( ff.Read(lpData, nBufferSize) != nBufferSize )
	{
		ff.Close();
		return -1;
	}
	dd.ReleaseBuffer();
	return HPF_NO_ERRER; 
}

///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA	
//int HPFFile::readOneDataChunk(Worksheet& wks, int nFileOffset, int nStartIndex)
int HPFFile::readOneDataChunk(Worksheet& wks, int nFileOffset, int nStartIndex, TreeNode& trChInfoChunk, int& nMaxRows, int& nColIndex)
///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
{
	int nRet, nSize;
	int arrChunkCommon[4];
	Seek(nFileOffset, file::begin);
	
	Seek(nFileOffset, file::begin);
	if ( COMMON_CHUNK_PART_SIZE != Read(arrChunkCommon, COMMON_CHUNK_PART_SIZE))
		FILE_CLOSE_RETURN(IMPERR_FAILED_READ)
	if ( DT_DATA != arrChunkCommon[0] )
		return HPF_ERR_INVALID_DATA_CHUNK;
	
	tagDTData 	DtDataInfo;
	nSize = sizeof(tagDTData);
	if ( nSize != Read(&DtDataInfo, nSize) )
		FILE_CLOSE_RETURN(IMPERR_FAILED_READ)
		
	int nDataCount = DtDataInfo.nDataCount;
	
	ReadDataArrayInFile ChanDesc(nDataCount, sizeof(DTChannelDescriptor), *this);
	PDTChannelDescriptor pDTChanDesc = (PDTChannelDescriptor)ChanDesc.GetBuffer();
	int nElementSize;				
	UINT nNumElements;
	int nSizeToRead;
	LPVOID lpData;
	float *pdata;
	
	for ( int ii = 0; ii < nDataCount; ii++, pDTChanDesc++)
	{		
		Column cc(wks, nColIndex);
		cc.SetUpperBound(m_nDataSize - 1);   
		lpData = cc.GetInternalDataBuffer(&nElementSize, &nNumElements);
		lpData += nStartIndex*nElementSize;
		int nTemp = cc.GetUpperBound();   
		
		nSizeToRead = pDTChanDesc->length;
		ASSERT(nElementSize * nNumElements == nSizeToRead);

		Seek(nFileOffset + pDTChanDesc->offset, file::begin);
		if (  nSizeToRead != Read(lpData, nSizeToRead))
			return IMPERR_FAILED_READ;
		cc.ReleaseBuffer();
		///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
		TreeNode trChannelInfo = trChInfoChunk.Children.Item(ii);
		handelColumnProperty(cc, trChannelInfo);
		nColIndex++;
		nMaxRows = nMaxRows < nNumElements? nNumElements : nMaxRows;
		///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
	}
	return HPF_NO_ERRER;
}
	
///Cheney 2007-1-25 ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA
bool HPFFile::handelColumnProperty(Column& col, TreeNode& trChInfo)
{
	//no correct doc , so not set it
	//vector<string> vsNames;
	//vector<string> vsValues;
	//vsNames.Add("Start Time");
	//vsValues.Add(ftoa(trChInfo.StartTime.dVal));
	//vsNames.Add("Per Channel Sample Rate");
	//vsValues.Add(ftoa(trChInfo.PerChannelSampleRate.dVal));
	//vsNames.Add("Time Increment");
	//vsValues.Add(ftoa(trChInfo.TimeIncrement.dVal));
	//vsNames.Add("Data Index");
	//vsValues.Add(ftoa(trChInfo.DataIndex.nVal));
	//set_user_parameters(col, vsNames,  vsValues);
	
	//set user info
	string strChannelInfo = "ChannelInfo";
	Tree trChannelInfo;
	trChannelInfo.AddTextNode(m_lpcszFileName, "ImportFile");
	trChannelInfo.AddNode(trChInfo.ChannelType);
	trChannelInfo.AddNode(trChInfo.DataType);
//	trChannelInfo.AddNode(trChInfo.PhysicalChannelNumber);
	trChannelInfo.AddNode(trChInfo.RangeMin);
	trChannelInfo.AddNode(trChInfo.RangeMax);
	trChannelInfo.AddNode(trChInfo.DataScale);
	trChannelInfo.AddNode(trChInfo.DataOffset);
	trChannelInfo.AddNode(trChInfo.SensorScale);
	trChannelInfo.AddNode(trChInfo.SensorOffset);
	trChannelInfo.Enable = ENABLE_READ_ONLY;
	trChannelInfo.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
	///---Sim 02-04-2010 QA81-15063 MOVE_IMP_FILE_INFO_OUT_FROM_COL_USER_INFO_TREE
	//return set_user_info(col, strChannelInfo, trChannelInfo);
	///---Sim 02-05-2010 QA81-15063 ROLL_BACK_MOVE_COL_INFO_OUT_OF_USER_TREE
	//trChannelInfo.Show = 0;
	//bool bRet = set_user_info(col, strChannelInfo, trChannelInfo);
	bool bRet = fu_set_import_file_info(col, trChannelInfo, strChannelInfo, IMPORT_INFO_TO_USER_TREE);
	///---END QA81-15063 ROLL_BACK_MOVE_COL_INFO_OUT_OF_USER_TREE
	///---Sim 02-05-2010 QA81-15063 ROLL_BACK_MOVE_COL_INFO_OUT_OF_USER_TREE
	// roll back move column info out of user tree, as CP said
	//fu_set_import_file_name_info(col, m_lpcszFileName);
//
	//trChannelInfo.RemoveChild("ImportFile");
	//trChannelInfo.Show = 1;
	//bRet &= set_import_file_info(col, trChannelInfo, "HPFChannelInfo");
	///---END QA81-15063 ROLL_BACK_MOVE_COL_INFO_OUT_OF_USER_TREE
	
	return bRet;
	///---END QA81-15063 MOVE_IMP_FILE_INFO_OUT_FROM_COL_USER_INFO_TREE
}
///end ADD_A_IMPORT_FUNCTION_TO_GET_INFO_AND_DATA

/////////////////////////////////////////////////////////////////////////
//////////// testing codes
///////////

int testHPF(BOOL bDialog = false)
{
	int nError = 0;
	string strFileName;
	
	if (bDialog)
		strFileName = GetOpenBox("[*.hpf] *.hpf");
	else
		strFileName = "C:\\Data\\dataview\\OriginTest.hpf";
	
	HPFFile myspcFile;
	Tree trInfo;
	Worksheet wks = Project.ActiveLayer();
	
	nError = myspcFile.ReadHeader(strFileName, trInfo);
	nError = myspcFile.ReadData(wks,trInfo); 
	return nError;
}
