/*------------------------------------------------------------------------------*
 * File Name:				 													*
 * Creation: 																	*
 * Purpose: OriginC Source C file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	Sim 07-16-2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6								*
 *	Sophy 7/17/2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6							*
 *	Folger 08/07/09 QA80-13998 SUPPORT_GET_GOAL_AND_FITTING_REPORT_GRAPH_UID_FROM_PAWIZMANAGER
 *------------------------------------------------------------------------------*/
 
////////////////////////////////////////////////////////////////////////////////////
// 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 "PAThemeConvert.h"
#include <..\Originlab\theme_utils.h>
////////////////////////////////////////////////////////////////////////////////////
// Start your functions here.
//#define	THEME_CONVERT_DEBUG 1

#ifdef THEME_CONVERT_DEBUG
stdioFile stdFile;
#define	DB_INIT_LOGFILE	{	SYSTEMTIME sysTime; \
						    GetSystemTime(&sysTime); \
						    char	szTime[200]; \
						    string	strLogFileName; \
						    systemtime_to_date_str(&sysTime, szTime,  LDF_LONG ); \
						    strLogFileName.Format("C:\\PAThemeConvertLogFile(%s).txt", szTime); \
							stdFile.Open(strLogFileName, file::modeWrite | file::modeNoTruncate); \
							if( !stdFile.IsOpen() ) \
							{ \
								stdFile.Open(strLogFileName, file::modeCreate | file::modeWrite); \
							} \
							if( stdFile.IsOpen() ) \
								stdFile.SeekToEnd(); }
#define	DB_OUT_STRING(_STR)	{ if( stdFile.IsOpen() )stdFile.WriteString(_STR);}
#define	DB_OUT_ID_PAIR(_OLDID, _NEWID)	{ string strIDs; strIDs.Format("\t%X	|	%X", _OLDID, _NEWID); if( stdFile.IsOpen() )stdFile.WriteString(strIDs);}
#define	DB_OUT_IVALUE_PAIR(_ID, _OLDVAL, _NEWVAL) { string strValues; strValues.Format("\tID:%X : %d	|	%d", _ID, _OLDVAL, _NEWVAL); if( stdFile.IsOpen() )stdFile.WriteString(strValues);}
#define	DB_OUT_DVALUE_PAIR(_ID, _OLDVAL, _NEWVAL) { string strValues; strValues.Format("\tID:%X : %lf	|	%lf", _ID, _OLDVAL, _NEWVAL); if( stdFile.IsOpen() )stdFile.WriteString(strValues);}
#define	DB_OUT_STRVAL_PAIR(_ID, _OLDVAL, _NEWVAL) { string strValues; strValues.Format("\tID:%X : %s	|	%s", _ID, _OLDVAL, _NEWVAL); if( stdFile.IsOpen() )stdFile.WriteString(strValues);}
#define	DB_CLOSE_LOGFILE stdFile.Close();
#else
#define	DB_INIT_LOGFILE
#define	DB_OUT_STRING(_STR)
#define	DB_OUT_ID_PAIR(_OLDID, _NEWID)
#define	DB_OUT_IVALUE_PAIR(_ID, _OLDVAL, _NEWVAL)
#define	DB_OUT_DVALUE_PAIR(_ID, _OLDVAL, _NEWVAL)
#define	DB_OUT_STRVAL_PAIR(_ID, _OLDVAL, _NEWVAL)
#define	DB_CLOSE_LOGFILE
#endif THEME_CONVERT_DEBUG

#define	CHECK_XF_IN_PATH(_XFNAME, _TREE_THEME) _check_xf_is_in_themetree(_XFNAME, _TREE_THEME);
						

#define	PA_XFNAME_START				"pa_start"
#define	PA_XFNAME_GOAL				"pa_goal"
#define	PA_XFNAME_BASELINEMODE		"pa_basemode"
#define	PA_XFNAME_CREATEBASELINE	"pa_basecreate"
#define	PA_XFNAME_BASECOND			"pa_basecond"
#define	PA_XFNAME_BASELINETREATMENT	"pa_basetreat"
#define	PA_XFNAME_FINDPEAKS			"pa_peaks"
#define	PA_XFNAME_INTEGRATEPEAKS	"pa_int"
#define	PA_XFNAME_FITPEAKS			"pa_fit"

#define	PA_BASELINEMODE_CON_ID_SR5				0x0005400b
#define	PA_BASELINEMODE_MINMAX_ID_SR5			0x0005400c
#define	PA_BASELINEMODE_SNAP_ID_SR5				0x00040032
#define	PA_CREATEBASELINE_SNAP_ID_SR5			0x00030032
#define	PA_BASELINE_TREATMENT_RESCALE_ID_SR5	0x00020032
#define	PA_FINDPEAKS_DERIV_ID_SR5				0x00070032
#define	PA_FITPEAKS_DERIV_ID_SR5				0x00050032
#define	PA_FINDPEAKS_DERIV_FIRST_ID_SR5			0x000B4014
#define	PA_FINDPEAKS_DERIV_SEC_ID_SR5			0x000B4015
#define	PA_FINDPEAKS_DERIV_FFTCUTOFF_ID_SR5		0x000B4016
#define	PA_INTEGPEAKS_INTWINDOW_ID_SR5			0x00040032
#define	PA_INTEGPEAKS_OUTID_ID_SR5				0x000C0032
#define PA_FITPEAKS_USESEPX_ID					0x000740A4
#define	PA_FITPEAKS_FUNCTIONS_ID				0x000900F8	//both in sr4&sr5
#define	PA_FITPEAKS_BASELINEPARAMETERS_ID		0x0009400b	//both in sr4&sr5
#define	PA_FITPEAKS_BASELINEFUNCTION_ID_SR5		0x000943FC	//only in sr5
#define	PA_FITPEAKS_PEAKNUM_ID_SR6				0x000740B4  //only in sr6	///Sophy 7/17/2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6

// this function for PA frame, it will be invoked by FindFunction()
// reuturn -1 is error, 0 is successful
int convert_pa_theme(TreeNode& trTheme)
{
	PAThemeConvert patc;
	return patc.Convert(trTheme);
}
///---Sim 07-16-2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
int convert_pa_theme_sr5_to_sr6(TreeNode& trTheme)
{
	PAThemeConvertSR6 patc;
	return patc.Convert(trTheme);
}
///---END CONVERT_PA_THEME_FROM_SR5_TO_SR6

static bool	_check_xf_is_in_themetree(LPCSTR lpcszXFName, const TreeNode& trThemeTree)
{
	vector<string> vsXFNames;
	vsXFNames = trThemeTree.Path.strVals;
	return is_in_list(lpcszXFName, vsXFNames);
}

int		get_xf_themetree(TreeNode& trTheme, LPCSTR lpcszXFName, TreeNode& trThemeTree)
{
	bool bInPath =  CHECK_XF_IN_PATH(lpcszXFName, trTheme);
	if ( !bInPath )
		return GET_IGNORE;
	
	if ( trTheme )
	{
		TreeNode trXF = trTheme.GetNode(lpcszXFName, false);
		if ( trXF )
		{
			trThemeTree = trXF.GetNode(STR_XFBAR_MULITIMODE_THEME_TREE);
		}
	}
	
	//Sim, 11-24-2008
	/*
	on xf wizard, user can save theme file at any moment, needn't in end of steps.
	example
	SR4: goal is fit peak, user go to baseline step, update baseline setting, and don't change other (keep default fit setting), then they save theme file on baseline step.
	SR5: this theme file is valid, and later we will use SR5 default instead.
	*/
	//return trThemeTree.IsValid() ? GET_SUCCESS : GET_FAIL;
	return trThemeTree.IsValid() ? GET_SUCCESS : GET_IGNORE;
	//---
}

class _FileHelper
{
public:
	_FileHelper() {DB_INIT_LOGFILE}
	~_FileHelper() {DB_CLOSE_LOGFILE}
};

#define _SAFE_RETURN_CALL(_CALLED) { \
		nRet = _CALLED; \
		if (nRet < 0) \
			return nRet; \
		}

///---Sim 07-16-2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
//int PAThemeConvert::Convert(TreeNode& trTheme)
int ThemeConvertBase::Convert(TreeNode& trTheme)
///---END CONVERT_PA_THEME_FROM_SR5_TO_SR6
{
	if ( !trTheme )
		return -1;
	
	_FileHelper filehelper;
	
	int nRet;
	_SAFE_RETURN_CALL(ConvertXFName(trTheme))
	_SAFE_RETURN_CALL(ConvertIDs(trTheme))
	_SAFE_RETURN_CALL(ConvertValue(trTheme))
	
	return 0;
}

///---Sim 07-16-2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
//int PAThemeConvert::convertIDs(TreeNode& trTheme, ThemeIDConverter* pidcvt, LPCSTR lpcszXFName)
int ThemeConvertBase::ConvertIDs(TreeNode& trTheme, ThemeIDConverter* pidcvt, LPCSTR lpcszXFName)
///---END CONVERT_PA_THEME_FROM_SR5_TO_SR6
{
	if ( NULL == pidcvt )
		return -1;
	
	TreeNode trThemeTree;
	int nResult = get_xf_themetree(trTheme, lpcszXFName, trThemeTree);
	if( GET_IGNORE == nResult )
		return 0;
	
	if( !trThemeTree )
		return -1;
	
	return pidcvt->Convert(trThemeTree);
}

///---Sim 07-16-2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
//int PAThemeConvert::convertSingleValue(TreeNode& trTheme, ThemeValueConverter* pvcvt, LPCSTR lpcszXFName)
int ThemeConvertBase::ConvertSingleValue(TreeNode& trTheme, ThemeValueConverter* pvcvt, LPCSTR lpcszXFName)
///---END CONVERT_PA_THEME_FROM_SR5_TO_SR6
{
	if ( NULL == pvcvt )
		return -1;
	
	TreeNode trThemeTree;
	int nResult = get_xf_themetree(trTheme, lpcszXFName, trThemeTree);
	if( GET_IGNORE == nResult )
		return 0;
	
	if( !trThemeTree )
		return -1;
	
	return pvcvt->Convert(trThemeTree);
}

///---Sim 07-16-2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
//int PAThemeConvert::convertGroupValues(TreeNode& trTheme, ThemeGroupValueConverter* pgvcvt)
int ThemeConvertBase::ConvertGroupValues(TreeNode& trTheme, ThemeGroupValueConverter* pgvcvt)
///---END CONVERT_PA_THEME_FROM_SR5_TO_SR6
{
	if ( NULL == pgvcvt )
		return -1;
	
	if( !trTheme )
		return -1;
	
	return pgvcvt->Convert(trTheme);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define	STR_USELESS_XFNAME_NONE	"None" ///Sophy 11/15/2008 CONVERTED_THEME_CAUSE_PA_IN_SR5_FAIL_TO_LOAD_XF
int PAThemeConvert::ConvertXFName(TreeNode& trTheme)
{
	DB_OUT_STRING("Converting XF Names...");

	StringArray saSourceXFNames = {PA_XFNAME_START, PA_XFNAME_BASECOND};
	StringArray saDestXFNames = {PA_XFNAME_GOAL, PA_XFNAME_BASELINETREATMENT};
	
	ASSERT(saSourceXFNames.GetSize() == saDestXFNames.GetSize());
	if ( saSourceXFNames.GetSize() != saDestXFNames.GetSize() )
		return -1;

	// update xf names on string array
	TreeNode trPath = trTheme.Path;
	if ( trPath )
	{
		StringArray saXFNames;
		saXFNames = trPath.strVals;
		for ( int nIndex = 0; nIndex < saXFNames.GetSize(); nIndex++ )
		{
			int nPos = saSourceXFNames.Find(saXFNames[nIndex]);
			if ( nPos >= 0 )
			{
				saXFNames[nIndex] = saDestXFNames[nPos];
			}
		}
		vector<string> vsInvalidXF = {STR_USELESS_XFNAME_NONE};
		remove_if_in_list(saXFNames, vsInvalidXF);
		trPath.strVals = saXFNames;
	}
	
	// rename tagname
	for ( int nPos = 0; nPos < saSourceXFNames.GetSize(); nPos++ )
	{
		TreeNode trXF = trTheme.GetNode(saSourceXFNames[nPos], false);
		if ( trXF )
		{
			TreeNode trXFNew = trTheme.AddNode(saDestXFNames[nPos]);
			trXFNew.Replace(trXF, true, true);
			trXF.Remove();

			DB_OUT_STRING( saSourceXFNames[nPos] + " Changed to " + saDestXFNames[nPos]);

			trXFNew.SetAttribute(STR_XF_NAME_ATTRIB, saDestXFNames[nPos]);
		}		
	}
	
	return 0;
}

int PAThemeConvert::ConvertIDs(TreeNode& trTheme)
{

	DB_OUT_STRING("Converting XF IDs...");

	int nRet;
	_SAFE_RETURN_CALL(ConvertIDsOnStart(trTheme));
	_SAFE_RETURN_CALL(ConvertIDsOnBaselineMode(trTheme));
	_SAFE_RETURN_CALL(ConvertIDsOnCreateBaseline(trTheme));
	_SAFE_RETURN_CALL(ConvertIDsOnBaselineTreatment(trTheme));
	_SAFE_RETURN_CALL(ConvertIDsOnFindPeaks(trTheme));
	_SAFE_RETURN_CALL(ConvertIDsOnIntegratePeaks(trTheme));
	_SAFE_RETURN_CALL(ConvertIDsOnFitPeaks(trTheme));
	
	return 0;
}

int PAThemeConvert::ConvertValue(TreeNode& trTheme)
{

	DB_OUT_STRING("Converting XF Values...");

	int nRet;
	_SAFE_RETURN_CALL(ConvertValueOnStart(trTheme));
	_SAFE_RETURN_CALL(ConvertValueOnBaselineMode(trTheme));
	_SAFE_RETURN_CALL(ConvertValueOnCreateBaseline(trTheme));
	_SAFE_RETURN_CALL(ConvertValueOnBaselineTreatment(trTheme));
	_SAFE_RETURN_CALL(ConvertValueOnFindPeaks(trTheme));
	_SAFE_RETURN_CALL(ConvertValueOnIntegratePeaks(trTheme));
	_SAFE_RETURN_CALL(ConvertValueOnFitPeaks(trTheme));
	
	return 0;
}

int PAThemeConvert::ConvertIDsOnStart(TreeNode& trTheme)
{
	PAGoalThemeIDConverter idcvt;
	return ConvertIDs(trTheme, &idcvt, PA_XFNAME_GOAL)
}

int PAThemeConvert::ConvertIDsOnBaselineMode(TreeNode& trTheme)
{
	PABaselineModeThemeIDConverter idcvt;
	return ConvertIDs(trTheme, &idcvt, PA_XFNAME_BASELINEMODE)
}

int PAThemeConvert::ConvertIDsOnCreateBaseline(TreeNode& trTheme)
{
	PACreateBaselineThemeIDConverter idcvt;
	return ConvertIDs(trTheme, &idcvt, PA_XFNAME_CREATEBASELINE)
}

int PAThemeConvert::ConvertIDsOnBaselineTreatment(TreeNode& trTheme)
{
	PABaselineTreatmentThemeIDConverter idcvt;
	return ConvertIDs(trTheme, &idcvt, PA_XFNAME_BASELINETREATMENT)
}

int PAThemeConvert::ConvertIDsOnFindPeaks(TreeNode& trTheme)
{
	PAFindPeaksThemeIDConverter idcvt;
	return ConvertIDs(trTheme, &idcvt, PA_XFNAME_FINDPEAKS)
}

int PAThemeConvert::ConvertIDsOnIntegratePeaks(TreeNode& trTheme)
{
	PAIntegratePeaksThemeIDConverter idcvt;
	return ConvertIDs(trTheme, &idcvt, PA_XFNAME_INTEGRATEPEAKS)
}

int PAThemeConvert::ConvertIDsOnFitPeaks( TreeNode& trTheme )
{
	PAFitPeaksThemeIDConverter idcvt;
	return ConvertIDs(trTheme, &idcvt, PA_XFNAME_FITPEAKS)
}

//Convert Value
int PAThemeConvert::ConvertValueOnStart(TreeNode& trTheme)
{
	PAGoalThemeValueConverter vcvt;
	return ConvertSingleValue(trTheme, &vcvt, PA_XFNAME_GOAL);
}

int PAThemeConvert::ConvertValueOnBaselineMode(TreeNode& trTheme)
{
	PAThemeGroupValueBaselineModeConverter gvcvt;
	return ConvertGroupValues(trTheme, &gvcvt);
}

int PAThemeConvert::ConvertValueOnCreateBaseline(TreeNode& trTheme)
{
	PAThemeGroupValueCreateBaselineConverter gvcvt;
	return ConvertGroupValues(trTheme, &gvcvt);
}

int	PAThemeConvert::ConvertValueOnBaselineTreatment(TreeNode& trTheme)
{
	PAThemeGroupValueBaselineTreatmentConverter	gvcvt;
	return ConvertGroupValues(trTheme, &gvcvt);
}

int PAThemeConvert::ConvertValueOnFindPeaks(TreeNode& trTheme)
{
	PAThemeGroupValueFindPeaksConverter gvcvt;
	return ConvertGroupValues(trTheme, &gvcvt);
}

int PAThemeConvert::ConvertValueOnIntegratePeaks(TreeNode& trTheme)
{
	PAThemeGroupValueIntegratePeaksConverter gvcvt;
	return ConvertGroupValues(trTheme, &gvcvt);
}

int PAThemeConvert::ConvertValueOnFitPeaks(TreeNode& trTheme)
{
	PAThemeGroupValueFitPeaksConverter gvcvt;
	return ConvertGroupValues(trTheme, &gvcvt);
}

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

///Sophy 7/17/2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
//virtual
int		PAThemeConvertSR6::ConvertIDs(TreeNode& trTheme)
{

	DB_OUT_STRING("Converting XF IDs...");

	int nRet;
	
	_SAFE_RETURN_CALL(ConvertIDsOnFitPeaks(trTheme));
	
	return 0;
}

int		PAThemeConvertSR6::ConvertIDsOnFitPeaks(TreeNode& trTheme)
{
	PAFitPeaksThemeIDConverterSR6 idcvt;
	return ConvertIDs(trTheme, &idcvt, PA_XFNAME_FITPEAKS)
}
///end CONVERT_PA_THEME_FROM_SR5_TO_SR6

///---Sim 07-16-2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
int		PAThemeConvertSR6::ConvertValue(TreeNode& trTheme)
{

	DB_OUT_STRING("Converting XF Values...");

	int nRet;
	_SAFE_RETURN_CALL(ConvertValueOnFitPeaks(trTheme));
	
	return 0;
}
int		PAThemeConvertSR6::ConvertValueOnFitPeaks(TreeNode& trTheme)
{
	PAThemeGroupValueFitPeaksConverterSR6 gvcvt;
	return ConvertGroupValues(trTheme, &gvcvt);
}
///---END CONVERT_PA_THEME_FROM_SR5_TO_SR6


/////////////////////////////////////////////////////////////////////////////////////////////////////////////
///------ Folger 08/07/09 QA80-13998 SUPPORT_GET_GOAL_AND_FITTING_REPORT_GRAPH_UID_FROM_PAWIZMANAGER
/// move to theme_utils.h
//#define	STR_THEME_NODE_TAGNAME_PREFIX	"node"
///------ End SUPPORT_GET_GOAL_AND_FITTING_REPORT_GRAPH_UID_FROM_PAWIZMANAGER
int 	ThemeElementConverter::GetIDFromTagName(LPCSTR lpcszTagName)
{
	string	strTagName(lpcszTagName);
	ASSERT(!strTagName.IsEmpty());
	
	string	strID = strTagName.Mid(strlen(STR_THEME_NODE_TAGNAME_PREFIX));	//theme node are format as "node????"
	return atoi(strID);
}

string	ThemeElementConverter::GetTagNameFromID(int ID)
{
	return STR_THEME_NODE_TAGNAME_PREFIX + ID;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define MASK_REPEAT_ID 0xFFFF0000
int		ThemeIDConverter::Convert(TreeNode& trThemeTree)
{
	if( !trThemeTree )
	{
		ASSERT(FALSE);
		return -1;
	}

	DB_OUT_STRING("\tConverting XF " + trThemeTree.Parent().tagName );

	Tree		trNewThemeRoot;
	TreeNode	trNewThemeTree = trNewThemeRoot.AddNode(STR_XFBAR_MULITIMODE_THEME_TREE);
	foreach( TreeNode trNode in trThemeTree.Children )
	{
		int nID = GetIDFromTagName(trNode.tagName);
		int nDestID = GetDestID(nID);
		if( nDestID < 0 )
		{
			///Sophy 7/17/2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
			//continue;
			if ( m_bKeepIfNotInTable )
				nDestID = nID;
			else
				continue;
			///end CONVERT_PA_THEME_FROM_SR5_TO_SR6
		}

		DB_OUT_ID_PAIR(nID, nDestID);

		string strNode = GetTagNameFromID(nDestID);
		TreeNode	trNewNode = trNewThemeTree.AddNode(strNode);
		trNewNode.Replace(trNode, true, true); //keep new tagname
	}
	
	trThemeTree.Replace(trNewThemeTree);
	
	AddIDs(trThemeTree);
	
	return 0;
}

int		ThemeIDConverter::AddIDs(TreeNode& trThemeTree)
{
	if( !trThemeTree )
	{
		ASSERT(FALSE);
		return -1;
	}
	DB_OUT_STRING("\tAdding New Nodes To XF " + trThemeTree.Parent().tagName);
	
	int nSize = m_vnAddedID.GetSize();
	for( int ii = 0; ii < nSize; ii++ )
	{
		string strNewNode = GetTagNameFromID(m_vnAddedID[ii]);
		TreeNode trNode = trThemeTree.AddNode(strNewNode);
		if( trNode )
		{
			string strMsg;
			strMsg.Format("\t\tAdd New Node To XF " + trThemeTree.Parent().tagName + " With ID %X", m_vnAddedID[ii]);
			DB_OUT_STRING(strMsg);
		}
		else
		{
			string strMsg;
			strMsg.Format("\t\tFail To Add New Node To XF " + trThemeTree.Parent().tagName + "With ID %X", m_vnAddedID[ii]);
			DB_OUT_STRING(strMsg);
		}
	}
	return 0;
}
	
int 	ThemeIDConverter::GetDestID(int nID)
{
	for( int ii = 0; ii < m_vbRepeatIDGrouped.GetSize(); ii++ )
	{
		if( !m_vbRepeatIDGrouped[ii] ) //accurate match has higher priority
		{
			if( nID == m_vnSourceID[ii] )
			{
				return m_vnDestID[ii];
			}
		}
		else//wild match
		{
			if( ( nID & MASK_REPEAT_ID ) == (m_vnSourceID[ii] & MASK_REPEAT_ID) )
			{
				return ( m_vnDestID[ii] & MASK_REPEAT_ID ) | ( nID & ~MASK_REPEAT_ID );
			}
		}
	}
	return -1;//invalid Dest ID, not in convertion table;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
PAGoalThemeIDConverter::PAGoalThemeIDConverter()
{
	vector<uint> vnSourceID = 
	{
		0x00050032
	};
	vector<uint> vnDestID = 
	{
		0x00060032
	};
	vector<byte> vbRepeatIDGrouped = 
	{
		0
	};
	m_vnSourceID = vnSourceID;
	m_vnDestID = vnDestID;
	m_vbRepeatIDGrouped = vbRepeatIDGrouped;
	
	ASSERT( m_vnSourceID.GetSize() == m_vnDestID.GetSize() && m_vnSourceID.GetSize() == m_vbRepeatIDGrouped.GetSize() );
	///Sophy 2/4/2009 comment out adding new IDs, as no need to convert any value in code.
	//vector<uint> vnAddedID =
	//{
		//0x00090032
	//};
	//m_vnAddedID = vnAddedID;
}

PABaselineModeThemeIDConverter::PABaselineModeThemeIDConverter()
{
	vector<uint> vnSourceID = 
	{
		0x00020032,
		0x00050032,
		0x00060032,
		0x00070000,
		0x00030000,
		0x00044002,
		0x00044001,
		0x00044005,
		0x00044004,
		0x00044064,
		0x000440c8
	};
	vector<uint> vnDestID = 
	{
		0x00030032,
		0x00070032,
		0x00080032,
		0x00090000,
		0x00050000,
		0x00064002,
		0x00064001,
		0x00064005,
		0x00040032,
		0x000B4064,
		0x000B40c8
	};
	vector<byte> vbRepeatIDGrouped = 
	{
		0, 0, 0, 1, 1,
		0, 0, 0, 0, 0,
		0
	};
	m_vnSourceID = vnSourceID;
	m_vnDestID = vnDestID;
	m_vbRepeatIDGrouped = vbRepeatIDGrouped;

	ASSERT( m_vnSourceID.GetSize() == m_vnDestID.GetSize() && m_vnSourceID.GetSize() == m_vbRepeatIDGrouped.GetSize() );
}

PACreateBaselineThemeIDConverter::PACreateBaselineThemeIDConverter()
{
	///Sophy 12/17/2008 v8.0987d since CP has fixed repeatID problem for single node branch, 0x00004001 will be convert to 0x00064001
	vector<uint> vnSourceID = 
	{
		0x00020032, 0x00030032, 0x00050032, 0x00040000, 0x00060000,
		0x00004001, 0x00070000, 0x000C0000
	};
	vector<uint> vnDestID = 
	{
		0x00020032, 0x00030032, 0x00050032, 0x00040000, 0x00060000,
		0x00064001, 0x00070000, 0x00090000
	};
	vector<byte> vbRepeatIDGrouped = 
	{
		0, 0, 0, 1, 1,
		0, 1, 1
	};
	m_vnSourceID = vnSourceID;
	m_vnDestID = vnDestID;
	m_vbRepeatIDGrouped = vbRepeatIDGrouped;

	ASSERT( m_vnSourceID.GetSize() == m_vnDestID.GetSize() && m_vnSourceID.GetSize() == m_vbRepeatIDGrouped.GetSize() );
}

PABaselineTreatmentThemeIDConverter::PABaselineTreatmentThemeIDConverter()
{
	vector<uint> vnSourceID = 
	{
		0x00020032, 
		0x00030032, 
		0x00040032, 
		0x00080032, 
		0x00090032,
		0x000A0032, 
		0x000C0032
	};
	vector<uint> vnDestID = 
	{
		0x00010032,
		0x00030032,
		0x00040032,
		0x00050032,
		0x00060032,
		0x00070032,
		0x00090032
	};
	vector<byte> vbRepeatIDGrouped = 
	{
		0,
		0,
		0,
		0,
		0,
		0,
		0
	};
	m_vnSourceID = vnSourceID;
	m_vnDestID = vnDestID;
	m_vbRepeatIDGrouped = vbRepeatIDGrouped;

	ASSERT( m_vnSourceID.GetSize() == m_vnDestID.GetSize() && m_vnSourceID.GetSize() == m_vbRepeatIDGrouped.GetSize() );
	
	vector<uint>	vnAddedID = 
	{
		0x00020032 //rescale node
	}
	m_vnAddedID = vnAddedID;
}

PAFindPeaksThemeIDConverter::PAFindPeaksThemeIDConverter()
{
	vector<uint> vnSourceID = 
	{
		0x00030032,
		0x00040032,
		0x00050032,
		0x00060032,
		0x00070032,
		0x00080032,
		0x00090032,
		0x000A0032,
		0x000B0032,
		0x000C0032,
		0x000D0032,
		0x000E0032,
		0x000F0032,
		0x00100032,
		0x00110032,
		0x00120032,
		0x00130032,
		0x00140032,
		0x00150032,
		0x00160032,
		0x00170032,
		0x001A0032,
		0x00180000,
		0x00190000
	};
	vector<uint> vnDestID = 
	{
		0x00020032,
		0x00030032,
		0x00040032,
		0x00050032,
		0x00060032,
		0x00070032,
		0x00080032,
		0x000A0032,
		0x000C0032,
		0x00090032,
		0x000D0032,
		0x000E0032,
		0x000F0032,
		0x00100032,
		0x00110032,
		0x00120032,
		0x00130032,
		0x00140032,
		0x00150032,
		0x00160032,
		0x00170032,
		0x001C0032,
		0x00180000,
		0x00190000
	};
	vector<byte> vbRepeatIDGrouped = 
	{
		0,0,0,0,0,
		0,0,0,0,0,
		0,0,0,0,0,
		0,0,0,0,0,
		0,0,1,1
	};
	
	m_vnSourceID = vnSourceID;
	m_vnDestID = vnDestID;
	m_vbRepeatIDGrouped = vbRepeatIDGrouped;
	ASSERT( m_vnSourceID.GetSize() == m_vnDestID.GetSize() && m_vnSourceID.GetSize() == m_vbRepeatIDGrouped.GetSize() );
	
	vector<uint> vnAddedID =
	{
		0x000B4014,
		0x000B4015,
		0x000B4016,
		0x000B4017,
		0x000B4018,
		0x001B0032
	};
	m_vnAddedID = vnAddedID;
}

PAIntegratePeaksThemeIDConverter::PAIntegratePeaksThemeIDConverter()
{
	vector<uint> vnSourceID = 
	{
		0x00040032,
		0x00050032,
		0x00060032,
		0x00070032,
		0x00080032,
		0x00090032,
		0x000A0032,
		0x000B0032,
		0x000C0032,
		0x000D0032,
		0x000E0032,
		0x000F0032,
		0x00100032,
		0x00110032,
		0x00130032,
		0x00120000,
		0x00140000
	};
	vector<uint> vnDestID = 
	{
		0x00030032,
		0x00070032,
		0x00090032,
		0x000A0032,
		0x000D0032,
		0x000E0032,
		0x000F0032,
		0x00100032,
		0x00110032,
		0x00120032,
		0x00130032,
		0x00140032,
		0x00190032,
		0x001A0032,
		0x00160032,
		0x00150000,
		0x00170000
	};
	vector<byte> vbRepeatIDGrouped = 
	{
		0, 0, 0, 0, 0,
		0, 0, 0, 0, 0,
		0, 0, 0, 0, 0,
		1, 1
	};
	
	m_vnSourceID = vnSourceID;
	m_vnDestID = vnDestID;
	m_vbRepeatIDGrouped = vbRepeatIDGrouped;

	ASSERT( m_vnSourceID.GetSize() == m_vnDestID.GetSize() && m_vnSourceID.GetSize() == m_vbRepeatIDGrouped.GetSize() );

	vector<uint> vnAddedID =
	{
		0x000B0032,
		0x000C0032, 
		0x00040032,
		0x00050032,
		0x00060032,
		0x001B0032
	}
	
	m_vnAddedID = vnAddedID;
}

PAFitPeaksThemeIDConverter::PAFitPeaksThemeIDConverter()
{
	vector<uint> vnSourceID = 
	{
		0x00050032, 0x00060032, 0x00070032, 0x00080032, 0x00090032,
		0x000E0032, 0x000A0000, 0x000B0000, 0x000C0000, 0x000D0000
	};
	vector<uint> vnDestID = 
	{
		0x00010032, 0x00020032, 0x00030032, 0x00040032, 0x00050032,
		0x00080032,	0x00060000, 0x00070000, 0x00090000, 0x000A0000
	};
	vector<byte> vbRepeatIDGrouped = 
	{
		0, 0, 0, 0, 0,
		0, 1, 1, 1, 1
	};
	vector<uint> vnAddedID = 
	{
		0x000943FC,
		0x000740A4
	};
	m_vnSourceID = vnSourceID;
	m_vnDestID = vnDestID;
	m_vbRepeatIDGrouped = vbRepeatIDGrouped;
	m_vnAddedID = vnAddedID;
	ASSERT( m_vnSourceID.GetSize() == m_vnDestID.GetSize() && m_vnSourceID.GetSize() == m_vbRepeatIDGrouped.GetSize() );
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define CHAR_SEP_VALUE_MAP		'|'

int		ThemeValueConverter::Convert(TreeNode& trThemeTree)
{
	if( !trThemeTree )
		return -1;
	
	DB_OUT_STRING("\tConverting XF " + trThemeTree.Parent().tagName );

	foreach( TreeNode trNode in trThemeTree.Children )
	{
		int nID = GetIDFromTagName(trNode.tagName);
		int nIndex = GetIndexInConvertTable(nID);
		if( nIndex >= 0 ) //need to convert value
		{
			int nNewValue;
			if( GetNodeNewValue(nIndex, trNode.nVal, nNewValue) )
			{				
				DB_OUT_IVALUE_PAIR(nID, trNode.nVal, nNewValue);	
				trNode.nVal = nNewValue;
			}
			else
			{
				DB_OUT_STRING("GetNodeNewValue Return Invalid Value!");
				return -1;
			}
		}
	}
	return 0;
}

int		ThemeValueConverter::GetIndexInConvertTable(int nID)
{
	for( int ii = 0; ii < m_vnIDs.GetSize(); ii++ )
	{
		if( nID == m_vnIDs[ii] )
			return ii;
	}
	return -1; //not in convert table
}

bool	ThemeValueConverter::GetNodeNewValue(int nIndex, int nOldValue, int& nNewValue)
{
	int nNumOld, nNumNew;
	vector<string> vsSrcValues, vsDestValues;
	nNumOld = m_vsSrcValuesMap[nIndex].GetTokens(vsSrcValues, CHAR_SEP_VALUE_MAP);
	nNumNew = m_vsDestValuesMap[nIndex].GetTokens(vsDestValues, CHAR_SEP_VALUE_MAP);
	
	ASSERT( nNumOld == nNumNew );
	if( nNumOld != nNumNew )
		return false;
	
	int nPos = vsSrcValues.Find((string)nOldValue);
	ASSERT( nPos >= 0 );
	if( nPos < 0 )
		return false;
	
	nNewValue = atoi(vsDestValues[nPos]);
	return true;
}

PAGoalThemeValueConverter::PAGoalThemeValueConverter()
{
	vector<uint> vnIDs =
	{
		0x00060032
	};
	vector<string> vsSrcValuesMap =
	{
		"0|1|2|3"
	};
	vector<string> vsDestValuesMap =
	{
		"0|1|3|4"
	}
	m_vnIDs = vnIDs;
	m_vsSrcValuesMap = vsSrcValuesMap;
	m_vsDestValuesMap = vsDestValuesMap;
	
	ASSERT( m_vnIDs.GetSize() == m_vsSrcValuesMap.GetSize() && m_vsSrcValuesMap.GetSize() == m_vsDestValuesMap.GetSize() );
}

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

#define	AUTO_ATTRIB_EQUALS_1	"::{Auto=1"
//#define AUTO_ATTRIB_EQUALS_0	"::{Auto=0"

int		ThemeGroupValueConverter::GroupConvert(TreeNode& trTheme, const GroupValueConvertTable& vct)
{
	bool	bValid = checkSizeConsistency(vct);
	if( !bValid )
	{
		ASSERT( bValid );
		DB_OUT_STRING("Detect Invalid GroupValueConvertTable!");
		return -1;
	}
	
	for( int ii = 0; ii < vct.vsDestIDs.GetSize(); ii++ )
	{
		TreeNode trDest;
		int nResult = GetXFThemeOneNode(trDest, trTheme, vct.vsDestIDs[ii]);
		if( GET_IGNORE == nResult )
			continue;
		
		if ( !trDest )
		{
			DB_OUT_STRING("Either Dest Node Not Found!");
			return -1;
		}
		
		string	 strParam;	
		int nOpType = getOpTypeAndValue(vct.vsOps[ii], strParam);
		switch( nOpType )
		{
		case OP_COPY_VALUE:
			TreeNode trSrc;
			int nResult = GetXFThemeOneNode(trSrc, trTheme, vct.vsSourceIDs[ii]);
			if( GET_IGNORE == nResult )
				continue;
			
			if ( !trSrc )
			{
				DB_OUT_STRING("Either Source Node Not Found!");
				return -1;
			}
			
			string strVal = trSrc.strVal;
			if ( STR_OP_PARAM_REMOVE_ATTRIB == strParam )
			{
				strVal = strVal.Mid(strVal.Find('}') + 1);
			}
			DB_OUT_STRVAL_PAIR(GetIDFromTagName(trDest.tagName), trDest.strVal, strVal)
			trDest.strVal = strVal;
			break;
		case OP_SET_VALUE:
			string strVal = strParam;
			DB_OUT_STRVAL_PAIR(GetIDFromTagName(trDest.tagName), trDest.strVal, strVal)
			trDest.strVal = strVal;
			break;
		case OP_SET_VALUES:
			vector<string> vsItems;
			strParam.GetTokens(vsItems, CHAR_VALUES_SEP);
			///Sophy, additional variable to complete value conversion
			Tree	trTmp;
			vector<int>		vnIDs;
			vector<string>	vsValues;
			string			strComment;
			
			trTmp.tt.strVals = vsItems;
			trTmp.tt.DataID = GetIDFromTagName(trDest.tagName);
			tree_get_values_with_ids(trTmp, vnIDs, vsValues);		
			octree_set_theme(&trTmp, &vnIDs, &vsValues, strComment);
			
			TreeNode trTmpDest = trTmp.GetNode(trDest.tagName);
			DB_OUT_STRVAL_PAIR(GetIDFromTagName(trDest.tagName), trDest.strVal, trTmpDest.strVal);
			trDest.Replace(trTmpDest);
			break;
		default:
			DB_OUT_STRING("Invalid Operation Type Found! @" + vct.vsOps[ii]);
			return -1;
		}
	}
	return 0;
}

bool	ThemeGroupValueConverter::checkSizeConsistency(const GroupValueConvertTable& vct)
{
	int nNumSrc = vct.vsSourceIDs.GetSize();
	int nNumDest = vct.vsDestIDs.GetSize();
	int nNumOps = vct.vsOps.GetSize();
	
	if( nNumSrc != nNumDest || nNumSrc != nNumOps )
		return false;
	
	return true;
}

int		ThemeGroupValueConverter::getOpTypeAndValue(LPCSTR lpcszOps, string& strParam)
{
	string strOps(lpcszOps);
	vector<string>	vsOps;
	strOps.GetTokens(vsOps, CHAR_OP_VALUE_SEP);
	
	if( vsOps.GetSize() < 1 )
	{
		DB_OUT_STRING("Can Not Convert Operation Type And Value!");
		return OP_INVALID_OP;
	}
	int nOpType = atoi(vsOps[0]);

	if ( vsOps.GetSize() >= 2 )
		strParam = vsOps[1];
	
	return nOpType;
}

bool	ThemeGroupValueConverter::getXFNameAndNodeName(LPCSTR lpcszNameAndID, string& strXFName, string& strNodeName)
{
	string	strNameAndID(lpcszNameAndID);

	vector<string>	vsNameAndID;
	strNameAndID.GetTokens(vsNameAndID, CHAR_OP_VALUE_SEP);
	
	ASSERT( vsNameAndID.GetSize() == 2 );
	if( vsNameAndID.GetSize() < 2 )
	{
		DB_OUT_STRING("Fail To Separate XFName And NodeName From " + strNameAndID);
		return false;
	}
	
	strXFName = vsNameAndID[0];
	strNodeName = GetTagNameFromID( atoi(vsNameAndID[1]) );
	return true;
}

int		ThemeGroupValueConverter::GetXFThemeOneNode(TreeNode& trNode, const TreeNode& trTheme, LPCSTR lpcszXFName, LPCSTR lpcszNodeName)
{
	TreeNode trThemeTree;
	int nResult = get_xf_themetree(trTheme, lpcszXFName, trThemeTree);
	if( GET_IGNORE == nResult )
		return GET_IGNORE;
	
	if( !trThemeTree )
	{
		DB_OUT_STRING("Fail To Get ThemeTree Of XF " + (string)lpcszXFName);
		
		ASSERT(FALSE);
		return GET_FAIL;
	}
	trNode = trThemeTree.GetNode(lpcszNodeName, false);
	if( !trNode )
	{
		DB_OUT_STRING("Fail To Get Node " + (string)lpcszNodeName +" From ThemeTree " + (string)lpcszXFName);
		
		ASSERT(FALSE);
		return GET_FAIL;
	}
	return GET_SUCCESS;
}
int		ThemeGroupValueConverter::GetXFThemeOneNode(TreeNode& trNode, const TreeNode& trTheme, LPCSTR lpcszNameAndID)
{
	string	strXFName, strNodeName;
	if ( getXFNameAndNodeName(lpcszNameAndID, strXFName, strNodeName) )
	{
		return GetXFThemeOneNode(trNode, trTheme, strXFName, strNodeName);
	}
	
	return GET_FAIL;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//construct convert table for basemode xf
static void	_construct_basemode_for_con_auto_attrib_1(GroupValueConvertTable& gvct)
{
	string strNANUM;
	strNANUM.Format("%.10g", NANUM);
	
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_BASELINEMODE + CHAR_OP_VALUE_SEP + PA_BASELINEMODE_CON_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + strNANUM);
}

static void	_construct_basemode_for_con_auto_attrib_0(GroupValueConvertTable& gvct)
{
	gvct.vsSourceIDs.Add(PA_XFNAME_BASELINEMODE + CHAR_OP_VALUE_SEP + PA_BASELINEMODE_CON_ID_SR5);
	gvct.vsDestIDs.Add(PA_XFNAME_BASELINEMODE + CHAR_OP_VALUE_SEP + PA_BASELINEMODE_CON_ID_SR5);
	gvct.vsOps.Add((string)OP_COPY_VALUE + CHAR_OP_VALUE_SEP + STR_OP_PARAM_REMOVE_ATTRIB);
	
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_BASELINEMODE + CHAR_OP_VALUE_SEP + PA_BASELINEMODE_MINMAX_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 4);
}

static void _construct_for_snap_value_1(GroupValueConvertTable& gvct)
{
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_BASELINEMODE + CHAR_OP_VALUE_SEP + PA_BASELINEMODE_SNAP_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 1);
	
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_CREATEBASELINE + CHAR_OP_VALUE_SEP + PA_CREATEBASELINE_SNAP_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 1);
}

static void	_construct_for_rescale_value(GroupValueConvertTable& gvct)
{
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_BASELINETREATMENT + CHAR_OP_VALUE_SEP + PA_BASELINE_TREATMENT_RESCALE_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 0);
}

static void _construct_for_derivative_value_1(GroupValueConvertTable& gvct)
{
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_FINDPEAKS + CHAR_OP_VALUE_SEP + PA_FINDPEAKS_DERIV_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 1);
	
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_FITPEAKS + CHAR_OP_VALUE_SEP + PA_FITPEAKS_DERIV_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 1);
}

static void _construct_findpeaks_for_deriv_smooth_first_value(GroupValueConvertTable& gvct)
{
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_FINDPEAKS + CHAR_OP_VALUE_SEP + PA_FINDPEAKS_DERIV_FIRST_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 0);
}

static void _construct_findpeaks_for_deriv_smooth_second_value(GroupValueConvertTable& gvct)
{	
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_FINDPEAKS + CHAR_OP_VALUE_SEP + PA_FINDPEAKS_DERIV_SEC_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 1);
}
static void _construct_findpeaks_for_deriv_smooth_fft_cutoff_value(GroupValueConvertTable& gvct)
{
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_FINDPEAKS + CHAR_OP_VALUE_SEP + PA_FINDPEAKS_DERIV_FFTCUTOFF_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 0.2);
}

static void _construct_integpeaks_for_intwindow_value(GroupValueConvertTable& gvct)
{
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_INTEGRATEPEAKS + CHAR_OP_VALUE_SEP + PA_INTEGPEAKS_INTWINDOW_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 1);
}

static void _construct_integpeaks_for_out_id_value(GroupValueConvertTable& gvct)
{
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_INTEGRATEPEAKS + CHAR_OP_VALUE_SEP + PA_INTEGPEAKS_OUTID_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 0);
}

static void _construct_fitpeaks_for_usesepx(GroupValueConvertTable& gvct)
{
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_FITPEAKS + CHAR_OP_VALUE_SEP + PA_FITPEAKS_USESEPX_ID);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 0);	
}
static void _construct_fitpeaks_for_functions_with_baseline(GroupValueConvertTable& gvct, LPCSTR lpcszFunctions, LPCSTR lpcszBaselineFunc )
{
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_FITPEAKS + CHAR_OP_VALUE_SEP + PA_FITPEAKS_FUNCTIONS_ID);
	gvct.vsOps.Add((string)OP_SET_VALUES + CHAR_OP_VALUE_SEP + lpcszFunctions);

	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_FITPEAKS + CHAR_OP_VALUE_SEP + PA_FITPEAKS_BASELINEFUNCTION_ID_SR5);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + lpcszBaselineFunc);
}

int		PAThemeGroupValueBaselineModeConverter::Convert(TreeNode& trTheme)
{
	if( !trTheme )
		return -1;
	
	DB_OUT_STRING("\tConverting XF " + PA_XFNAME_BASELINEMODE);
	
	TreeNode trCon;
	int nResult1 = GetXFThemeOneNode(trCon, trTheme, PA_XFNAME_BASELINEMODE, GetTagNameFromID(PA_BASELINEMODE_CON_ID_SR5));
	TreeNode trMinmax;
	int nResult2 = GetXFThemeOneNode(trMinmax, trTheme, PA_XFNAME_BASELINEMODE, GetTagNameFromID(PA_BASELINEMODE_MINMAX_ID_SR5));
	GroupValueConvertTable gvct;
	
	if( GET_FAIL == nResult1 || GET_FAIL == nResult2 )
	{
		DB_OUT_STRING("BaseMode Can Not Find con or minmax!");
		return -1;
	}
	if( GET_SUCCESS == nResult1 && GET_SUCCESS == nResult2 )
	{
		string strConValue = trCon.strVal;
		int nAuto = strConValue.Find(AUTO_ATTRIB_EQUALS_1) >= 0 ? 1 : 0;
		if( nAuto )
			_construct_basemode_for_con_auto_attrib_1(gvct);
		else
			_construct_basemode_for_con_auto_attrib_0(gvct);
	}
	
	TreeNode trNode;
	int nResult = GetXFThemeOneNode(trNode, trTheme, PA_XFNAME_BASELINEMODE, GetTagNameFromID(PA_BASELINEMODE_SNAP_ID_SR5));
	if( GET_FAIL == nResult )
	{
		DB_OUT_STRING("Snap Not Exist In BaseMode!");
		return -1;
	}
	if( GET_SUCCESS == nResult )
	{
		if( trNode.nVal )
			_construct_for_snap_value_1(gvct);
	}
		
	return GroupConvert(trTheme, gvct);
}


int		PAThemeGroupValueCreateBaselineConverter::Convert(TreeNode& trTheme)
{
	if( !trTheme )
		return -1;
	
	DB_OUT_STRING("\tConverting XF " + PA_XFNAME_CREATEBASELINE);
	
	TreeNode trNode;
	GroupValueConvertTable gvct;
	
	int nResult = GetXFThemeOneNode(trNode, trTheme, PA_XFNAME_CREATEBASELINE, GetTagNameFromID(PA_CREATEBASELINE_SNAP_ID_SR5));
	if( GET_FAIL == nResult )
	{
		DB_OUT_STRING("Snap Not Exist In BaseCreate!");
		return -1;
	}
	if( GET_SUCCESS == nResult )
	{
		if( trNode.nVal )
			_construct_for_snap_value_1(gvct);
	}	
	
	return GroupConvert(trTheme, gvct);
}

int		PAThemeGroupValueBaselineTreatmentConverter::Convert(TreeNode& trTheme)
{
	if ( !trTheme )
		return -1;
	DB_OUT_STRING("\tConverting XF " + PA_XFNAME_BASELINETREATMENT);
	
	TreeNode trNode;
	GroupValueConvertTable	gvct;
	int nResult = GetXFThemeOneNode(trNode, trTheme, PA_XFNAME_BASELINETREATMENT, GetTagNameFromID(PA_BASELINE_TREATMENT_RESCALE_ID_SR5));
	if ( GET_FAIL == nResult )
	{
		DB_OUT_STRING("Rescale Not Exist In BaeslineTreatment!");
		return -1;
	}
	if ( GET_SUCCESS == nResult )
	{
		_construct_for_rescale_value(gvct);
	}
	return GroupConvert(trTheme, gvct);
}
int		PAThemeGroupValueFindPeaksConverter::Convert(TreeNode& trTheme)
{
	if( !trTheme )
		return -1;
	
	DB_OUT_STRING("\tConverting XF " + PA_XFNAME_FINDPEAKS);

	TreeNode trNode;
	GroupValueConvertTable gvct;
	
	int nResult = GetXFThemeOneNode(trNode, trTheme, PA_XFNAME_FINDPEAKS, GetTagNameFromID(PA_FINDPEAKS_DERIV_ID_SR5));
	if( GET_FAIL == nResult )
	{
		DB_OUT_STRING("Can Not Find Derivative ThemeTree Of " + PA_XFNAME_FINDPEAKS);
		return -1;
	}
	if( GET_SUCCESS == nResult )
	{
		if( trNode.nVal )
			_construct_for_derivative_value_1(gvct);
	}
	
	nResult = GetXFThemeOneNode( trNode, trTheme, PA_XFNAME_FINDPEAKS, GetTagNameFromID(PA_FINDPEAKS_DERIV_FIRST_ID_SR5) );
	if( GET_FAIL == nResult )
	{
		DB_OUT_STRING("Can Not Find deriv_smooth->first Of" + PA_XFNAME_FINDPEAKS);
		return -1;
	}
	if( GET_SUCCESS == nResult )
		_construct_findpeaks_for_deriv_smooth_first_value(gvct);
	
	nResult = GetXFThemeOneNode( trNode, trTheme, PA_XFNAME_FINDPEAKS, GetTagNameFromID(PA_FINDPEAKS_DERIV_SEC_ID_SR5) );
	if( GET_FAIL == nResult )
	{
		DB_OUT_STRING("Can Not Find deriv_smooth->second Of" + PA_XFNAME_FINDPEAKS);
		return -1;
	}
	if( GET_SUCCESS == nResult )
		_construct_findpeaks_for_deriv_smooth_second_value(gvct);
	
	nResult = GetXFThemeOneNode( trNode, trTheme, PA_XFNAME_FINDPEAKS, GetTagNameFromID(PA_FINDPEAKS_DERIV_FFTCUTOFF_ID_SR5) );
	if( GET_FAIL == nResult )
	{
		DB_OUT_STRING("Can Not Find deriv_smooth->fft_cutoff Of" + PA_XFNAME_FINDPEAKS);
		return -1;
	}
	if( GET_SUCCESS == nResult )
		_construct_findpeaks_for_deriv_smooth_fft_cutoff_value(gvct);
	
	return GroupConvert(trTheme, gvct);
}

int		PAThemeGroupValueIntegratePeaksConverter::Convert(TreeNode& trTheme)
{
	if( !trTheme )
		return -1;
	DB_OUT_STRING("\tConverting XF " + PA_XFNAME_INTEGRATEPEAKS);
	
	TreeNode trNode;
	GroupValueConvertTable gvct;
	
	int nResult = GetXFThemeOneNode(trNode, trTheme, PA_XFNAME_INTEGRATEPEAKS, GetTagNameFromID(PA_INTEGPEAKS_INTWINDOW_ID_SR5) );
	if( GET_FAIL == nResult )
	{
		DB_OUT_STRING("Can Not Find intwindow Of " + PA_XFNAME_INTEGRATEPEAKS);
		return -1;
	}
	if( GET_SUCCESS == nResult )
		_construct_integpeaks_for_intwindow_value(gvct);
	
	nResult = GetXFThemeOneNode(trNode, trTheme, PA_XFNAME_INTEGRATEPEAKS, GetTagNameFromID(PA_INTEGPEAKS_OUTID_ID_SR5) );
	if( GET_FAIL == nResult )
	{
		DB_OUT_STRING("Can Not Find out_id Of " + PA_XFNAME_INTEGRATEPEAKS);
		return -1;
	}
	if( GET_SUCCESS == nResult )
		_construct_integpeaks_for_out_id_value(gvct);
	
	return GroupConvert(trTheme, gvct);
}

int		PAThemeGroupValueFitPeaksConverter::Convert(TreeNode& trTheme)
{
	if( !trTheme )
		return -1;
	
	DB_OUT_STRING("\tConverting XF " + PA_XFNAME_FITPEAKS);
	
	TreeNode trNode;
	GroupValueConvertTable gvct;
	
	int nResult = GetXFThemeOneNode(trNode, trTheme, PA_XFNAME_FITPEAKS, GetTagNameFromID(PA_FITPEAKS_DERIV_ID_SR5));
	if( GET_FAIL == nResult )
	{
		DB_OUT_STRING("Can Not Find Derivative ThemeTree of  " + PA_XFNAME_FITPEAKS);
		return -1;
	}
	if ( GET_SUCCESS == nResult )
	{
		if( trNode.nVal )
			_construct_for_derivative_value_1(gvct);
	}
	
	//convert baseline function
	nResult = GetXFThemeOneNode(trNode, trTheme, PA_XFNAME_FITPEAKS, GetTagNameFromID(PA_FITPEAKS_BASELINEPARAMETERS_ID));
	if( GET_FAIL == nResult )
	{
		DB_OUT_STRING("Can Not Find BaselineParameters ThemeTree of " + PA_XFNAME_FITPEAKS);
		return -1;
	}
	if ( GET_SUCCESS == nResult && trNode.nVal > 0 )
	{
		nResult = GetXFThemeOneNode(trNode, trTheme, PA_XFNAME_FITPEAKS, GetTagNameFromID(PA_FITPEAKS_FUNCTIONS_ID));
		if( GET_FAIL == nResult )
		{
			DB_OUT_STRING("Can Not Find Functions ThemeTree of " + PA_XFNAME_FITPEAKS);
			return -1;
		}
		///----Convert Special String To String Vector Begin
		Tree tr;
		tr.AddNode(trNode);
		vector<int> vnIDs;
		vector<string> vsValues;
		string strComment;		
		
		Tree trTmp;
		trTmp.Functions.DataID = PA_FITPEAKS_FUNCTIONS_ID;
		int nDupID = 0;
		
		octree_get_theme(&tr, &vnIDs, &vsValues, &strComment);
		ASSERT( PA_FITPEAKS_FUNCTIONS_ID == vnIDs[0] );
		tree_set_values_by_ids(trTmp, vnIDs, vsValues, 0, &nDupID);
		
		vector<string> vsFunctions;
		vsFunctions = trTmp.Functions.strVals;		
		///----Convert Special String To String Vector End
		
		nResult = GetXFThemeOneNode(trNode, trTheme, PA_XFNAME_FITPEAKS, GetTagNameFromID(PA_FITPEAKS_BASELINEFUNCTION_ID_SR5));
		if( GET_FAIL == nResult )
		{
			DB_OUT_STRING("Can Not Find BaselineFunction ThemeTree of " + PA_XFNAME_FITPEAKS);
			return -1;
		}
		
		//move baseline function from Functions to BaselineFunction
		ASSERT( vsFunctions.GetSize() );
		string strBaselineFunc = vsFunctions[0];
		vsFunctions.RemoveAt(0);
		string strFunctions;
		strFunctions.SetTokens(vsFunctions, CHAR_VALUES_SEP);
		_construct_fitpeaks_for_functions_with_baseline(gvct, strFunctions, strBaselineFunc);
	}
	nResult = GetXFThemeOneNode(trNode, trTheme, PA_XFNAME_FITPEAKS, GetTagNameFromID(PA_FITPEAKS_USESEPX_ID));
	if ( GET_SUCCESS == nResult )
	{
		_construct_fitpeaks_for_usesepx(gvct);
	}
	return GroupConvert(trTheme, gvct);
}

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



//////////////////////////////Theme IDs from SR5 to SR6///////////////////////////////////////////////////

///Sophy 7/17/2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
PAFitPeaksThemeIDConverterSR6::PAFitPeaksThemeIDConverterSR6()
{
	vector<uint> vnAddedID = 
	{
		0x000740B4
	};
	
	m_vnAddedID = vnAddedID;
	
	m_bKeepIfNotInTable = true; //since we convert old theme to SR5 and then convert to SR6, most useful nodes are not in convert table here, we should keep them in theme tree.
}
///end CONVERT_PA_THEME_FROM_SR5_TO_SR6
///////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////Theme Values from SR5 to SR6///////////////////////////////////////////////////
///Sophy 7/17/2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
static void _construct_fitpeaks_for_peaknum(GroupValueConvertTable& gvct)
{
	gvct.vsSourceIDs.Add("");
	gvct.vsDestIDs.Add(PA_XFNAME_FITPEAKS + CHAR_OP_VALUE_SEP + PA_FITPEAKS_PEAKNUM_ID_SR6);
	gvct.vsOps.Add((string)OP_SET_VALUE + CHAR_OP_VALUE_SEP + 0);
}
///end CONVERT_PA_THEME_FROM_SR5_TO_SR6

///---Sim 07-16-2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
int		PAThemeGroupValueFitPeaksConverterSR6::Convert(TreeNode& trTheme)
{
	///Sophy 7/17/2009 CONVERT_PA_THEME_FROM_SR5_TO_SR6
	if ( !trTheme )
		return GET_FAIL;
	
	DB_OUT_STRING("\tConverting XF " + PA_XFNAME_FITPEAKS);
	
	TreeNode trNode;
	GroupValueConvertTable gvct;
	
	int nResult = GetXFThemeOneNode(trNode, trTheme, PA_XFNAME_FITPEAKS, GetTagNameFromID(PA_FITPEAKS_PEAKNUM_ID_SR6));
	if ( GET_SUCCESS == nResult )
	{
		_construct_fitpeaks_for_peaknum(gvct);
	}
	
	return GroupConvert(trTheme, gvct);
	///end CONVERT_PA_THEME_FROM_SR5_TO_SR6
}
///---END CONVERT_PA_THEME_FROM_SR5_TO_SR6
