#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	mode_mono,
	mode_stereo,
};
enum{
	bits_bit8,
	bits_bit16,
	bits_bit32,
};
//put additional include files here
#include <GetNBox.h>

#ifdef _FOR_SMART_LODING_ONLY
	#include <..\originlab\file_utils.h>
	#include <..\Originlab\fu_utils.h>
#endif //_FOR_SMART_LODING_ONLY

#include <..\originlab\exportWAV.h>
#include <okocUtils.h>		///Folger 04/16/07 REPLACE_BY_OKOC_OUT_MSG

#define STR_WAVE_FILE_GROUP "Sound" ///---Sim 05-25-2007 GET_DEFAULT_FROM_ORIGIN_OPTIONS
//#define STR_ONLY_FILE_NAME_ATTRIB  "OnlyFileName"///---Jake 06/27/07 STORE_USER_FILE_NAME
//put your own support static functions here

///---Sim 05-25-2007 GET_DEFAULT_FROM_ORIGIN_OPTIONS
static string _get_default_path()
{
	string strPath = get_file_group_default_path(STR_WAVE_FILE_GROUP);
	if ( strPath.IsEmpty() )
		strPath = GetAppPath(FALSE);
	
	return strPath;
}
///---END GET_DEFAULT_FROM_ORIGIN_OPTIONS

///---Sim 03-17-2008 FIX_CHECK_FILE_EXTENSION
/*
static bool _check_add_file_ext(string& strFile)
{
	string strFilepath = strFile;
	string strFname, strFext, strExt;	
	if( !separate_file_name_ext(strFilepath, strFname, strFext) || 0 != strFext.CompareNoCase("wav") )
	{
		strFile = strFname + ".wav";
		return true;
	}
	return false; // no change
}
*/
#define WAVE_FILE_EXT	"wav"
///---END FIX_CHECK_FILE_EXTENSION

/// Hong 03/05/07 ADD_ERROR_CHECK
static bool _gui_check_update_path(TreeNode& trGetN)
{	
	TreeNode 	trPath = trGetN.fname;

	//get path, if path is empty, get current file path
	string		strPath = trPath.strVal;
	
	if(strPath.IsEmpty() || strPath == STR_UNASSIGNED)
		///---Sim 05-25-2007 GET_DEFAULT_FROM_ORIGIN_OPTIONS
		//strPath = GetAppPath();
		strPath = _get_default_path();
		///---END GET_DEFAULT_FROM_ORIGIN_OPTIONS
	
	/// Iris 07/03/2007 v8.0654 USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
	bool 	bIsSpecialPath = str_is_predefined_path(strPath);
	if(bIsSpecialPath)
		strPath = cvt_predefined_path_to_real_path(strPath);
	///end USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL

	//----Jake 06/26/07 GET_COMBO_LIST_FROM_REGISTRY
	int nID = okutil_cvt_str_to_predefined_type(strPath);
	if( nID != PDS_INVALID && nID != PDS_USER)
		strPath = cvt_predefined_path_to_real_path(strPath);
	//----end GET_COMBO_LIST_FROM_REGISTRY
	
	//get ext and filname from path
	string strFile, strExtFromPath;
	separate_file_name_ext(strPath, strFile, strExtFromPath);
	string strFilename = GetFileName(strFile); //strFile have path
	
	/// Hong 09/17/07 QA80-10381 SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
	/*
	//if fil name is empty, use actived wks'name as file name
	string strWksName;
	Worksheet	wks;
	//okxf_resolve_string_get_origin_object(trGetN.wks.strVal, &wks);
	DataRange dr;
	TreeNode trXY = trGetN.irng;
	okxf_resolve_tree_construct_range(&trXY, &dr);
	//if(!wks)
	if ( !check_get_wks(dr, wks) )
		return false;
//	strWksName = wks.GetName();//Jake 06/27/07 should get file name from STR_FILENAME_ATTRIB
	*/
	/// end SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
	
	if(strFilename.IsEmpty())
	{
		//----Jake 06/27/07 GET_FILE_NAME_FROM_STR_ONLY_FILENAME_ATTRIB
		//strFile = GetFilePath(strFile) + strWksName;
		///---Sim 07-13-2007 FIX_WHEN_EMPTY_FILE_NAME
		//trPath.GetAttribute(STR_ONLY_FILENAME_ATTRIB,strFilename);
		string strVal;
		if ( trPath.GetAttribute(STR_ONLY_FILENAME_ATTRIB, strVal) )
			strFilename = strVal;
		else
		{
			/// Hong 09/17/07 QA80-10381 SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
			Worksheet wks;
			okxf_resolve_string_get_origin_object(trGetN.iw.strVal, &wks);
			if ( !wks )
				return false;
			/// end SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
			strFilename = wks.GetName();
		}
		///---END FIX_WHEN_EMPTY_FILE_NAME
		strFile = GetFilePath(strFile) + strFilename;
		//----end GET_FILE_NAME_FROM_STR_ONLY_FILENAME_ATTRIB
	}
	
	//update path in GUI
	/// Iris 07/04/2007 v8.0654 USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
	if( bIsSpecialPath )
	{
		strPath = trPath.strVal;
	}
	else
	///end USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
	{
		//----Jake 06/27/07 ADD_EXT_FOR_FILE_NAME
		//strPath =  strFile + ".wav";
		strPath = strFile;
		///---Sim 03-17-2008 FIX_CHECK_FILE_EXTENSION
		//_check_add_file_ext(strPath);
		add_file_extension(strPath, WAVE_FILE_EXT);
		///---Sim 05-07-2009 QA80-13571 FIX_CRASH_WHEN_FILE_PATH_LENGTH_IS_TOO_LONG
#ifdef CHECK_EXCEED_FILE_PATH_LENGTH_LIMITATION
		check_trim_file_path_if_too_long(strPath);
#endif
		///---END QA80-13571 FIX_CRASH_WHEN_FILE_PATH_LENGTH_IS_TOO_LONG
		///---END FIX_CHECK_FILE_EXTENSION
		//----end ADD_EXT_FOR_FILE_NAME
	}
	
	trPath.strVal = strPath;
	
	/// Iris 07/04/2007 v8.0654 USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
	//tree_set_only_file_name_attrib(trPath, strPath);///Jake 06/28/07 SET_ONLY_FILENAME_ATTRIBUTE
	tree_set_browse_combo_attrib(trPath);	
	///end USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
	
	return true; 
}

///---Sim 07-13-2007 IMPROVE_ERR_CHECKING
/*
static bool _check_err_condition(TreeNode& trGetN, LPCSTR lpcszNodeName, string& strErrMsg)
{
	string strAbsolutePath = cvt_predefined_path_to_real_path(trGetN.fname.strVal); /// Iris 07/03/2007 v8.0654 USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL

	//----Jake 06/26/07 NEED_TO_CHECK_VALID_PATH_AFTER_UPDATE_PATH, so change the codes position 
	if(NULL == lpcszNodeName || lstrcmpi(lpcszNodeName, "fname") == 0)
	{
		if(!_gui_check_update_path(trGetN))
		{
			strErrMsg = "Failed to update filename";
			return false;
		}		
	}
	
	///Cheney 2006-11-3 CHECK_IF_FILE_PATH_IS_VALID
	if(lpcszNodeName != NULL)  
	{
		/// Iris 07/03/2007 v8.0654 USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
		//string strPath = GetFilePath(trGetN.fname.strVal); //when init, path is empty, no need to check 
		string	strPath = GetFilePath(strAbsolutePath);
		///end USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
		if(!strPath.IsPath())
		{
			/// Iris 07/04/2007 v8.0655 CREATE_PATH_IF_SPECIFIED_PATH_IS_NOT_EXISTED
			//strErrMsg = CER_INVALID_FILEPATH;
			//return false;
			strErrMsg = XFWARN_WILL_CREATE_NONEXISTING_PATH;
			return true;
			///end CREATE_PATH_IF_SPECIFIED_PATH_IS_NOT_EXISTED
		}
	}
	///end CHECK_IF_FILE_PATH_IS_VALID
	//----end NEED_TO_CHECK_VALID_PATH_AFTER_UPDATE_PATH
	
	///---Sim 06-05-2007 WARNING_EXPORT_TO_EXISTING_FILE
	/// Iris 07/03/2007 v8.0654 USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
	//if ( trGetN.fname.strVal.IsFile() )
	if(strAbsolutePath.IsFile())
	///end USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
	{
		strErrMsg = EXPWARN_FILE_EXIST;
		strErrMsg += ":";
		/// Iris 07/03/2007 v8.0654 USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
		//strErrMsg += GetFileName(trGetN.fname.strVal);
		strErrMsg += GetFileName(strAbsolutePath);
		///end USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
	}
	///---END WARNING_EXPORT_TO_EXISTING_FILE
	
	return true;
}
/// end ADD_ERROR_CHECK
*/
static bool check_file_name(TreeNode trGetN, string& strErr, string& strWarn)
{
	if ( !_gui_check_update_path(trGetN) )
	{
		strErr = CER_INVALID_FILENAME;
		return false;
	}
	
	bool bOK = true;
	check_relative_path(trGetN.fname.strVal, false, &strErr, &bOK);
	if( !bOK )
		return false;

	
	string strAbsolutePath = cvt_predefined_path_to_real_path(trGetN.fname.strVal);

	if(strAbsolutePath.IsFile())
	{
		strWarn = EXPWARN_FILE_EXIST;
		strWarn += ":";
		strWarn += GetFileName(strAbsolutePath);
	}

	return true;
}

//static bool s_bValidPath = true;
static bool s_bValidFileName = true;
static bool s_bValidSourceData = true;
static bool s_bIsNotExistingFile = true;

static string s_strErrFileName;
static string s_strErrSourceData;
static string s_strWarnExistingFile;

#define OK_SURE(_OK_ENABLE) _OK_ENABLE = (s_bValidFileName && s_bValidSourceData);

static void _get_error_message(string& strErrMsg)
{
	strErrMsg = CER_NO_ERROR;
	
	if ( !s_bIsNotExistingFile )
	{
		strErrMsg = s_strWarnExistingFile;
	}
	
	if ( !s_bValidFileName )
	{
		strErrMsg = s_strErrFileName;
		return;
	}
	
	if ( !s_bValidSourceData )
	{
		strErrMsg = s_strErrSourceData;
		return;
	}
	
}
///---END IMPROVE_ERR_CHECKING

/*
static bool check_get_wks(Worksheet& wks, XYRange& xy)
{
	if ( !xy || xy.GetNumData(DRR_GET_DEPENDENT) <= 0)
		return false;

	int c1, c2;
	xy.GetRange(wks, c1, c2);

	if ( !wks )
		return false;
	
	return true;
}

static bool get_column_index(XYRange& xy, int& nC1, int& nC2, int& nCX)
{
	int nNumYCol;
	nNumYCol = xy.GetNumData(DRR_GET_DEPENDENT);
	if ( nNumYCol <= 0 )
	{
		XF_WARN(_L("No data! Please select a range."));
		return false;
	}
	if ( nNumYCol > 2 )
	{
		XF_WARN(_L("Only support 2 channel, redundant column data(more than 2) will be ignore."));
		nNumYCol = 2;
	}
	
	Column col;
	for ( int ii = 0; ii < nNumYCol; ii++ )
	{
		int nX = -1, nY = -1;
		if ( xy.GetXColumn(col, ii) )
			nX = col.GetIndex();
		if ( xy.GetYColumn(col, ii) )
			nY = col.GetIndex();
		
		if ( 0 == ii )
		{
			nCX = nX;
			nC1 = nC2 = nY;
		}
		else
		{
			if ( nX != nCX )
			{
				XF_WARN(_L("X-axis of all channels aren't consistent!"));
				return false;
			}
			if ( nC2 - nC1 + 1 > nNumYCol )
			{
				XF_WARN(_L("Columns aren't continuous! Please select again."));
				return false;
			}
			nC2 = nY;
		}
	}
	
	return true;	
}
*/

static bool check_get_wks(DataRange& irng, Worksheet& wks, int* pnC1 = NULL, int* pnC2 = NULL, int* pnR1 = NULL, int* pnR2 = NULL)
{
	if ( !irng || irng.GetNumData() <= 0 )
		return false;

	int c1, c2, r1, r2;
	irng.GetRange(0, r1, c1, r2, c2, wks);
	
	if ( !wks )
		return false;
	
	if ( NULL != pnC1 )
		*pnC1 = c1;
	if ( NULL != pnC2 )
		*pnC2 = c2;
	if ( NULL != pnR1 )
		*pnR1 = r1;
	if ( NULL != pnR2 )
		*pnR2 = r2;
	
	return true;
}

static int get_column_index(DataRange& irng, Worksheet& wks, int& nC1, int& nC2, int& nCX, int& nR1, int& nR2)
{
	int c1, c2, r1, r2;
	//Worksheet wks;
	if ( !check_get_wks(irng, wks, &c1, &c2, &r1, &r2) )
	{
		return CER_NO_WORKSHEET;
	}
	
	//if ( !wks )
	//{
		//return CER_NO_WORKSHEET;
	//}
	
	if ( irng.GetNumData() > 1 )
	{
		return CER_NOT_SINGLE_RANGE;
	}
	
	if ( -1 == c2 )
		c2 = wks.GetNumCols() - 1;
	
	Column col;
	// detect x column
	nCX = -1;
	col = wks.Columns(c1);
	if ( OKDATAOBJ_DESIGNATION_X == col.GetType() )
		nCX = c1++;		
		
	if ( c2 - c1 + 1 > 2 )
	{
		return EXPERR_WAVE_TOO_MANY_CHANNEL;
	}
	
	if ( c1 > c2 )
	{
		return EXPERR_WAVE_NO_Y_COLUMN;
	}
	
	// detect y column
	int nRows = 0;
	bool bNoneSampleRate = true;
	for ( int ii = c1; ii <= c2; ii++ )
	{
		col = wks.Columns(ii);
		if ( OKDATAOBJ_DESIGNATION_Y != col.GetType() )
		{
			return EXPERR_WAVE_INVALID_COL_DESIGNATION;
		}
		
		double dTempX0, dTempInc;
		if ( col.IsEvenSampling(&dTempX0, &dTempInc) )
			bNoneSampleRate = false;
		
		if ( col.GetNumRows() > nRows )
			nRows = col.GetNumRows();
	}
	
	// not have sample interval in any column
	// auto detect x-axis column
	if ( nCX < 0 && bNoneSampleRate )
	{	
		nCX = c1 - 1;
		while ( nCX >= 0 )
		{
			col = wks.Columns(nCX);
			if ( OKDATAOBJ_DESIGNATION_X == col.GetType() )
				break;
			nCX--;
		}
		
		if ( nCX < 0)
			return EXPERR_WAVE_NOT_SAMPLE_RATE;
	}
	
	///---Sim 08-24-2007 FIX_CHECK_SAMPLING_SETTING
	if ( -1 == r2 )
		r2 = nRows - 1;
	///---END FIX_CHECK_SAMPLING_SETTING
		
	// check sample interval of each column
	double dX0 = 0, dInc = 0; ///---Sim 08-24-2007 FIX_CHECK_SAMPLING_SETTING
	if ( nCX < 0 )
	{	
		//double dX0 = 0, dInc = 0; ///---Sim 08-24-2007 FIX_CHECK_SAMPLING_SETTING remove
		for ( int ii = c1; ii <= c2; ii++ )
		{
			col = wks.Columns(ii);
			//if ( OKDATAOBJ_DESIGNATION_Y != col.GetType() )
			//{
				//return EXPERR_WAVE_INVALID_COL_DESIGNATION;
			//}
			//if ( -1 == nCX )
			//{
			double dTempX0, dTempInc;
			if ( !col.IsEvenSampling(&dTempX0, &dTempInc) )
				return EXPERR_WAVE_NOT_SAMPLE_RATE;
			
			if ( 0 != dTempX0 )
				return EXPERR_WAVE_SAMPLE_RATE_X0;
			
			if ( dInc > 0 && dTempInc != dInc )
				return EXPERR_WAVE_INCONSISTENT_SAMPLE_RATE;
			
			dInc = dTempInc;			
			//}
			//if ( col.GetNumRows() > nRows )
				//nRows = col.GetNumRows();
		}
	}
	///---Sim 08-24-2007 FIX_CHECK_SAMPLING_SETTING
	else
	{
		col = wks.Columns(nCX);
		vectorbase& vb = col.GetDataObject();
		vector vX;
		vX = vb;
		if ( r2 < vX.GetSize() - 1 )
			vX.RemoveAt(r2+1, vX.GetSize() - 1 - r2);
		if ( r1 > 1 )
			vX.RemoveAt(0, r1);
		
		int nErr;
		nErr = ocmath_sampling_resolution(vX.GetSize(), vX, &dInc);
		if ( OE_NOERROR != nErr )
			return EXPERR_WAV_INVALID_X_AXIS;
	}

	if ( dInc <= 0 )
		return EXPERR_WAV_INVALID_X_AXIS;
	
	DWORD dwSampleRate = 0;
	dwSampleRate = 1/dInc;
		
	if ( (dwSampleRate) < WAV_SAMPLE_RATE_MINIMUM_LIMIT )
		return EXPERR_WAV_INVALID_X_AXIS;

	//if ( -1 == r2 )
		//r2 = nRows - 1;
	///---END FIX_CHECK_SAMPLING_SETTING
	
	nC1 = c1;
	nC2 = c2;
	nR1 = r1;
	nR2 = r2;
	
	return CER_NO_ERROR;	
}
/// Hong 09/17/07 QA80-10381 SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
//static int export_wave_file(LPCSTR lpcszFileName, Worksheet& wks, int nC1, int nChannel, int nCX, int nR1, int nR2, int nBits, double dFactor = 1.0)
static int export_wave_file(LPCSTR lpcszFileName, Worksheet& wks, int nC1, int nC2, int nR1, int nR2, int nBits, double dFactor = 1.0, bool bStereo = FALSE)
/// end SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
{
	int nRet;
	
	exportWAVFile wavFile;
	
	nRet = wavFile.SetBitsPerSample(nBits);
	if ( 0 != nRet )
		return nRet;
	
	/// Hong 09/17/07 QA80-10381 SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
	//nRet = wavFile.SetRange(wks, nC1, nC1 + nChannel - 1, nCX, nR1, nR2);
	nRet = wavFile.SetRange(wks, nC1, nC2, nR1, nR2, bStereo);
	/// end SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
	if ( 0 != nRet )
		return nRet;
	/// Hong 09/24/07 QA80-10381 v8.0707 REMOVE_VOLUMN_FACTOR
	//nRet = wavFile.SetFactor(dFactor);
	//if ( 0 != nRet )
		//return nRet;
	/// end REMOVE_VOLUMN_FACTOR

	nRet = wavFile.WriteFile(lpcszFileName);
	
	return nRet;
}

static bool check_export_rang(TreeNode trDr, string& strErrMsg)
{
	DataRange dr;
	okxf_resolve_tree_construct_range(&trDr, &dr);
	
	Worksheet wks;
	int nCX, nC1, nC2, nR1, nR2;
	int nRet = get_column_index(dr, wks, nC1, nC2, nCX, nR1, nR2);
	if ( nRet )
	{
		strErrMsg = nRet;
		return false;
	}
	
	return true;
}

/// Hong 09/17/07 QA80-10381 SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
static bool _get_sample_interval(Worksheet& wks, int nLTIndex, double& dX0, double& dInc, int& nType)
{
	Column col(wks, nLTIndex - 1);			
	if ( !col )
		return false;
		
	if ( !col.IsEvenSampling(&dX0, &dInc) )
	{
		///---Sim 12-11-2007 IMPROVE_GET_SAMPLING_INTERVAL_FROM_X_COL
		//Curve crv;
		//crv.Attach(col);	
		//
		//string strXCol;
		//if ( !crv.HasX(strXCol) )	
			//return false;			
		//
		//dX0 = 0.0;
		//Dataset ds(strXCol);		
		//int nErr = ocmath_sampling_resolution(ds.GetSize(), ds, &dInc);
		//if ( OE_NOERROR != nErr )
			//return false;	
		int nYCol = nLTIndex - 1;
		int nXCol = wks.FindColIndex(nYCol , OKDATAOBJ_DESIGNATION_X);
		if ( nXCol < 0 )
			return false;
		
		Column colX(wks, nXCol);
		vectorbase& vb = colX.GetDataObject();
		if ( vb.GetSize() <= 0 )
			return false;
		
		vector vd = vb;
		dX0 = vd[0];
		int nErr = ocmath_sampling_resolution(vd.GetSize(), vd, &dInc);
		if ( OE_NOERROR != nErr )
			return false;
		///---END IMPROVE_GET_SAMPLING_INTERVAL_FROM_X_COL
	}	
	
	nType = col.GetInternalData();
	
	return true;
}

static int _check_columns(Worksheet& wks, int nLTC1, int nLTC2, bool bStereo, int& nBits, bool& bShowBits)
{
	if ( !wks )
		return CER_NO_WORKSHEET;
	
	double dX0, dInc;
	int nC1Type;
	if ( !_get_sample_interval(wks, nLTC1, dX0, dInc, nC1Type) )
		return EXPERR_WAVE_NOT_SAMPLE_RATE;
	
	bShowBits = false;
	switch ( nC1Type )
	{
		///---Sim 12-13-2007 IMPROVE_CONVERT_SAMPLE_BITS
		//case FSI_CHAR: nBits = 0; break;
		case FSI_BYTE: nBits = 0; break;
		///---END IMPROVE_CONVERT_SAMPLE_BITS
		case FSI_SHORT: nBits = 1; break;
		case FSI_LONG: nBits = 2; break;
		default:
			return IMPERR_WAVE_UNSUPPORT_DATA_TYPE; /// Hong 09/18/07 ERROR_CHECK_FOR_COLUMN_DATA_TYPE
	}
	
	if (  dInc <= 0 )
		return EXPERR_WAV_INVALID_X_AXIS;
	
	if ( bStereo )
	{
		int nC2Type;
		double dTempX0, dTempInc;
		if ( !_get_sample_interval(wks, nLTC2, dTempX0, dTempInc, nC2Type) )		
			return EXPERR_WAVE_NOT_SAMPLE_RATE;
		
		/// Hong 09/18/07 ERROR_CHECK_FOR_COLUMN_DATA_TYPE
		///---Sim 12-13-2007 IMPROVE_CONVERT_SAMPLE_BITS
		//if ( FSI_CHAR != nC2Type && FSI_SHORT != nC2Type && FSI_LONG != nC2Type)
		if ( FSI_BYTE != nC2Type && FSI_SHORT != nC2Type && FSI_LONG != nC2Type)
		///---END IMPROVE_CONVERT_SAMPLE_BITS
			return IMPERR_WAVE_UNSUPPORT_DATA_TYPE;
		/// end ERROR_CHECK_FOR_COLUMN_DATA_TYPE
		
		if ( nC1Type != nC2Type )
			bShowBits = true;
			
		if ( dX0 != dTempX0 )
			return EXPERR_WAVE_SAMPLE_RATE_X0;
			
		if ( dInc > 0 && dTempInc != dInc )
			return EXPERR_WAVE_INCONSISTENT_SAMPLE_RATE;
	}
	
	///---Sim 08-11-2008 CHECK_SAMPLE_RATE_LIMIT
	/////---Sim 12-10-2007 CHECK_SAMPLE_RATE_LIMIT
	//if ( (1/dInc) < WAV_SAMPLE_RATE_MINIMUM_LIMIT )
		//return EXPERR_WAV_INVALID_X_AXIS;
	/////---END CHECK_SAMPLE_RATE_LIMIT
	if ( !((1.0/WAV_SAMPLE_RATE_MAXIMUM_LIMIT) <= dInc && dInc <= (1.0/WAV_SAMPLE_RATE_MINIMUM_LIMIT)) )
		return EXPERR_WAV_INVALID_X_AXIS;
	///---END CHECK_SAMPLE_RATE_LIMIT
	
	return CER_NO_ERROR;
}

static int _left_right_channel_event(TreeNode& trGetN)
{
	Worksheet wks;
	if ( !_change_worksheet_event(trGetN, &wks) )	
		return CER_NO_WORKSHEET;	
		
	/// Hong 12/10/07 v8.0765 IMPROVE_CODE_FOR_HIDE_SHOW
	/*
	int nRet, nBits;
	bool bShowBits;
	if ( nRet = _check_columns(wks, trGetN.left.nVal, trGetN.right.nVal, trGetN.mode.nVal, nBits, bShowBits) )
		return nRet;
	
	trGetN.bits.nVal = nBits;
	trGetN.bits.Show = bShowBits;
	*/
	int nRet, nBits = 0;
	bool bShowBits = false;
	nRet = _check_columns(wks, trGetN.left.nVal, trGetN.right.nVal, trGetN.mode.nVal, nBits, bShowBits);		
	
	trGetN.bits.nVal = nBits;
	trGetN.bits.Show = bShowBits;	
	
	if ( nRet )
		return nRet;
	/// end IMPROVE_CODE_FOR_HIDE_SHOW
	//trGetN.scl.Show = bShowBits; /// Hong 09/24/07 QA80-10381 v8.0707 REMOVE_VOLUMN_FACTOR
	
	return CER_NO_ERROR;
}

static bool _change_worksheet_event(TreeNode& trGetN, Worksheet* pwks = NULL)
{
	Worksheet wks;
	okxf_resolve_string_get_origin_object(trGetN.iw.strVal, &wks);
	
	if ( !wks )
		return false;
	
	if ( pwks != NULL )
		*pwks = wks;
	
	return true;
}

static int _change_mode_event(TreeNode& trGetN)
{
	if ( mode_mono == trGetN.mode.nVal )
	{
		/// Hong 02/03/09 QA80-13026 IMPROVE_LABEL_SUGGESTED_BY_GREG
		//trGetN.left.SetAttribute(STR_LABEL_ATTRIB, _L("Channel"));
		trGetN.left.SetAttribute(STR_LABEL_ATTRIB, _L("Column"));
		/// end IMPROVE_LABEL_SUGGESTED_BY_GREG
		trGetN.right.Show = 0;
	}
	else
	{
		/// Hong 02/03/09 QA80-13026 IMPROVE_LABEL_SUGGESTED_BY_GREG
		//trGetN.left.SetAttribute(STR_LABEL_ATTRIB, _L("Left Channel"));
		trGetN.left.SetAttribute(STR_LABEL_ATTRIB, _L("Column(L)"));
		/// end IMPROVE_LABEL_SUGGESTED_BY_GREG
		trGetN.right.Show = 1;
	}
	
	return _left_right_channel_event(trGetN);
}
/// end SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED


void expWAV(const int& mode, const Worksheet& iw, const int& left, const int& right, const int& r1, const int& r2, const string& fname, const int& bits)
{
	/// Hong 09/17/07 QA80-10381 SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
	/*
	Worksheet wks;
	//if ( !check_get_wks(irng, wks) )
		//XF_THROW(CER_NO_WORKSHEET);
	int nC1, nC2, nCX, nR1, nR2;
	int nRet = get_column_index(irng, wks, nC1, nC2, nCX, nR1, nR2);
	*/
	int nBits;
	bool bShowBits;
	int nRet = _check_columns(iw, left, right, mode, nBits, bShowBits);
	/// end SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
	if ( nRet )
		XF_THROW(nRet);
		
	int Bits[3] = {BITS_8, BITS_16, BITS_32};
	
	string strPath = cvt_predefined_path_to_real_path(fname);/// Iris 07/04/2007 v8.0654 USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
	
	///---Sim 03-17-2008 FIX_CHECK_FILE_EXTENSION
	//_check_add_file_ext(strPath);
	add_file_extension(strPath, WAVE_FILE_EXT);
	///---Sim 05-07-2009 QA80-13571 FIX_CRASH_WHEN_FILE_PATH_LENGTH_IS_TOO_LONG
	#ifdef CHECK_EXCEED_FILE_PATH_LENGTH_LIMITATION
	check_trim_file_path_if_too_long(strPath);
	#endif
	///---END QA80-13571 FIX_CRASH_WHEN_FILE_PATH_LENGTH_IS_TOO_LONG
	///---END FIX_CHECK_FILE_EXTENSION
	DeleteFile(strPath);
	
	int nErr;
	/// Hong 09/17/07 QA80-10381 SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
	//nErr = export_wave_file(strPath, wks, nC1, nC2-nC1+1, nCX, nR1, nR2, Bits[bits], (vol/100.0));
	/// Hong 09/24/07 QA80-10381 v8.0707 REMOVE_VOLUMN_FACTOR
	//nErr = export_wave_file(strPath, iw, left - 1, right - 1, r1 - 1, r2 - 1, Bits[bits], scl, mode);
	nErr = export_wave_file(strPath, iw, left - 1, right - 1, r1 - 1, r2 - 1, Bits[bits], 1.0, mode);
	/// end REMOVE_VOLUMN_FACTOR
	/// end SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
	string strMessage;
	///Folger 05/24/07 MODIFY_OUTPUT_INFO_MSG
	//strMessage.Format(_L("%s to export page %s to %s."), (fname.IsFile() && nErr == 0)?"Succeed":"Failed", wks.GetName(), fname);
	///Folger 06/05/07 ADD_FAILURE_MSG
	///---Sim 12-13-2007 IMPROVE_CHECK_FILE_NAME
	//if (fname.IsFile() && nErr == 0)
	if (strPath.IsFile() && nErr == 0)
	///---END IMPROVE_CHECK_FILE_NAME
	{
		ocu_load_msg_str(XF_EXPORT_SUCCESS, &strMessage, iw.GetName(), NULL, strPath);
		update_recent_path_list(strPath); ///---Sim 12-13-2007 IMPROVE_CHECK_FILE_NAME
	}
	else
		ocu_load_msg_str(XF_EXPORT_FAILED, &strMessage, iw.GetName(), NULL, strPath);
	///End ADD_FAILURE_MSG
	///End MODIFY_OUTPUT_INFO_MSG
	okoc_out_msg(strMessage, 'I');
	
	///---Sim 12-13-2007 IMPROVE_CHECK_FILE_NAME
	/*
	///Jake 06/28/07 SUPPORT_DEFAULT_KEY_NAME
	/#
	//----Jake 06/26/07 GET_COMBO_LIST_FROM_REGISTRY
	char szLastXFName[MAXFULLPATH];
	LT_get_str(LTVAR_LAST_XF, szLastXFName, MAXFULLPATH);
	update_recent_path_list(szLastXFName,fname);//update path to registry
	//----end GET_COMBO_LIST_FROM_REGISTRY
	#/
	update_recent_path_list(strPath);
	///end GET_COMBO_LIST_FROM_REGISTRY
	*/
	///---END IMPROVE_CHECK_FILE_NAME
}

//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int expWAV_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return expWAV_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	///---Sim 07-13-2007 IMPROVE_ERR_CHECKING
	/*
	bOKEnable = _check_err_condition(trGetN, (GETNE_ON_INIT==nEventID || GETNE_ON_THEME==nEventID)? NULL:lpcszNodeName, strErrMsg);
	if ( 0 == lstrcmp(lpcszNodeName, "irng") || GETNE_ON_INIT==nEventID || GETNE_ON_THEME==nEventID )
	{
		string strMsg;
		if ( !check_export_rang(trGetN.irng, strMsg) )
		{
			strErrMsg = strMsg;
			bOKEnable = false;
		}
		return true;
	}
	
	return false;
	*/
	if ( 0 == lstrcmp(lpcszNodeName, "fname") || GETNE_ON_INIT==nEventID || GETNE_ON_THEME==nEventID )
	{
		string strErr, strWarn;
		
		check_file_name(trGetN, strErr, strWarn);
		
		s_bValidFileName = strErr.IsEmpty();
		s_strErrFileName = strErr;
		
		s_bIsNotExistingFile = strWarn.IsEmpty();
		s_strWarnExistingFile = strWarn;
	}
	/// Hong 09/17/07 QA80-10381 SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
	/*
	if ( 0 == lstrcmp(lpcszNodeName, "irng") || GETNE_ON_INIT==nEventID || GETNE_ON_THEME==nEventID )
	{
		string strErr;
		
		check_export_rang(trGetN.irng, strErr);
		
		
		s_bValidSourceData = strErr.IsEmpty();
		s_strErrSourceData = strErr;
	}
	*/	
	if ( 0 == lstrcmp(lpcszNodeName, "mode") || GETNE_ON_INIT==nEventID || GETNE_ON_THEME==nEventID )
	{
		string strErr; 
		int nRet;
		if ( nRet = _change_mode_event(trGetN) )
			strErr = nRet;
		
		s_bValidSourceData = strErr.IsEmpty();
		s_strErrSourceData = strErr;		
	}
	
	if ( 0 == lstrcmp(lpcszNodeName, "iw") || GETNE_ON_INIT==nEventID || GETNE_ON_THEME==nEventID )
	{
		string strErr; 
		int nRet;
		if ( !_change_worksheet_event(trGetN) )
			strErr = CER_NO_WORKSHEET;
		else if ( nRet = _left_right_channel_event(trGetN) )
			strErr = nRet;
		
		s_bValidSourceData = strErr.IsEmpty();
		s_strErrSourceData = strErr;
	}
	
	if ( 0 == lstrcmp(lpcszNodeName, "left") || 0 == lstrcmp(lpcszNodeName, "right") )
	{
		string strErr;
		int nRet;
		if ( nRet = _left_right_channel_event(trGetN) )
			strErr = nRet;
	
		s_bValidSourceData = strErr.IsEmpty();
		s_strErrSourceData = strErr;
	}
	/// end SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED		
		
	OK_SURE(bOKEnable);
	_get_error_message(strErrMsg);
	
	
	return true;
	///---END IMPROVE_ERR_CHECKING
	

}

int expWAV_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	return false;
}
//nGetNDialog = 0,1,2, corresponding to the XF GetN dropdown, 0 = dialog is not used
//you can change nRet to be one of XFEVT_PROCEED (defualt), XFEVT_ABORT, XFEVT_PROCEED_NO_DLG or XFEVT_PROCEED_WITH_DLG(when nGetNDialog = 0)
//nGetNDialog = -1 when Ok on GetN dialog to allow handler to preocess <auto> etc variables
//dwCntrl is combination of bits
//LTXF_FROM_GUI_MENU, LTXF_FROM_GUI_PROMPT, LTXF_FROM_AUTO_UPDATE, LTXF_FROM_FUNCTION, LTXF_THEME_USED, LTXF_CHANGE_PARAM
void expWAV_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	
	if(nGetNDialog > 0)
	{
		//trGetN.vol.Show = 0;
		
		/// Iris 07/04/2007 v8.0654 USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
		/*
		///Jake 06/28/07 SUPPORT_DEFAULT_KEY_NAME		
		////----Jake 06/26/07 GET_COMBO_LIST_FROM_REGISTRY
		//char szLastXFName[MAXFULLPATH];
		//LT_get_str(LTVAR_LAST_XF, szLastXFName, MAXFULLPATH); //Jake 06/27/07 GET_THE_NAME_OF_LAST_XF_CALLED
		//TreeNode trPath = trGetN.fname;
		//tree_set_browse_combo_attrib(trPath, szLastXFName, false);
		////----end GET_COMBO_LIST_FROM_REGISTRY		
		TreeNode trPath = trGetN.fname;
		tree_set_browse_combo_attrib(trPath);
		///end SUPPORT_DEFAULT_KEY_NAME
		*/
		///end USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
	}
	
	if(nGetNDialog > -1)
	{
		
		Worksheet	wks;
		//okxf_resolve_string_get_origin_object(trGetN.wks.strVal, &wks);
		/// Hong 09/17/07 QA80-10381 SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED]
		/*
		DataRange dr;
		TreeNode trXY = trGetN.irng;
		okxf_resolve_tree_construct_range(&trXY, &dr);
		//if(!wks)
		if ( !check_get_wks(dr, wks) )
		*/
		if ( !_change_worksheet_event(trGetN, &wks) )
		/// end SIMPLIFY_GUI_HIDDEN_OPTION_IF_NO_NEED
		{
			/// Hong 08/09/07 v8.0678 CONSOLIDATE_ERROR_BEHAVIOR_FOR_EXPORT
			nRet = XFEVT_ABORT;
			warning_msg_box(CER_NO_WORKSHEET, true);
			/// end CONSOLIDATE_ERROR_BEHAVIOR_FOR_EXPORT
			//warning_msg_box(CER_NOT_ONE_XYRANGE, true);
			return;
		}
		/// Hong 08/09/07 v8.0678 CONSOLIDATE_ERROR_BEHAVIOR_FOR_EXPORT
		if (wks.GetSystemParam(0) & WP_SHEET_HIERARCHY)
		{
			nRet = XFEVT_ABORT;
			warning_msg_box(XFERR_CANNOT_EXP_REPORT_SHEET_TO_WAVE, true);
			return;
		}
		/// end /// Hong 08/09/07 v8.0678 CONSOLIDATE_ERROR_BEHAVIOR_FOR_EXPORT
		///---Sim 06-18-2007 ADD_SHOW_DLG_CHECK_BOX_TO_SAVE_AS_DLG
		/*
		if(!(dwCntrl & LTXF_FROM_GUI_PROMPT) || (dwCntrl & LTXF_THEME_USED))
		{
			//trim file name from path then set it to wks name
			if((dwCntrl & LTXF_THEME_USED) && !trGetN.fname.strVal.IsEmpty())
			{
				trGetN.fname.strVal = GetFilePath(trGetN.fname.strVal) + wks.GetName();
			}
		}
		*/
		
		string strFileName = trGetN.fname.strVal;
		
		if ( LTXF_FROM_GUI_MENU & dwCntrl ) // if from menu, ignore default value fname$
			strFileName = "";
		
		//if(nGetNDialog == 0)
		//{
			//if apply theme, should ask user input a file name but not pop-up a dlg
			//if(is_empty_or_unassigned(trGetN.fname.strVal) || (dwCntrl & LTXF_THEME_USED))
		if( is_empty_or_unassigned(strFileName) )	
		{
			string strWksName = wks.GetName();
			
			int nFilesRet;
			if ( 0 != nGetNDialog )
			{
				int nShowOptionsDlg = 1;
				/// Hong 09/26/07 8.0709 CLEAN_OPEN_SAVE_DIALOG_TITLE_TO_DEFAULT
				//nFilesRet = get_saveas_box_by_file_group(strFileName, STR_WAVE_FILE_GROUP, _L("Sound File"),
				//	0, NULL, strWksName, _L("Show Options Dialog"), &nShowOptionsDlg);
				nFilesRet = get_saveas_box_by_file_group(strFileName, STR_WAVE_FILE_GROUP, NULL,
					0, NULL, strWksName, STR_SHOW_OPT_DLG, &nShowOptionsDlg);
				/// end CLEAN_OPEN_SAVE_DIALOG_TITLE_TO_DEFAULT
				nRet = (nShowOptionsDlg ? XFEVT_PROCEED : XFEVT_PROCEED_NO_DLG);
			}
			else
			{
				//nFilesRet = get_saveas_box_by_file_group(strFileName, STR_WAVE_FILE_GROUP, _L("Sound File"), 0, NULL, strWksName);
				nFilesRet = get_saveas_box_by_file_group(strFileName, STR_WAVE_FILE_GROUP, NULL, 0, NULL, strWksName); /// Hong 09/26/07 8.0709 CLEAN_OPEN_SAVE_DIALOG_TITLE_TO_DEFAULT
			}
			/*
			///---Sim 05-25-2007 GET_DEFAULT_FROM_ORIGIN_OPTIONS
			//string strPath = is_empty_or_unassigned(trGetN.fname.strVal)? GetAppPath() : GetFilePath(trGetN.fname.strVal);
			string strPath = is_empty_or_unassigned(trGetN.fname.strVal) ? 
						_get_default_path() : GetFilePath(trGetN.fname.strVal);
			///---END GET_DEFAULT_FROM_ORIGIN_OPTIONS
			/// Hong 03/14/07 FIX_FAIL_OPEN_SAVE_DIALOG
			//strPath = GetSaveAsBox("*tdm National Instrucment", strPath, strPageName);
			strPath = GetSaveAsBox("[wave Sound Format File(*.wav)] *.wav", strPath, strWksName);
			/// end FIX_FAIL_OPEN_SAVE_DIALOG
			*/
			
			//if(strPath.IsEmpty())
			if ( 0 == nFilesRet )
			{
				nRet = XFEVT_ABORT;
				//warning_msg_box(XFERR_UI_USER_CANCEL, false); // Hong 03/14/07 NO_NEED_CANCEL_WARNING
				return;
			}
	
			trGetN.fname.strVal = strFileName;
			
			///Jake 06/28/07 CODES_MOVED_TO_GLOBAL
			/*
			//---Jake 06/27/07 STORE_USER_FILE_NAME
			string strOnlyFileName = GetFileName(strFileName);
			trGetN.fname.SetAttribute(STR_ONLY_FILE_NAME_ATTRIB,strOnlyFileName);
			//---end STORE_USER_FILE_NAME
			*/
			/// Iris 07/04/2007 v8.0654 USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
			//tree_set_only_file_name_attrib(trGetN.fname,strFileName);
			///end USAGE_OF_BROWSER_COMBO_NOT_CONSISTENT_IN_FILE_AND_PATH_CONTROL
			///end CODES_MOVED_TO_GLOBAL
		}
		//}
		///---END ADD_SHOW_DLG_CHECK_BOX_TO_SAVE_AS_DLG
	}
}
//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int expWAV_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
