/*------------------------------------------------------------------------------*
 * File Name: DIADemImport.h													*
 * Creation: Hong 01/19/07														*
 * Purpose: OriginC Source C file to import DIADem(*.tdm)files					*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * Modification Log:															*
 *	Hong 03/14/07 UDPATE_USER_NEW_DLL											*	
 *	Hong 03/27/07 V8.0590 FREE_MEMORY_ALLOCATED_BY_DLL							*
 *	Hong 03/27/07 v8.0590 MORE_PARAMETER_SUPPORT_BY_NEW_DLL						*
 *	Hong 09/06/07 v8.0697 ALLOW_EMPTY_CHANNEL_GROUP								*
 *	Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME					*
 *	Hong 09/11/07 v8.0700 UPDATE_TO_NEW_DLL_SUPPORT_TDMS						*
 *	Hong 12/10/07 v8.0765 NITDM_ALLOW_IMPORT_EMPTY_COLUMN						*
 *	Hong 12/10/07 v8.0765 NITDM_SHOW_SAMPLE_RATE_ROW_IF_HAVE					*
 *	Hong 12/03/09 QA80-14785 IMPROVE_TDM_IMPORT_SPEED							*
 *	Hong 01/19/10 FIX_FAIL_TO_IMPORT_EMPTY_COL_DUE_TO_FAIL_GET_DATA_TYPE		*
 *	Hong 01/20/10 QA80-14785 IMPROVE_IMPORT_SPEED_FOR_TDM_STRING_COL			*
 *	Sim 02-01-2010 QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS		*
 *	Hong 02/02/10 QA80-15051 IMPRORT_SUPPORT_PROGRESSBAR						*
 *	Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE			*
 * 	Sim 02-03-2010 QA81-15050 ADD_CUSTOM_PROPERTIES_INTO_PAGE_INFO_TREE			*
 *	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			*
 *------------------------------------------------------------------------------*/

#ifndef	DIADEMIMPORT_H
#define	DIADEMIMPORT_H

#include <ocm.h>
#include <.\..\originlab\nilibddc\nilibddc.h>

/// Hong 09/11/07 v8.0700 UPDATE_TO_NEW_DLL_SUPPORT_TDMS
#define _USE_NEW_DLL
/// end UPDATE_TO_NEW_DLL_SUPPORT_TDMS

// for the following parameters macro, all get from .tdm file, so sure always correct
#define DDC_CHANNEL_STORAGE				"sequence_representation"       // Storage
#define CHANNEL_STORAGE					"Storage"
#define DDC_CHANNEL_SOURCE_START_VALUE	"StartValue"       	// StartValue
#define DDC_CHANNEL_SOURCE_STEP_WIDTH	"StepWidth"       	// StepWidth
#define DDC_CHANNEL_MISSING_VALUE_FLAG	"novaluekey"       	// Missing Value Flag
#define MISSING_VALUE_FLAG				"Missing Value Flag"
#define DDC_CHANNEL_MONOTONY			"Monotony"       // Monotony
#define DDC_CHANNEL_WAVEFORM			"WaveForm"       // WaveForm
#define DDC_CHANNEL_WAVEFORM_NAME		"wf_xname"       // WaveForm X-name	
#define DDC_CHANNEL_WAVEFORM_UNIT		"wf_xunit_string"       // WaveForm X-unit
#define DDC_CHANNEL_WAVEFORM_OFFSET		"wf_start_offset"       // WaveForm X-offset
#define DDC_CHANNEL_WAVEFORM_INCREMENT	"wf_increment"      	// WaveForm X-increment
#define CHANNEL_INDEX					"Channel Index"		// index in its channel group
#define CHANNEL_NUMBER					"Channel Number"	// index in all channel group
#define DDC_CHANNEL_DISPLAY_TYPE		"displaytype"       // disply type
#define DISPLAY_TYPE					"DisplayFormat"
#define TDM_TIME_DISPLAY_TYPE			"Time"
#define DAY_OF_A_YEAR					86400
#define DIFF_TIME_OFFSET_BETTEEN_TDM_OC 1721060
///---Sim 02-01-2010 QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
#define DDC_CHANNEL_FILENAME			"ImportFile"
#define DDC_CHANNEL_DATATYPE			"DataType"
///---END QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS

typedef enum	// for temp 
{
	FAIL_GET_CHANNEL_GROUP_NUM = -20,
	FAIL_GET_CHANNEL_GROUPS,
	FAIL_GET_CHANNELS,
	FAIL_GET_CHANNEL_NUM,
	FAIL_ALLOCATE_MEMORY,
	FAIL_GET_CHANNEL,
	FAIL_READ_DATA,
	FAIL_GET_DATA_NUM,
	FAIL_GET_DATA_TYPE,
	UNKNOWN_DATA_TYPE,
	FAIL_GET_DATA,	
	FAIL_USER_CANCEL, /// Hong 02/02/10 QA80-15051 IMPRORT_SUPPORT_PROGRESSBAR
	IMPORTED_SUCCEED = 0,
	
}TDM_ERROR;

///---Sim 02-01-2010 QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
enum
{
	CUSTOM_PROP_CHANNEL_MASK = 0x0003,
	CUSTOM_PROP_CHANNEL_TO_COL_INFO_TREE = 0x0000,
	CUSTOM_PROP_CHANNEL_TO_COL_USER_PARAM = 0x0001,
};
///---END QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS

class DIADemImport
{
public:
	DIADemImport(LPCSTR lpcszFileName)
	{
		m_File = 0;
		m_strFileName = lpcszFileName;
		m_bValidTDM = FALSE;
		
		if( m_strFileName.IsFile() && Open() )
		{
			m_bValidTDM = TRUE;
		}
		
		///---Sim 02-01-2010 QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
		m_dwCustomProperties = 0;
		SetCustomPropertiesChannelBits(CUSTOM_PROP_CHANNEL_TO_COL_INFO_TREE);
		///---END QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
		
		/// Hong 02/02/10 QA80-15051 IMPRORT_SUPPORT_PROGRESSBAR
		m_pProgress = NULL;
		m_nDataCount = 0;
		m_bUserCancel = false;
		/// end IMPRORT_SUPPORT_PROGRESSBAR
	}
	
	~DIADemImport()
	{
		Close();
		/// Hong 02/02/10 QA80-15051 IMPRORT_SUPPORT_PROGRESSBAR
		NICE_SAFE_REMOVAL(m_pProgress);
		/// end IMPRORT_SUPPORT_PROGRESSBAR
	}
	
public:
	
	int ReadFile(WorksheetPage& wp, TreeNode& trSelect, TreeNode& trInfo)
	{
		if( !m_bValidTDM )
			return IMPERR_INVALID_FILE;
		
		m_wp = wp;
		//...read file info for page here		
		TreeNode trFileNode = trInfo.AddNode("File");
		trFileNode.SetAttribute(STR_LABEL_ATTRIB, "File Info");/// Hong 05/24/07 v8.0626 CLEAN_INFO
		///---Sim 02-03-2010 QA81-15050 ADD_CUSTOM_PROPERTIES_INTO_PAGE_INFO_TREE
		//string strFileName;
		//if( !GetFileProperty(trFileNode, DDC_FILE_NAME, strFileName) )
			//m_wp.SetLongName(strFileName, false);
		//GetFileProperty(trFileNode, DDC_FILE_DESCRIPTION, strFileName);
		//GetFileProperty(trFileNode, DDC_FILE_TITLE, strFileName);
		//GetFileProperty(trFileNode, DDC_FILE_AUTHOR, strFileName);
		handelFileInfo(trFileNode, m_File);
		
		TreeNode trFileName = tree_get_node_by_tagname(trFileNode, DDC_FILE_NAME, true);
		if ( trFileName )
			m_wp.SetLongName(trFileName.strVal, false);
		///---END QA81-15050 ADD_CUSTOM_PROPERTIES_INTO_PAGE_INFO_TREE
		
		return ReadGroups(trSelect, trFileNode);
	}
	
	int GetGroupChannelNum( vector<int>& vnChannenNum, vector<string>& vsNames )
	{
		if( !m_bValidTDM )
			return IMPERR_INVALID_FILE;

		string strName;
		for(int ii=0; ii < m_vChannelGroups.GetSize(); ii++)
		{
			Tree trInfo;
			// add channel group name
			if( GetGroupProperty(ii, trInfo, DDC_CHANNELGROUP_NAME, strName) )
				strName.Format("Channel Group #%d", ii+1);
			vsNames.Add(strName);
			// add channel names
			UINT unChannelNum;
			vector<DDCChannelHandle> vChannles;
			
			if( DDC_GetNumChannels(m_vChannelGroups[ii], &unChannelNum) )
				return FAIL_GET_CHANNEL_NUM;
			
			vnChannenNum.Add( unChannelNum );
			
			/// Hong 09/06/07 v8.0697 ALLOW_EMPTY_CHANNEL_GROUP
			//if( unChannelNum <= 0 )
			//	return FAIL_GET_CHANNEL;
			if( unChannelNum < 0 )
				return FAIL_GET_CHANNEL;
			else if ( 0 == unChannelNum )
				continue;
			/// end ALLOW_EMPTY_CHANNEL_GROUP
			
			vChannles.SetSize(unChannelNum);
					
			if( DDC_GetChannels(m_vChannelGroups[ii], vChannles, unChannelNum))
				return FAIL_GET_CHANNEL;
						
			for(int jj=0; jj < vChannles.GetSize(); jj++)
			{
				if( GetChannelProperty(vChannles[jj], trInfo, DDC_CHANNEL_NAME, strName) )
					strName.Format("Channel #%d", jj+1);
				vsNames.Add(strName);
			}
		}
			
		return IMPORTED_SUCCEED;
	}
	
	///---Sim 02-01-2010 QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
	void	SetCustomPropertiesChannelBits(DWORD dw = CUSTOM_PROP_CHANNEL_TO_COL_INFO_TREE)
	{
		m_dwCustomProperties &= !CUSTOM_PROP_CHANNEL_MASK;
		m_dwCustomProperties |= (dw & CUSTOM_PROP_CHANNEL_MASK);
	}
	DWORD	GetCustomPropertiesChannelBits()
	{
		return (m_dwCustomProperties & CUSTOM_PROP_CHANNEL_MASK);
	}
	///---END QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
protected:
	
	int GetFileProperty(TreeNode& trInfo, LPCSTR lpcszProperName, string& strValue)
	{
		int nRet = 0;
		UINT	unLength;
		
		if ( nRet = DDC_GetFileStringPropertyLength(m_File, lpcszProperName, &unLength))
			return nRet;
		nRet = DDC_GetFileProperty(m_File, lpcszProperName, strValue.GetBuffer(unLength + 1), unLength + 1);
		strValue.ReleaseBuffer();
		if ( 0 == nRet )
		{
			///---Sim 02-03-2010 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			//trInfo.AddTextNode(strValue, lpcszProperName);	
			string strTagName(lpcszProperName);
			strTagName.MakeValidCName();
			trInfo.AddTextNode(strValue, strTagName);
			///---END FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
		}
		return nRet;
	}
	
	int GetGroupProperty(int nIndex, TreeNode& trInfo, LPCSTR lpcszProperName, string& strValue)
	{
		int nRet = 0;
		UINT	unLength;
		
		if ( nRet = DDC_GetChannelGroupStringPropertyLength (m_vChannelGroups[nIndex], lpcszProperName, &unLength))
			return nRet;
		
		nRet = DDC_GetChannelGroupProperty(m_vChannelGroups[nIndex], lpcszProperName, strValue.GetBuffer(unLength + 1), unLength + 1);
		strValue.ReleaseBuffer();
		if ( 0 == nRet )
		{
			///---Sim 02-03-2010 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			//trInfo.AddTextNode(strValue, lpcszProperName);	
			string strTagName(lpcszProperName);
			strTagName.MakeValidCName();
			trInfo.AddTextNode(strValue, strTagName);
			///---END FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
		}
		return nRet;
	}
		
	int ReadGroups(TreeNode& trSelect, TreeNode& trInfo)
	{
		//TreeNode trGroups, trGroup; 
		//trGroups = trInfo.AddNode("Groups");
		// no need save to organizer
		Tree trGroup;
		
		/// Hong 02/02/10 QA80-15051 IMPRORT_SUPPORT_PROGRESSBAR
		int			nDataTotalNumber = GetSelectedCount(trSelect);
		NICE_SAFE_REMOVAL(m_pProgress);
		m_pProgress = new progressBox(m_strFileName, PBOX_DEFAULT_STYLE);
		m_pProgress->SetRange(0, nDataTotalNumber);
		m_nDataCount = 0;
		m_bUserCancel = false;
		/// end IMPRORT_SUPPORT_PROGRESSBAR
	
		UINT ii = 0, unChannelNum = 0;
		int nLayers = -1;
		foreach( TreeNode trCG in trSelect.Children )
		{	
			bool bHaveData = false;
			foreach( TreeNode trCC in trCG.Children )
			{
				if(trCC.nVal)
				{
					nLayers++;
					bHaveData = true;
					break;
				}
			}
			if( bHaveData )
			{
				if(m_wp.Layers.Count() == nLayers)
					m_wp.AddLayer();
				Worksheet wks = m_wp.Layers(nLayers);
				//...read channel group info for wks here
				string strName, strDescription;
				//trGroup = trGroups.AddNode("Group"); // no need save to organizer
				if( !GetGroupProperty(ii, trGroup, DDC_CHANNELGROUP_NAME, strName) )
					wks.SetName(strName, OCD_ENUM_NEXT);
				///---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
				//if( !GetGroupProperty(ii, trGroup, DDC_CHANNELGROUP_DESCRIPTION, strDescription) )
					//wks.SetComments(strDescription);		
				///---END QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
				int nRet = IMPORTED_SUCCEED;
				if( nRet = ReadChannels(wks, ii, trCG, trGroup, unChannelNum) )
					return nRet;
			}
			ii++;
		}
		
		return IMPORTED_SUCCEED;
	}
	
	int GetChannelProperty(DDCChannelHandle channel, TreeNode& trInfo, LPCSTR lpcszProperName, string& strValue)
	{
		int nRet = 0;
		UINT	unLength;
		
		if ( nRet = DDC_GetChannelStringPropertyLength (channel, lpcszProperName, &unLength))
			return nRet;
		
		nRet = DDC_GetChannelProperty(channel, lpcszProperName, strValue.GetBuffer(unLength + 1), unLength + 1);
		strValue.ReleaseBuffer();
		
		if ( 0 == nRet )
		{
			/// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			//trInfo.AddTextNode(strValue, lpcszProperName);	
			string strTagName(lpcszProperName);
			strTagName.MakeValidCName();
			trInfo.AddTextNode(strValue, strTagName);
			/// end FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
		}
		
		return nRet;
	}
	///---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
	// need centralize later
	int GetChannelGroupProperty(DDCChannelGroupHandle group, TreeNode& trInfo, LPCSTR lpcszProperName, string& strValue)
	{
		int nRet = 0;
		UINT	unLength;
		
		if ( nRet = DDC_GetChannelGroupStringPropertyLength (group, lpcszProperName, &unLength))
			return nRet;
		
		nRet = DDC_GetChannelGroupProperty(group, lpcszProperName, strValue.GetBuffer(unLength + 1), unLength + 1);
		strValue.ReleaseBuffer();
		
		if ( 0 == nRet )
		{
			/// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			//trInfo.AddTextNode(strValue, lpcszProperName);	
			string strTagName(lpcszProperName);
			strTagName.MakeValidCName();
			trInfo.AddTextNode(strValue, strTagName);
			/// end FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
		}
		
		return nRet;
	}
	///---END QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE

	void handelColumnParameter(Column& col, TreeNode& trInfo, DDCChannelHandle channel, int nChannelIndex, int nChannelNumber)
	{
		string strValue;
		if( !GetChannelProperty(channel, trInfo, DDC_CHANNEL_NAME, strValue) )
			col.SetLongName(strValue);
		if( !GetChannelProperty(channel, trInfo, DDC_CHANNEL_DESCRIPTION, strValue) )
			col.SetComments(strValue);
		if( !GetChannelProperty(channel, trInfo, DDC_CHANNEL_UNIT_STRING, strValue) )
			col.SetUnits(strValue);
		
		StringArray saNames, saValues;
		if( !GetChannelProperty(channel, trInfo, DDC_CHANNEL_MISSING_VALUE_FLAG, strValue) )
		{
			saNames.Add(MISSING_VALUE_FLAG);
			saValues.Add(strValue);
		}	
		if( !GetChannelProperty(channel, trInfo, DDC_CHANNEL_MONOTONY, strValue) )
		{
			saNames.Add(DDC_CHANNEL_MONOTONY);
			saValues.Add(strValue);
		}	
		
		saNames.Add(CHANNEL_INDEX);
		strValue.Format("%d", nChannelIndex);
		saValues.Add(strValue);
		
		saNames.Add(CHANNEL_NUMBER);
		strValue.Format("%d", nChannelNumber);
		saValues.Add(strValue);
	
		///---Sim 02-01-2010 QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
		if ( CUSTOM_PROP_CHANNEL_TO_COL_USER_PARAM == GetCustomPropertiesChannelBits() )
		{
			Tree trUserInfo;
			getChannelInfo(trUserInfo, channel);
			GetCustomProperties(saNames, saValues, trUserInfo);
		}		
		///---END QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
		
		set_user_parameters(col, saNames, saValues);
	}
#ifdef _USE_NEW_DLL
	/// Hong 03/27/07 v8.0590 MORE_PARAMETER_SUPPORT_BY_NEW_DLL
	bool AddChannelPropertyToTree(TreeNode& trInfo, DDCChannelHandle channel, LPCSTR lpszProName)
	{
		int nRet = 0;
		
		DDCDataType ddcType;
		if ( nRet = DDC_GetChannelPropertyType(channel, lpszProName, &ddcType) )
			return false;
		
		/// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
		string strTagName(lpszProName);
		strTagName.MakeValidCName();
		/// end FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
		
		switch(ddcType)
		{
		case DDC_String:
			Tree trTemp;
			string strVal;
			if( !GetChannelProperty(channel, trTemp, lpszProName, strVal) )
				//trInfo.AddTextNode(strVal, lpszProName);
				trInfo.AddTextNode(strVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			break;
		case DDC_UInt8:
			BYTE byVal;
			
			nRet = DDC_GetChannelProperty(channel, lpszProName, &byVal, sizeof(BYTE));

			if ( 0 == nRet )
				//trInfo.AddNumericNode(byVal, lpszProName);	
				trInfo.AddNumericNode(byVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			
			break;
		case DDC_Int16:
			short nVal;
			nRet = DDC_GetChannelProperty(channel, lpszProName, &nVal, sizeof(short));

			if ( 0 == nRet )
				//trInfo.AddNumericNode(nVal, lpszProName);	
				trInfo.AddNumericNode(nVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
	
			break;
		case DDC_Int32:
			LONG nVal;
			nRet = DDC_GetChannelProperty(channel, lpszProName, &nVal, sizeof(LONG));
			
			if ( 0 == nRet )
				//trInfo.AddNumericNode(nVal, lpszProName);
				trInfo.AddNumericNode(nVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			
			break;				
		case DDC_Float:
			float fVal;	
			nRet = DDC_GetChannelProperty(channel, lpszProName, &fVal, sizeof(float));
			
			if ( 0 == nRet )
				//trInfo.AddNumericNode(fVal, lpszProName);	
				trInfo.AddNumericNode(fVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			
			break;
		case DDC_Double:
			double dVal;		
			nRet = DDC_GetChannelProperty(channel, lpszProName, &dVal, sizeof(double));
			
			if ( 0 == nRet )
				//trInfo.AddNumericNode(dVal, lpszProName);	
				trInfo.AddNumericNode(dVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			
			break;				
		}
		
		if( nRet )
			return false;
		
		return true;
	}
	
	void getChannelInfo(TreeNode& trInfo, DDCChannelHandle channel)
	{
		int nRet = 0;

		UINT unNumProperty;
		if( nRet = DDC_GetNumChannelProperties(channel, &unNumProperty) )
			return;

		vector<string> vs;
		
		char **pPropertyNames = NULL;
		
		pPropertyNames = (char**)malloc(unNumProperty * sizeof(DWORD));


		DDC_GetChannelPropertyNames(channel, pPropertyNames, unNumProperty);
		
		for(UINT ii=0; ii < unNumProperty; ii++)
		{
			vs.Add((char*)pPropertyNames[ii]);
			DDC_FreeMemory (pPropertyNames[ii]);
		}
		
		free(pPropertyNames);
		
		if( nRet ) // not return before free momery
			return;
		
		for(int nIdx=0; nIdx < vs.GetSize(); nIdx++)
		{
			AddChannelPropertyToTree(trInfo, channel, vs[nIdx]);
		}
	}
	/// end MORE_PARAMETER_SUPPORT_BY_NEW_DLL
	///---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
	// need centralize later
	bool AddChannelGroupPropertyToTree(TreeNode& trInfo, DDCChannelGroupHandle group, LPCSTR lpszProName)
	{
		int nRet = 0;
		
		DDCDataType ddcType;
		if ( nRet = DDC_GetChannelGroupPropertyType(group, lpszProName, &ddcType) )
			return false;
		
		/// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
		string strTagName(lpszProName);
		strTagName.MakeValidCName();
		/// end FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
		
		switch(ddcType)
		{
		case DDC_String:
			Tree trTemp;
			string strVal;
			if( !GetChannelGroupProperty(group, trTemp, lpszProName, strVal) )
				//trInfo.AddTextNode(strVal, lpszProName);
				trInfo.AddTextNode(strVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			break;
		case DDC_UInt8:
			BYTE byVal;
			
			nRet = DDC_GetChannelGroupProperty(group, lpszProName, &byVal, sizeof(BYTE));

			if ( 0 == nRet )
				//trInfo.AddNumericNode(byVal, lpszProName);	
				trInfo.AddNumericNode(byVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			
			break;
		case DDC_Int16:
			short nVal;
			nRet = DDC_GetChannelGroupProperty(group, lpszProName, &nVal, sizeof(short));

			if ( 0 == nRet )
				//trInfo.AddNumericNode(nVal, lpszProName);	
				trInfo.AddNumericNode(nVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
	
			break;
		case DDC_Int32:
			LONG nVal;
			nRet = DDC_GetChannelGroupProperty(group, lpszProName, &nVal, sizeof(LONG));
			
			if ( 0 == nRet )
				//trInfo.AddNumericNode(nVal, lpszProName);
				trInfo.AddNumericNode(nVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			
			break;				
		case DDC_Float:
			float fVal;	
			nRet = DDC_GetChannelGroupProperty(group, lpszProName, &fVal, sizeof(float));
			
			if ( 0 == nRet )
				//trInfo.AddNumericNode(fVal, lpszProName);	
				trInfo.AddNumericNode(fVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			
			break;
		case DDC_Double:
			double dVal;		
			nRet = DDC_GetChannelGroupProperty(group, lpszProName, &dVal, sizeof(double));
			
			if ( 0 == nRet )
				//trInfo.AddNumericNode(dVal, lpszProName);	
				trInfo.AddNumericNode(dVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			
			break;				
		}
		
		if( nRet )
			return false;
		
		return true;
	}
	
	void getGroupInfo(TreeNode& trInfo, DDCChannelGroupHandle group)
	{
		int nRet = 0;

		UINT unNumProperty;
		if( nRet = DDC_GetNumChannelGroupProperties(group, &unNumProperty) )
			return;

		vector<string> vs;
		
		char **pPropertyNames = NULL;
		
		pPropertyNames = (char**)malloc(unNumProperty * sizeof(DWORD));


		DDC_GetChannelGroupPropertyNames(group, pPropertyNames, unNumProperty);
		
		for(UINT ii=0; ii < unNumProperty; ii++)
		{
			vs.Add((char*)pPropertyNames[ii]);
			DDC_FreeMemory (pPropertyNames[ii]);
		}
		
		free(pPropertyNames);
		
		if( nRet ) // not return before free momery
			return;
		
		for(int nIdx=0; nIdx < vs.GetSize(); nIdx++)
		{
			AddChannelGroupPropertyToTree(trInfo, group, vs[nIdx]);
		}
	}
	///---END QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
	
	///---Sim 02-03-2010 QA81-15050 ADD_CUSTOM_PROPERTIES_INTO_PAGE_INFO_TREE
	// need centralize later
	bool AddFilePropertyToTree(TreeNode& trInfo, DDCFileHandle fl, LPCSTR lpszProName)
	{
		int nRet = 0;
		
		DDCDataType ddcType;
		if ( nRet = DDC_GetFilePropertyType(fl, lpszProName, &ddcType) )
			return false;
		
		/// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
		string strTagName(lpszProName);
		strTagName.MakeValidCName();
		/// end FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
		
		switch(ddcType)
		{
		case DDC_String:
			Tree trTemp;
			string strVal;
			if( !GetFileProperty(trTemp, lpszProName, strVal) )
				//trInfo.AddTextNode(strVal, lpszProName);
				trInfo.AddTextNode(strVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			break;
		case DDC_UInt8:
			BYTE byVal;
			
			nRet = DDC_GetFileProperty(fl, lpszProName, &byVal, sizeof(BYTE));

			if ( 0 == nRet )
				//trInfo.AddNumericNode(byVal, lpszProName);	
				trInfo.AddNumericNode(byVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			
			break;
		case DDC_Int16:
			short nVal;
			nRet = DDC_GetFileProperty(fl, lpszProName, &nVal, sizeof(short));

			if ( 0 == nRet )
				//trInfo.AddNumericNode(nVal, lpszProName);	
				trInfo.AddNumericNode(nVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
	
			break;
		case DDC_Int32:
			LONG nVal;
			nRet = DDC_GetFileProperty(fl, lpszProName, &nVal, sizeof(LONG));
			
			if ( 0 == nRet )
				//trInfo.AddNumericNode(nVal, lpszProName);
				trInfo.AddNumericNode(nVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			
			break;				
		case DDC_Float:
			float fVal;	
			nRet = DDC_GetFileProperty(fl, lpszProName, &fVal, sizeof(float));
			
			if ( 0 == nRet )
				//trInfo.AddNumericNode(fVal, lpszProName);	
				trInfo.AddNumericNode(fVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			
			break;
		case DDC_Double:
			double dVal;		
			nRet = DDC_GetFileProperty(fl, lpszProName, &dVal, sizeof(double));
			
			if ( 0 == nRet )
				//trInfo.AddNumericNode(dVal, lpszProName);	
				trInfo.AddNumericNode(dVal, strTagName); /// Hong 09/06/07 v8.0697 FIX_RUNTIME_IF_INVALID_TREE_TAGNAME
			
			break;				
		}
		
		if( nRet )
			return false;
		
		return true;
	}
	
	void getFileInfo(TreeNode& trInfo, DDCFileHandle fl)
	{
		int nRet = 0;

		UINT unNumProperty;
		if( nRet = DDC_GetNumFileProperties(fl, &unNumProperty) )
			return;

		vector<string> vs;
		
		char **pPropertyNames = NULL;
		
		pPropertyNames = (char**)malloc(unNumProperty * sizeof(DWORD));


		DDC_GetFilePropertyNames(fl, pPropertyNames, unNumProperty);
		
		for(UINT ii=0; ii < unNumProperty; ii++)
		{
			vs.Add((char*)pPropertyNames[ii]);
			DDC_FreeMemory (pPropertyNames[ii]);
		}
		
		free(pPropertyNames);
		
		if( nRet ) // not return before free momery
			return;
		
		for(int nIdx=0; nIdx < vs.GetSize(); nIdx++)
		{
			AddFilePropertyToTree(trInfo, fl, vs[nIdx]);
		}
	}
	///---END QA81-15050 ADD_CUSTOM_PROPERTIES_INTO_PAGE_INFO_TREE
#endif // _USE_NEW_DLL	
	void handelColumnUserInfo(Column& col, TreeNode& trInfo, DDCChannelHandle channel, int nGroupIndex, int nChannelIndex, bool bHasWaveform, bool& bTime)
	{
		///---Sim 02-04-2010 QA81-15063 MOVE_IMP_FILE_INFO_OUT_FROM_COL_USER_INFO_TREE
		//Tree trUserInfo;
		/////---Sim 02-01-2010 QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
		////trUserInfo.AddTextNode(m_strFileName, "ImportFile");
		//TreeNode trFileName = trUserInfo.AddTextNode(m_strFileName, DDC_CHANNEL_FILENAME);
		/////---END QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
		/////---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
		//// keep compatibility for old code
		//trUserInfo.Enable = ENABLE_READ_ONLY;
		//trUserInfo.Show = 0;
		//trUserInfo.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
		//string strName("ColumnInfo");
		//set_user_info(col, strName, trUserInfo);
//
		//set_import_file_info(col, trFileName, DDC_CHANNEL_FILENAME);
		fu_set_import_file_name_info(col, m_strFileName, IMPORT_INFO_TO_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_strFileName);
		///---END QA81-15063 ROLL_BACK_MOVE_COL_INFO_OUT_OF_USER_TREE
		///---END QA81-15063 MOVE_IMP_FILE_INFO_OUT_FROM_COL_USER_INFO_TREE
		
		Tree trChannelInfo;
		///---END QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
		string strValue;
		if( !GetChannelProperty(channel, trInfo, DDC_CHANNEL_DISPLAY_TYPE, strValue) )
		{
			if( 0 == strValue.CompareNoCase(TDM_TIME_DISPLAY_TYPE))
				bTime = true;
			///---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
			//trUserInfo.AddTextNode(strValue, DISPLAY_TYPE);
			trChannelInfo.AddTextNode(strValue, DISPLAY_TYPE);
			///---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
		}	
		UINT unType;
		if( !DDC_GetDataType(channel, &unType) )
		{
			switch(unType)
			{
			case DDC_UInt8:
				strValue = "unsigned char";
				break;
			case DDC_Int16:
				strValue = "short";
				break;
			case DDC_Int32:
				strValue = "int";
				break;
			case DDC_Float:
				strValue = "float";
				break;
			case DDC_Double:
				strValue = "double";
				break;
			case DDC_String:
				strValue = "string";
				break;
			default:
				/// Hong 09/13/07 LOCALIZATION_ERR_MSG
				// no need duplicate dump warning message as when reading we have already detected this error
				//ASSERT(FALSE);
				//out_str("please check unsuuport data type, and contact andrew");
				strValue = "unknown";
				/// end LOCALIZATION_ERR_MSG
				break;
			}
			///---Sim 02-01-2010 QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
			//trUserInfo.AddTextNode(strValue, "DataType");
			///---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
			//trUserInfo.AddTextNode(strValue, DDC_CHANNEL_DATATYPE);
			trChannelInfo.AddTextNode(strValue, DDC_CHANNEL_DATATYPE);
			///---END QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
			///---END QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
		}
		// fail to get by this
		/*
		if( !GetChannelProperty(channel, trInfo, DDC_CHANNEL_STORAGE, strValue) )
			trUserInfo.AddTextNode(strValue, CHANNEL_STORAGE);

		if( !GetChannelProperty(channel, trInfo, DDC_CHANNEL_SOURCE_START_VALUE, strValue) )
			trUserInfo.AddTextNode(strValue, DDC_CHANNEL_SOURCE_START_VALUE);
		
		if( !GetChannelProperty(channel, trInfo, DDC_CHANNEL_SOURCE_STEP_WIDTH, strValue) )
			trUserInfo.AddTextNode(strValue, DDC_CHANNEL_SOURCE_STEP_WIDTH);
		*/
		if( bHasWaveform )
		{
			///---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
			//trUserInfo.AddTextNode("Yes", DDC_CHANNEL_WAVEFORM);
			trChannelInfo.AddTextNode("Yes", DDC_CHANNEL_WAVEFORM);
			///---END QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
		}
		else
		{
			///---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
			//trUserInfo.AddTextNode("No", DDC_CHANNEL_WAVEFORM);
			trChannelInfo.AddTextNode("No", DDC_CHANNEL_WAVEFORM);
			///---END QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
		}
	#ifdef _USE_NEW_DLL
		/// Hong 03/27/07 v8.0590 MORE_PARAMETER_SUPPORT_BY_NEW_DLL
		///---Sim 02-01-2010 QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
		if ( CUSTOM_PROP_CHANNEL_TO_COL_INFO_TREE == GetCustomPropertiesChannelBits() ) 
		///---END QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
			///---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
			//getChannelInfo(trUserInfo, channel);
			getChannelInfo(trChannelInfo, channel);
			///---END QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
		/// end MORE_PARAMETER_SUPPORT_BY_NEW_DLL
	#endif // _USE_NEW_DLL
		///---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
		//trUserInfo.Enable = ENABLE_READ_ONLY;
		//trUserInfo.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
		//string strName("ColumnInfo");
		//set_user_info(col, strName, trUserInfo);
		trChannelInfo.Enable = ENABLE_READ_ONLY;
		trChannelInfo.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
		///---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
		//set_import_file_info(col, trChannelInfo, "TDMSChan");
		set_user_info(col, (string)"TDMSChan", trChannelInfo);
		///---END QA81-15063 ROLL_BACK_MOVE_COL_INFO_OUT_OF_USER_TREE
		///---END QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
	}
	///---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
	void handelWksUserInfo(Worksheet& wks, TreeNode& trInfo, DDCChannelGroupHandle group)
	{
		Tree trGroup;
		getGroupInfo(trGroup, group);
		trGroup.Enable = ENABLE_READ_ONLY;
		trGroup.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
		set_import_file_info(wks, trGroup, "TDMSGroup");
	}
	///---END QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
	///---Sim 02-03-2010 QA81-15050 ADD_CUSTOM_PROPERTIES_INTO_PAGE_INFO_TREE
	void handelFileInfo(TreeNode& trInfo, DDCFileHandle fl)
	{
		getFileInfo(trInfo, fl);
	}
	///---END QA81-15050 ADD_CUSTOM_PROPERTIES_INTO_PAGE_INFO_TREE
	
	int ReadChannels(Worksheet& wks, UINT unIndex, TreeNode& trSelect, TreeNode& trInfo, UINT& unChNum)
	{
		//TreeNode trChannels, trChannel; // no need save to organizer
		Tree trChannel;
		UINT unChannelNum;
		vector<DDCChannelHandle> vChannles;
		
		if( DDC_GetNumChannels(m_vChannelGroups[unIndex], &unChannelNum) )
			return FAIL_GET_CHANNEL_NUM;
		
		if( unChannelNum <= 0 )
			return FAIL_GET_CHANNEL;
		
		//trChannels = trInfo.AddNode("Channels"); // no need save to organizer
		vChannles.SetSize(unChannelNum);
				
		if( DDC_GetChannels(m_vChannelGroups[unIndex], vChannles, unChannelNum))
			return FAIL_GET_CHANNEL;
		/// Hong 02/25/07 FIX_SHOULD_NOT_CLEAN_EXISTING_USER_PARAMETER
		//wks.SetSize(0, 0);
		int nCount = wks.GetNumCols();
		int nColIdx = 0;
		/// end FIX_SHOULD_NOT_CLEAN_EXISTING_USER_PARAMETER
		/// Hong 12/03/09 QA80-14785 IMPROVE_TDM_IMPORT_SPEED
		int	nSelCount = GetSelectedCount(trSelect);
		if ( nSelCount + nColIdx > nCount )
		{
			nCount = nSelCount + nColIdx;
			wks.SetSize(-1, nCount);
		}
		bool	bHasUpdatedLabelShown = false;
		/// end IMPROVE_TDM_IMPORT_SPEED
		UINT ii = 0;
		foreach( TreeNode trCC in trSelect.Children )
		{
			if(trCC.nVal)
			{
				/// Hong 02/25/07 FIX_SHOULD_NOT_CLEAN_EXISTING_USER_PARAMETER
				//Column col = wks.Columns(wks.AddCol());	
				/// Hong 12/03/09 QA80-14785 IMPROVE_TDM_IMPORT_SPEED
				//if(nColIdx >= nCount)
				//	wks.AddCol();
				ASSERT( nCount > nColIdx );
				/// end IMPROVE_TDM_IMPORT_SPEED
				Column col = wks.Columns(nColIdx++);	
				/// end FIX_SHOULD_NOT_CLEAN_EXISTING_USER_PARAMETER
				//...read channel info for column here
				//trChannel = trChannels.AddNode("Channel"); // no need save to organizer
				handelColumnParameter(col, trChannel, vChannles[ii], ii + 1, unChNum + 1);
				
				// set waveform 
				int nWavRet = 0;
				bool bHasWaveform = false;
				string strWFName, strWFUnit;
				double dOffset, dIncrement;
				nWavRet += GetChannelProperty(vChannles[ii], trChannel, DDC_CHANNEL_WAVEFORM_NAME, strWFName);
				nWavRet += GetChannelProperty(vChannles[ii], trChannel, DDC_CHANNEL_WAVEFORM_UNIT, strWFUnit);		
				nWavRet += DDC_GetChannelProperty(vChannles[ii], DDC_CHANNEL_WAVEFORM_OFFSET, &dOffset, sizeof(double));
				nWavRet += DDC_GetChannelProperty(vChannles[ii], DDC_CHANNEL_WAVEFORM_INCREMENT, &dIncrement, sizeof(double));
				if( 0 == nWavRet )					
				{
					bHasWaveform = true;
					wks.SetEvenSampling((float)dOffset, (float)dIncrement, col, strWFUnit, strWFName );
					/// Hong 12/10/07 v8.0765 NITDM_SHOW_SAMPLE_RATE_ROW_IF_HAVE
					/// Hong 12/03/09 QA80-14785 IMPROVE_TDM_IMPORT_SPEED
					if ( !bHasUpdatedLabelShown )
					{
					/// end IMPROVE_TDM_IMPORT_SPEED
						vector<int> vn = {RCLT_SAMPLE_RATE};
						wks_add_show_labels(wks, vn, false);
					/// Hong 12/03/09 QA80-14785 IMPROVE_TDM_IMPORT_SPEED
						bHasUpdatedLabelShown = true;
					}
					/// end IMPROVE_TDM_IMPORT_SPEED
					/// end NITDM_SHOW_SAMPLE_RATE_ROW_IF_HAVE
				}
				// add user parameters here
				bool bTime = false;
				handelColumnUserInfo(col, trChannel, vChannles[ii], ii + 1, unChNum + 1, bHasWaveform, bTime);
				
				int nRet = IMPORTED_SUCCEED;
				if( nRet = ReadData(col, vChannles[ii], trChannel, bTime) )
					return nRet;
			
			/// Hong 02/02/10 QA80-15051 IMPRORT_SUPPORT_PROGRESSBAR
			m_pProgress->Set(m_nDataCount++);
			if ( m_pProgress->IsAbort() )
				return FAIL_USER_CANCEL;
			/// end IMPRORT_SUPPORT_PROGRESSBAR

			}
			ii++;
			unChNum++;
		}
		
		///---Sim 02-02-2010 QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
		handelWksUserInfo(wks, trInfo, m_vChannelGroups[unIndex]);
		///---END QA81-15063 ADD_CUSTOM_PROPERTIES_INTO_WKS_INFO_TREE
		
		return IMPORTED_SUCCEED;
	}
	
	int _get_data_type(UINT unType)
	{
		int nDataType; 
	
		switch(unType)
		{
		case DDC_UInt8:
			nDataType = FSI_BYTE;
			break;
		case DDC_Int16:
			nDataType = FSI_SHORT;
			break;
		case DDC_Int32:
			nDataType = FSI_LONG;
			break;
		case DDC_Float:
			nDataType = FSI_REAL;
			break;
		case DDC_Double:
			nDataType = FSI_DOUBLE;
			break;
		case DDC_String:
			nDataType = FSI_TEXT;
			break;
		default:
			/// Hong 09/13/07 LOCALIZATION_ERR_MSG
			//ASSERT(FALSE);
			//out_str("please check unsuuport data type, and contact andrew");
			warning_msg_box(IMPERR_UNKNOW_TYPE, false);
			/// end LOCALIZATION_ERR_MSG
			nDataType = FSI_MIXED;
			break;
		}
		return nDataType;
	}
	
	int ReadData(Column& col, DDCChannelHandle channel, TreeNode& trInfo, bool bTime)
	{
		UINT arrDataValue[2];
		
		if( DDC_GetNumDataValues(channel, arrDataValue) )
			return FAIL_GET_DATA_NUM;
		
		/// Hong 12/10/07 v8.0765 NITDM_ALLOW_IMPORT_EMPTY_COLUMN
		//if( arrDataValue[0] <= 0 )
		if( arrDataValue[0] < 0 )
		/// end NITDM_ALLOW_IMPORT_EMPTY_COLUMN
			return FAIL_GET_DATA;
			
		/// Hong 01/19/10 FIX_FAIL_TO_IMPORT_EMPTY_COL_DUE_TO_FAIL_GET_DATA_TYPE
		if ( 0 == arrDataValue[0] )
		{
			col.SetNumRows(arrDataValue[0]);
			return IMPORTED_SUCCEED;
		}
		/// end FIX_FAIL_TO_IMPORT_EMPTY_COL_DUE_TO_FAIL_GET_DATA_TYPE
		
		UINT unType;
		if( DDC_GetDataType(channel, &unType) )
			return FAIL_GET_DATA_TYPE;
		
		/// Hong 12/03/09 QA80-14785 IMPROVE_TDM_IMPORT_SPEED
		//vector vData;
		//vData.SetSize(arrDataValue[0]);
		/// end IMPROVE_TDM_IMPORT_SPEED
		
		col.SetInternalData( _get_data_type(unType) );
		
		if( DDC_String == unType)
		{
			// need special care
			/// Hong 01/20/10 QA80-14785 IMPROVE_IMPORT_SPEED_FOR_TDM_STRING_COL
			/*
			vector<string> vstrVal;
			vstrVal.SetSize(arrDataValue[0]);
			vector<DWORD> dwTemp;
			dwTemp.SetSize(arrDataValue[0]);

			if( DDC_GetDataValues(channel, 0, arrDataValue[0], dwTemp) )
				return FAIL_GET_DATA;
			
			for(int ii=0; ii < arrDataValue[0]; ii++)
			/// Hong 03/27/07 V8.0590 FREE_MEMORY_ALLOCATED_BY_DLL
			//vstrVal[ii] = (char *)dwTemp[ii];
			{
				vstrVal[ii] = (char *)dwTemp[ii];
				DDC_FreeMemory( (char *)dwTemp[ii] );
			}
			/// end FREE_MEMORY_ALLOCATED_BY_DLL
			
			col.SetFormat(OKCOLTYPE_TEXT);
			col.PutStringArray(vstrVal);
			*/
			pfnDDC_GetValues pfnGetValues = DDC_GetDataValues;
			pfnDDC_FreeMemory pfnFreeMemory = DDC_FreeMemory;
			col.ImportTDMStringValues(pfnGetValues, channel, arrDataValue[0], pfnFreeMemory);
			/// end IMPROVE_IMPORT_SPEED_FOR_TDM_STRING_COL
		}
		else
		{
			int nElementSize;				
			UINT nNumElements;	
			col.SetUpperBound( arrDataValue[0] - 1 );   
			LPVOID lpData = col.GetInternalDataBuffer(&nElementSize, &nNumElements);
			DDC_GetDataValues(channel, 0, arrDataValue[0], lpData);
			
			if( FSI_DOUBLE == col.GetInternalData() )
				ocm_check_infinite_value((double*)lpData, arrDataValue[0]);
		}
		
		if( bTime )
		{
			Dataset ds(col);
			ds = ds/DAY_OF_A_YEAR + DIFF_TIME_OFFSET_BETTEEN_TDM_OC;
			col.SetFormat(OKCOLTYPE_DATE);
		}

		return IMPORTED_SUCCEED;
	}
	
	///---Sim 02-01-2010 QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
	bool IsCustomProperty(LPCSTR lpcszName)
	{
		StringArray saNames = {DDC_CHANNEL_FILENAME, DDC_CHANNEL_DATATYPE, DDC_CHANNEL_WAVEFORM, DDC_CHANNEL_NAME, DDC_CHANNEL_DESCRIPTION, DDC_CHANNEL_UNIT_STRING};
		for ( int ii = 0; ii < saNames.GetSize(); ii++ )
		{
			if ( 0 == lstrcmp(lpcszName, saNames[ii]) )
				return false;
		}
		
		return true;
	}
	
	int GetCustomProperties(vector<string>& m_vsNames, vector<string>& m_vsValues, const TreeNode trProperties)
	{
		foreach ( TreeNode tr in trProperties.Children )
		{
			string strName;
			strName = tr.tagName;
			tr.GetAttribute(STR_LABEL_ATTRIB, strName);
			
			if ( !IsCustomProperty(strName) )
				continue;
			
			int nPos = m_vsNames.Find(strName);
			if ( nPos < 0 )
			{
				m_vsNames.Add(strName);
				m_vsValues.Add("");
				nPos = m_vsNames.GetSize() - 1;
			}
			
			m_vsValues[nPos] = tr.strVal;
		}
		
		return 0;
	}
	///---END QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
	
protected:
	BOOL Open()
	{
	/// Hong 09/11/07 v8.0700 UPDATE_TO_NEW_DLL_SUPPORT_TDMS
	/*
		/// Hong 03/14/07 UDPATE_USER_NEW_DLL	
	#ifndef _USE_NEW_DLL
		if( DDC_OpenFile(m_strFileName, "TDM", &m_File) )
	#else // _USE_NEW_DLL
		if( DDC_OpenFileEx(m_strFileName, "TDM", TRUE, &m_File) )
	#endif // _USE_NEW_DLL
		/// end UDPATE_USER_NEW_DLL
			return FALSE;
	*/
	#ifndef _USE_NEW_DLL
		if( DDC_OpenFile(m_strFileName, NULL, &m_File) )
	#else // _USE_NEW_DLL
		if( DDC_OpenFileEx(m_strFileName, NULL, TRUE, &m_File) )
	#endif // _USE_NEW_DLL
		return false;
	/// end UPDATE_TO_NEW_DLL_SUPPORT_TDMS
		//initial class members
		if( DDC_GetNumChannelGroups(m_File, &m_unGroupNum) )
			return FALSE;
	
		if(m_unGroupNum <= 0)
			return FALSE;
		
		m_vChannelGroups.SetSize(m_unGroupNum);
		
		if( DDC_GetChannelGroups(m_File, m_vChannelGroups, m_unGroupNum) )
			return FALSE;
		
		return TRUE;
	}
	
	BOOL Close()
	{
		if( DDC_CloseFile(m_File) )
			return FALSE;
		
		return TRUE;
	}
	/// Hong 12/03/09 QA80-14785 IMPROVE_TDM_IMPORT_SPEED
	int	GetSelectedCount(TreeNode& tr)
	{
		int		nSel = 0;
		foreach ( TreeNode trNode in tr.Children )
		{
			/// Hong 02/02/10 QA80-15051 IMPRORT_SUPPORT_PROGRESSBAR
			if ( trNode.FirstNode )
				nSel += GetSelectedCount(trNode);
			else
			/// end IMPRORT_SUPPORT_PROGRESSBAR
			if ( trNode.nVal )
				nSel++;
		}
		return nSel;
	}
	/// end IMPROVE_TDM_IMPORT_SPEED
private:
	string		m_strFileName;
	UINT		m_unGroupNum;
	DDCFileHandle	m_File;
	vector<DDCChannelGroupHandle>	m_vChannelGroups;
	BOOL		m_bValidTDM;
	WorksheetPage	m_wp;
	
	///---Sim 02-01-2010 QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
	DWORD		m_dwCustomProperties;
	///---END QA81-15050-P1 ADD_CUSTOM_PROPERTIES_INTO_COL_PARAMETERS
	/// Hong 02/02/10 QA80-15051 IMPRORT_SUPPORT_PROGRESSBAR
	progressBox*	m_pProgress;
	int			m_nDataCount;
	bool		m_bUserCancel;
	/// end IMPRORT_SUPPORT_PROGRESSBAR
};

#endif //DIADEMIMPORT_H
