#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	mode_sweeps,
	mode_continuous,
	mode_concatenated,
};
//put additional include files here
#include <GetNbox.h>
#include <..\system\oExtFile.h>
#include <..\originlab\pClampImport.h>
#include <..\originlab\XFunctionEx.h> //<XFbase.h>
#include <..\originlab\grobj_utils.h>
#include <..\originlab\graph_utils.h>
#include <..\originlab\fu_utils.h> // Hong 03/08/07 SUPPORT_RELATIVE_DATA_RANGE

///////////////////////////////////////////////////////////////////////
//////// modification log
/// Hong 06/16/08 QA80-10360 FIX_PLOT_SELECTION_FAIL_UPDATE_AFTER_CHANGE_FILE_INDEX
/// Hong 08/08/08 QA80-10360 FIX_MULTI_PCLAMP_FAIL_REPLOT_IN_PLOT_CONTROL
/// Hong 08/08/08 v8.0918b MORE_INVALID_CHECKING
/// Hong 01/15/09 FIX_PCLAMP_PLOT_FAIL_HANDLE_TIME_OFFSET_OF_HOLDING_DURATION
/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
/// Sim 04-16-2009 QA80-13318 IMPROVE_HONG_FIX_REIMPORT_FAIL_GET_CORRECT_ROW_NUM
/// Hong 04/23/09 QA80-13222-P7 FIX_TAG_TIME_IS_WRONG_WHEN_CHECK_HOLDING_DURATION
/// Hong 08/20/09 QA80-13483 -P2 REMOVE_UNFRIENDLY_ERR_MSG_WHEN_REPLOT_FROM_PCLAMP_PLOT_CONTROL
/// Hong 02/26/10 QA80-10360-P16 FIX_LAST_EPISODE_UNCHECKED_FAIL_SAVE_WHEN_REOPEN_XF
///////////////////////////////////////////////////////////////////////

/// Hong 06/14/07 v8.0641 USER_KEYWORD_FOR_COMBO_STRING
//enum
//{
	//PLOT_MODE_SWEEPS = 0, 
	//PLOT_MODE_CONTINUOUS,
	//PLOT_MODE_CONCANITATED
//};
/// end USER_KEYWORD_FOR_COMBO_STRING

/// Hong 05/22/07 v8.0623 FIX_CRASH_CAUSE_BY_REATTACH_XFBAR
enum
{
	PLOT_CTRL_NOT_SHOW = 0,
	PLOT_CTRL_SHOW,
	PLOT_CTRL_NO_UPDATE
};
/// end FIX_CRASH_CAUSE_BY_REATTACH_XFBAR

//// AW 11/08/06 SET_COLOR_IN_PCLAMP
static void _set_color_to_grapglayer(GraphLayer& gl)
{
	if ( !gl )
		return;
	int nIndex = 0;
	foreach (DataPlot dp in gl.DataPlots)
	{
		// Change the display range of the data plot to show only points from 5 to 10:
		/// Hong 05/23/07 AVOID_WHITE_COLOR_MIXED_WITH_BKGRND
		// temp for 14 to loop
		//dp.SetColor(nIndex++);
		dp.SetColor(nIndex % 14);
		nIndex++;
		/// end AVOID_WHITE_COLOR_MIXED_WITH_BKGRND
	}	
}
/// END SET_COLOR_IN_PCLAMP

/// AW 11/08/06 PCLAMP_ZOOM
static void _set_layey_range(Page& pg, double dXEnd, int nScaleLayer)
{
	GraphLayer glScale = pg.Layers(nScaleLayer);
	glScale.X.To = dXEnd;
//	pg.Refresh(true);
//	pg.LT_execute("run.section(pCLAMP, OnNewPlot)");
}
/// END PCLAMP_ZOOM

/// SY 2006-11-03 v8.0505 ADD_SCALER_OBJECT

static bool _arrange_link_layers_and_add_scaler(GraphPage &gp, int nChannels, StringArray &saStrUnits, int nBaseLayer = 0, int nHeightChangelayer = -1, int nSecondHeight = 50)
{
	if( !gp )
		return false;
	
	if ( 1 == nChannels )
	{
		GraphLayer gl;
		gl = gp.Layers(nChannels);
		gl.Destroy();  
	}

	double dTop = 2;
	page_arrange_link_layers(gp, nBaseLayer, -1, dTop, -1000, nHeightChangelayer, nSecondHeight); 

	GraphLayer gl1;
	gl1 = gp.Layers(nBaseLayer);

	double dBottom;
	layer_get_position(gl1, NULL, NULL, NULL, &dBottom);

	GraphObject go = gl1.GraphObjects("line");
	if(go)
		move_vline(go, dTop, dBottom);
	
	GraphLayer gl;

	int nSize = saStrUnits.GetSize();
	for( int nIndex = 0; nIndex < nSize; nIndex++ )
	{
		if( gl = gp.Layers(nIndex + nBaseLayer) ) 
		{
			GraphObject goScaler;
			double dd = fabs(gl.Y.To - gl.Y.From)/5.;
			add_y_scaler(gl, go, dd, saStrUnits[nIndex]);
		}
	}
	
	gp.Refresh(true);
	gp.LT_execute("run.section(pCLAMP, OnNewPlot)");
	return  true;
}

static bool _prepare_graph_page(GraphPage &gp, LPCSTR lpcszShortName, LPCSTR lpcszName, bool bAddPickValue)
{
	GraphLayer gl;
	//justin 02/03/2007	OUTPUT_GRAPH
	//gp.Create("pClamp.otp");
	if(gp.IsValid())
	{
		/// Hong 11/09/07 v8.744 FIX_PLOT_PCLAMP_FAIL_LOAD_SYSTEM_THEME
		//gp.LoadTemplate("pClamp.otp");
		bool bLoadTheme = true;
		page_load(gp, "pClamp.otp", NOCLICK_USE_DEFAULT, &bLoadTheme);
		/// end FIX_PLOT_PCLAMP_FAIL_LOAD_SYSTEM_THEME		
	}
	else
	{
		gp.Create("pClamp.otp");
	}
	//end OUTPUT_GRAPH
	gp.Rename(lpcszShortName);
	gp.SetLongName(lpcszName, false);
	
	gl = gp.Layers(0);
	if( !bAddPickValue )
	{
		/// Hong 03/26/07 QA80-9457 v8.0589b IMPROVE_AXIS_SCROOLBAR
		/*
		gl.RemoveGraphObject("line");
		gl.RemoveGraphObject("show");
		gl.RemoveGraphObject("add");
		*/
		gl.GraphObjects("line").Show(false);
		gl.GraphObjects("show").Show(false);
		gl.GraphObjects("add").Show(false);
		/// END IMPROVE_AXIS_SCROOLBAR
	}
	
	return gp ? true : false;
}

static void _prepare_layers(GraphPage &gp, Worksheet& iw, int nStartCol, int nChannels, int nSweeps)
{
	if( !gp )
		return;
	
	//_set_layey_range(gp, dEndTime, 0);
	GraphLayer gl;
	for( int ii = 0; ii < nChannels; ii++ )
	{
		_get_layer(iw, gl, gp, nStartCol, ii);
		nStartCol += nSweeps;
	}
}

static BOOL _get_layer(Worksheet& iw, GraphLayer &gl, GraphPage &gp, int nIndex, int nChannel)
{
	string strName;
	strName = iw.Columns(nIndex).GetComments();
	
	if( 0 == nChannel || 1 == nChannel )
		gl = gp.Layers(nChannel);
	else
		add_x_link_layer(gp, gl, 1, 0);

	if( gl )
		gl.SetName(strName);
	
	return gl ? TRUE : FALSE;
}
/// end ADD_SCALER_OBJECT

///---Sim 11-06-2006 FILE_SETTING_UTILS_FUNCTION
static bool _get_channel_sweep_number(TreeNode& trFileNode, int& nChannels, int& nSweeps)
{
	if ( !trFileNode.Channels )
		return false;
	if ( !trFileNode.Sweeps )
		return false;
	
	nChannels = nSweeps = 0;
	
	foreach( TreeNode trChannel in trFileNode.Channels.Children )
	{
		if ( trChannel.nVal )
			nChannels++;
	}
	
	foreach( TreeNode trSweep in trFileNode.Sweeps.Children )
	{
		if ( trSweep.nVal )
			nSweeps++;
	}
	
	if(0 == nChannels || 0 == nSweeps)
		return false;
	
	return true;
}
///---END FILE_SETTING_UTILS_FUNCTION

/// Hong 06/11/07 v8.0638c MORE_VALID_CHECK
//static void _convert_trSetting(TreeNode& trSetting, TreeNode& trPlotSetting)
static bool _convert_trSetting(TreeNode& trSetting, TreeNode& trPlotSetting)
/// end MORE_VALID_CHECK
{
	trSetting.RemoveChildrenWithPrefix();
	/// Hong 06/11/07 v8.0638c MORE_VALID_CHECK
	if ( !trPlotSetting && trPlotSetting.GetNodeCount() < 0 )
		return false;
	/// end MORE_VALID_CHECK
	//trSetting.Replace( trPlotSetting.Clone(), true, true );
	/// AW 05/08/07 MORE_ON_PCLAMP_PLOT
	//TreeNode trFileSetting = trPlotSetting.AddNode("FileSetting");
	//trFileSetting.Replace( trPlotSetting.Clone(), true, true );
	TreeNode trFileSetting = trSetting;
	trSetting.Replace( trPlotSetting.Clone(), true, true );
	trSetting.SetAttribute(STR_LABEL_ATTRIB, _L("Plot Selection"));
	
	/// Hong 05/14/07 v8.0617 ADD_STIMULUS_SELECT_OPTION
	trFileSetting.Stimulus.Show = 0; // hidden Stimulus avoid edit
	/// END ADD_STIMULUS_SELECT_OPTION
	
	//trFileSetting.InfoFileNormal.Show = 0;
	/// Hong 06/04/07 v8.0623 USE_MACRO_FOR_MORE_FRIENDLY_NAME
	//trFileSetting.SkipPointsOptions.Show = 0;	
	TreeNode trSkipPointsOption = trFileSetting.GetNode(STR_FILTER_PARTIAL_NODE);
	if ( trSkipPointsOption )
		trSkipPointsOption.Show = 0;
	/// end USE_MACRO_FOR_MORE_FRIENDLY_NAME
	/*
	TreeNode trChannels = trFileSetting.Channels;
	trChannels.SetAttribute(STR_ATTRIB_DISPFMT, DISPLAY_EDITOR_CHECK_ON_LEFT);
	TreeNode trSweeps = trFileSetting.Sweeps;
	trSweeps.SetAttribute(STR_ATTRIB_DISPFMT, DISPLAY_EDITOR_CHECK_ON_LEFT);
	*/
	/// END MORE_ON_PCLAMP_PLOT	
	
	foreach(TreeNode trChannel in trFileSetting.Channels.Children)
	{
		if( !trChannel.nVal )
			//tn.RemoveChild(trLeaf);
			/// Hong 05/10/07 v8.0614 GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE
			//trChannel.Remove();
			trChannel.Show = 0;
			/// END GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE
		/// AW 05/08/07 MORE_ON_PCLAMP_PLOT
		else
			trChannel.SetAttribute(STR_ATTRIB_DISPFMT, DISPLAY_EDITOR_CHECK_ON_LEFT);
		/// END MORE_ON_PCLAMP_PLOT

	}
	foreach(TreeNode trSweep in trFileSetting.Sweeps.Children)
	{
		if( !trSweep.nVal )
			//tn.RemoveChild(trLeaf);
			/// Hong 05/10/07 v8.0614 GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE
			//trSweep.Remove();
			trSweep.Show = 0;
			/// END GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE
		/// AW 05/08/07 MORE_ON_PCLAMP_PLOT
		else
			trSweep.SetAttribute(STR_ATTRIB_DISPFMT, DISPLAY_EDITOR_CHECK_ON_LEFT);
		/// END MORE_ON_PCLAMP_PLOT

	}
	return true; // Hong 06/11/07 v8.0638c MORE_VALID_CHECK
}

static int _list_imported_data_and_init_trSetting(TreeNode& trGetN)
{
	TreeNode trFiles;
	if( !_find_imported_datas_node(trGetN, trFiles) )
	{
		trGetN.trSetting.RemoveChildrenWithPrefix();
		trGetN.findex.SetAttribute(STR_COMBO_ATTRIB, "<none>");
		trGetN.findex.nVal = 0;
		return false;
	}
	/// Hong 06/11/07 v8.0638c MORE_VALID_CHECK
	//_convert_trSetting(trGetN.trSetting, trFiles.FirstNode.Import.trSetting);
	if ( !trFiles.FirstNode || !trFiles.FirstNode.Import || !trFiles.FirstNode.Import.trSetting )
		return false;
	
	if ( ! _convert_trSetting(trGetN.trSetting, trFiles.FirstNode.Import.trSetting) )
		return false;
	/// end MORE_VALID_CHECK
	/// set option by imported file info
	int nStimulur = trFiles.FirstNode.Import.WavStimulu.nVal + trFiles.FirstNode.Import.DigStimulu.nVal;
	if( nStimulur > 0)
		trGetN.stimulur.Show = true;
	else
	{
		trGetN.stimulur.Show = false;
		trGetN.stimulur.nVal = 0; ///---Sim 03-16-2007 ADD_STICK_STIMULUS_OPTION_ON_XF_GUI add stimulus should be off if it not show
	}
	
	TreeNode trTagsNode = tree_get_node_by_tagname(trFiles.FirstNode, "FileTags", true);
	if(!trTagsNode.IsValid()) 
	{
		trGetN.tag.nVal = 0; // Hong 05/15/07 should be turn off is hidden
		trGetN.tag.Show = false;
	}
	else
		trGetN.tag.Show = true;
	/// ---
	vector<string> sa;
	foreach( TreeNode tn in trFiles.Children )
	{
		string strFile;
		strFile.Format("File%d:", sa.GetSize() + 1);
		strFile += tn.Info.FileName.strVal;
		sa.Add(strFile);
	}
	string strDataFiles = str_combine(sa, "|");
	trGetN.findex.SetAttribute(STR_COMBO_ATTRIB, strDataFiles);
	// Hidden findex option if only one pclamp file in current iw
	if(sa.GetSize() < 2)
		trGetN.findex.Show = false;
	else
		trGetN.findex.Show = true;
	
	return true;
}

static int _update_trSetting(TreeNode& trGetN)
{
	TreeNode trFiles;
	if( !_find_imported_datas_node(trGetN, trFiles) )
	{
		trGetN.trSetting.RemoveChildrenWithPrefix();
		return false;
	}
	int nFile = trGetN.findex.nVal;
	foreach(TreeNode tn in trFiles.Children)
	{
		if( !nFile )
		{
			_convert_trSetting(trGetN.trSetting, tn.Import.trSetting);
			
			TreeNode trTagsNode = tree_get_node_by_tagname(tn, "FileTags", true);
			if(!trTagsNode.IsValid()) 
				trGetN.tag.Show = false;
			else
				trGetN.tag.Show = true;
			
			int nStimulur = tn.Import.WavStimulu.nVal + tn.Import.DigStimulu.nVal;
			if( nStimulur > 0)
				trGetN.stimulur.Show = true;
			else
			{
				trGetN.stimulur.Show = false;
				trGetN.stimulur.nVal = 0; ///---Sim 03-16-2007 ADD_STICK_STIMULUS_OPTION_ON_XF_GUI add stimulus should be off if it not show
			}
			
			break;
		}
		nFile--;
	}
	
	return true;
}

static int _find_imported_datas_node(TreeNode& trGetN, TreeNode& trFiles)
{
	Tree trImported;
	trFiles = trImported.AddNode("ImportedFiles");
	int nRet = 0;

	Worksheet iw;
	bool bOK = okxf_resolve_string_get_origin_object(trGetN.iw.strVal, &iw);

	if( !bOK || !iw.IsValid() )
		return nRet;
	
	Page pg;
	iw.GetParent(pg);
	Tree trBinary;
	if( !tree_get_binary_storage(trBinary, pg, IFI_BINARY_STORAGE_NAME) )
		return nRet;
	
	int nIndex = iw.GetIndex();
	foreach(TreeNode tn in trBinary.Children)
	{
		TreeNode trRange = tree_get_node_by_tagname(tn, "DataRange", true);
		if(!trRange.IsValid())
			continue;
		/// Hong 03/09/07 SKIP_INVALID_RANGE
		if( tn.Info.CoveredByAnotherImport && ("Yes" == tn.Info.CoveredByAnotherImport.strVal) )
			continue;
		/// end SKIP_INVALID_RANGE
		
		Worksheet wksTemp;
		int nStartCol, nEndCol;
		DataRange dr;
		/// Hong 02/07/07 CREATE_DATARANGE_BY_UID
		//dr.Create(trRange);
		//dr.GetRange(wksTemp, nStartCol, nEndCol);
		/// Hong 03/08/07 SUPPORT_RELATIVE_DATA_RANGE
		//UINT uid = trRange.RangeUID.nVal;
		//dr = (DataRange)Project.GetObject(uid);
		dr = get_and_check_range(trRange, pg.GetName());
		/// end SUPPORT_RELATIVE_DATA_RANGE
		///---Sim 11-01-2007 FIX_REIMPORT_RUNTIME_ERROR
		//if( !dr.IsValid() && (0 == dr.GetNumData()) )
		if( !dr.IsValid() || (0 == dr.GetNumData()) )
		///---END FIX_REIMPORT_RUNTIME_ERROR
			//return nRet;
			continue; // Hong should only skip invalid datarange
		dr.GetRange(wksTemp, nStartCol, nEndCol);
		/// end CREATE_DATARANGE_BY_UID
		
		if( nIndex == wksTemp.GetIndex() )
		{
			trFiles.AddNode(tn.Clone());
			nRet++;
		}
	}

	return nRet;
}


static bool _is_tree_node_not_hidden(TreeNode& trNode)
{
	int nShow = 1;
	if ( !trNode.GetAttribute(STR_SHOW_ATTRIB, nShow) || 1 == nShow )
		return true;
	
	return false;
}

static void _check_tag_sweep_in_selected(TreeNode& trFileTags, TreeNode& trSweepInfo, vector<int>& vnIndex)
{
	foreach(TreeNode trTag in trFileTags.Children)
	{
		int nSweepIndex = 1;
		int nPlotIndex = -1;
		bool bInSelect = false;
		
		foreach(TreeNode trSweep in trSweepInfo.Children)
		{
			/// Hong 05/10/07 v8.0614 GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE
			/*
			if(tn.nVal)
			{
				
				string strTemp, strLabel;
				strTemp.Format("#%d", trTag.SweepNum.nVal);
				tn.GetAttribute(STR_LABEL_ATTRIB, strLabel);
				if( 0 == strTemp.CompareNoCase(strLabel) )
				{
					vnIndex.Add(nIndex);
					bInSelect = true;
				}
			}
			*/
			if (trSweep.nVal )
			{
				nPlotIndex++;
				if (  nSweepIndex == trTag.SweepNum.nVal )
				{
					vnIndex.Add(nPlotIndex); // SweepNum is 1 offset, as Column Index is 0 offset
					bInSelect = true;	
					break;
				}
			}
			
			if ( _is_tree_node_not_hidden(trSweep) ) // if not hidden
				nSweepIndex++;
			/// END GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE			
		}
		if( !bInSelect )
			vnIndex.Add(-1);
	}
}

//static bool _add_plot(Worksheet& wksTarget, TreeNode& trPlotInfo, TreeNode& trSetting, int nCurCol, bool AddTags , int nPlotMode, bool bAddPickValue)
//static bool _add_plot(Worksheet& wksTarget, TreeNode& trPlotInfo, TreeNode& trSetting, int nCurCol, bool AddTags , int nPlotMode, bool bAddPickValue, bool bAddScrollbar) // Hong 01/12/07 ADD_SCROLLBAR_TO_PLOT
//static bool _add_plot(Worksheet& wksTarget, TreeNode& trPlotInfo, TreeNode& trSetting, int nCurCol, bool AddTags , int nPlotMode, bool bAddPickValue, bool bAddScrollbar, GraphPage& gp) // Justin 02/03/07 OUTPUT_GRAPH
/// Hong 05/11/07 v8.0616 MORE_INFO_FOR_PLOT_CONTROL
//static bool _add_plot(Worksheet& wksTarget, TreeNode& trPlotInfo, TreeNode& trSetting, int nCurCol, bool AddTags , int nPlotMode, bool bAddPickValue, bool bAddScrollbar, GraphPage& gp, bool bStickStimulus) ///---Sim 03-16-2007 ADD_STICK_STIMULUS_OPTION_ON_XF_GUI
//// AW 05/17/07 FIX_REIMPORT_PROBELM
//static bool _add_plot(Worksheet& wksTarget, TreeNode& trPlotInfo, TreeNode& trSetting, int nCurCol, bool AddTags , int nPlotMode, bool bAddPickValue, bool bAddScrollbar, GraphPage& gp, bool bStickStimulus, bool bCtrlPanel)
/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
//static bool _add_plot(Worksheet& wksTarget, TreeNode& trPlotInfo, TreeNode& trSetting, int nCurCol, bool AddTags , int nPlotMode, bool bAddPickValue, bool bAddScrollbar, GraphPage& gp, bool bStickStimulus, bool bCtrlPanel, double dX0)
static bool _add_plot(Worksheet& wksTarget, TreeNode& trPlotInfo, TreeNode& trSetting, int nCurCol, bool AddTags , int nPlotMode, bool bAddPickValue, bool bAddScrollbar, GraphPage& gp, bool bStickStimulus, bool bCtrlPanel, double dX0, int nXCol = -1)
/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
//// END FIX_REIMPORT_PROBELM
/// END MORE_INFO_FOR_PLOT_CONTROL
{	
	//GraphPage gp; //justin 02/03/2007 OUTPUT_GRAPH
	GraphLayer gl;	
	int nSelChannels, nSelSweeps;
	if ( !_get_channel_sweep_number(trSetting, nSelChannels, nSelSweeps) )
	//// AW 05/18/07 MORE_ON_SELECT_CHANNEL
	//	return false;
	{
		if ( 0 == nSelChannels )
		{
			/// Hong 06/29/07 v8.0652 SHOULD_REMOVE_ALL_GRAPHOBJECT_IN_PAGE_IF_NO_DATA_SELECTED
			//gl = gp.Layers(0);
			foreach ( gl in gp.Layers )
			{
			/// end SHOULD_REMOVE_ALL_GRAPHOBJECT_IN_PAGE_IF_NO_DATA_SELECTED
				if ( gl )
				{
					int nPlots = gl.DataPlots.Count();
					BOOL bOK = false;
			   		for(int ii = 0; ii < nPlots; ii++)
			   			bOK = gl.RemovePlot(0);
			}
			}
		}
		return false;
	}
	//// END MORE_ON_SELECT_CHANNEL
	/// Hong 03/16/07 FIX_ERROR_LAYER_NAME_WHEN_DO_PARTIAL_PLOT
	int nImpChannels, nImpSweeps;
	if ( !_get_channel_sweep_number(trPlotInfo.trSetting, nImpChannels, nImpSweeps) )
		return false;	
	/// end FIX_ERROR_LAYER_NAME_WHEN_DO_PARTIAL_PLOT
	string strName;
	wksTarget.GetName(strName);
	_prepare_graph_page(gp, "pclamp", strName, bAddPickValue);
	/// Hong 03/16/07 MORE_OPTION_TO_ALLOW_SPECIAL_PLOT_GRAPH
	//_prepare_layers(gp, wksTarget, nCurCol, nSelChannels, nSelSweeps);
	int nNumSweep = trPlotInfo.SweepNum.nVal;
	int nPlotLayers = nSelChannels;	
	int nWavLayer = trPlotInfo.WavStimulu.nVal / nImpSweeps; 
	// Fisher 4/29/2008 QA80-10360	STIMULUS_WAVEFORM_PLOT_INCOMPLETE
	//int nLayers = nWavLayer +  trPlotInfo.DigStimulu.nVal / nNumSweep;	
	int nLayers = nWavLayer +  trPlotInfo.DigStimulu.nVal;
	// END STIMULUS_WAVEFORM_PLOT_INCOMPLETE
	
	if ( bStickStimulus ) ///---Sim 03-16-2007 ADD_STICK_STIMULUS_OPTION_ON_XF_GUI
		nPlotLayers += nWavLayer;
	
	_prepare_layers(gp, wksTarget, nCurCol, nPlotLayers, nImpSweeps); // Hong 03/16/07 FIX_ERROR_LAYER_NAME_WHEN_DO_PARTIAL_PLOT
	if ( bStickStimulus ) ///---Sim 03-16-2007 ADD_STICK_STIMULUS_OPTION_ON_XF_GUI
	{
		int nIndexCol = nCurCol + nSelChannels * nSelSweeps + trPlotInfo.WavStimulu.nVal;
		int nHeightChangeLayer = nSelChannels + nWavLayer - 1;
		_prepare_digit_stimulur_layers(gp, wksTarget, nIndexCol, nLayers + nSelChannels, nWavLayer + nSelChannels, nNumSweep, nHeightChangeLayer);
	}
	/// end MORE_OPTION_TO_ALLOW_SPECIAL_PLOT_GRAPH
	
	int nChIndex = 0;
	StringArray saStrUnits;	
	/// Hong 05/16/07 SPEED_UP_BY_SAVE_MORE_INFO
	///// Hong 05/15/07 MORE_RELIABLE_TIME_WHEN_PLOT
	//bool bCaculX0 = true;
	//double dX0 = 0.0;
	///// END MORE_RELIABLE_TIME_WHEN_PLOT
	
	//// AW 05/17/07 FIX_REIMPORT_PROBELM
	//dX0 = trPlotInfo.XOffset.dVal;
	//// END FIX_REIMPORT_PROBELM
	
	/// end SPEED_UP_BY_SAVE_MORE_INFO
	/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
	bool		bHasXCol = (-1 != nXCol ? true : false);
	/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
	foreach( TreeNode trChannel in trSetting.Channels.Children )
	{
		if ( 1 == trChannel.nVal )
		{
			string strUnits = wksTarget.Columns(nCurCol).GetUnits();
			saStrUnits.Add(strUnits);
			
			DataRange dr;
			/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
			if ( bHasXCol )
				dr.Add(wksTarget, nXCol, "X");
			/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
			foreach( TreeNode trSweep in trSetting.Sweeps.Children )
			{
				if ( 1 == trSweep.nVal )
				{
					dr.Add(wksTarget, nCurCol++, "Y");
					/// Hong 05/16/07 SPEED_UP_BY_SAVE_MORE_INFO
					/*
					/// Hong 05/15/07 MORE_RELIABLE_TIME_WHEN_PLOT
					if ( bCaculX0 )
					{
						double dTempX = 0, dTempInc = 0;
						Column col(wksTarget, nCurCol - 1);		
		   				col.IsEvenSampling(&dTempX, &dTempInc);
		   				
						trSweep.GetAttribute("PLCAMP_StartTime", dX0);		
						dX0 = dTempX - dX0;
						bCaculX0 = false;
					}
					/// end MORE_RELIABLE_TIME_WHEN_PLOT
					*/
					/// end SPEED_UP_BY_SAVE_MORE_INFO
				}
				/// Hong 05/10/07 v8.0614 GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE
				else if ( _is_tree_node_not_hidden(trSweep) ) // if not hidden
				/// END GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE
					nCurCol++;
			}
			gl = gp.Layers(nChIndex);
			
			int nPlot = gl.AddPlot(dr, IDM_PLOT_LINE, 0);//GAP_USE_X_FROM_SY);
			if(nPlot < 0)
				return false;
		//	return true;
			/// Hong 02/12/07 START_TIME_ALREADY_IN_SAMPLING_INTERVAL
			//vector dvStartTime;
			//dvStartTime = trPlotInfo.StartTime.dVals;
			/// end START_TIME_ALREADY_IN_SAMPLING_INTERVAL	
			/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
			if ( !bHasXCol )
			{
			/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
				switch(nPlotMode)
				{
				case mode_sweeps:
					for(int ii=0; ii < nSelSweeps; ii++)
				   	{    
				       	DataPlot dp = gl.DataPlots(ii);
				       	/// Hong 05/15/07 MORE_RELIABLE_TIME_WHEN_PLOT
				       	//dp.x0 = 0;
				       	dp.x0 = dX0;
				       	/// END MORE_RELIABLE_TIME_WHEN_PLOT
				   	}
				   	gl.Rescale();
					break;
				case mode_continuous:   
					break;
				case mode_concatenated:
					axis_label_set_show(gl, AXIS_BOTTOM, false); // Hong 02/03/07 REMOVE_X_LABEL_AS_NOT_VALID_VALUE
					/// Hong 05/15/07 MORE_RELIABLE_TIME_WHEN_PLOT
					//double x2Last = 0;
					double x2Last = dX0;
					/// END MORE_RELIABLE_TIME_WHEN_PLOT
					for(int ii=0; ii < nSelSweeps; ii++)
				   	{    
				       	DataPlot dp = gl.DataPlots(ii);
				       	int nPts = dp.i2;
				       	/// Hong 02/12/07 START_TIME_ALREADY_IN_SAMPLING_INTERVAL
				       	//if(0 == ii)
				           	//dp.x0 = dvStartTime[0];
				       	//else
				           	//dp.x0 = x2Last; // connect to last data plot
				     	dp.x0 = x2Last; // connect to last data plot
				       	/// end START_TIME_ALREADY_IN_SAMPLING_INTERVAL
				       
				       	double xEnd = dp.x0 + dp.i2* dp.xInc;
				       	x2Last = xEnd;
				   	}		
					break;
				}
			/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
			}
			/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
			
			_set_color_to_grapglayer(gl); 
			gl.Rescale();
			
			nChIndex++;
		}
		/// Hong 05/10/07 v8.0614 GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE
		else if ( _is_tree_node_not_hidden(trChannel) ) // if not hidden
		/// END GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE
			/// Hong 05/11/07 v8.0616 FIX_ERROR_INDEX_FOR_EPISODE_SELECT
			//nCurCol += nSelSweeps;
			nCurCol += nImpSweeps;
			/// END FIX_ERROR_INDEX_FOR_EPISODE_SELECT
	}

	GraphLayer gl2 = gp.Layers(0);

	if(AddTags)
	{
		vector<int> vnIndex;
		_check_tag_sweep_in_selected(trPlotInfo.FileTags, trSetting.Sweeps, vnIndex);
		
		int nIndex = 0;
		foreach(TreeNode trTag in trPlotInfo.FileTags.Children)
		{
			GraphObject grLine;
			GraphObject grText;
			string strTag;
			int nTime;
			
			nIndex++;
			if( -1 == vnIndex[nIndex - 1] )
					continue;

			DataPlot dp = gl.DataPlots(vnIndex[nIndex - 1]);
			/// Hong 04/23/09 QA80-13222-P7 FIX_TAG_TIME_IS_WRONG_WHEN_CHECK_HOLDING_DURATION
			/* Hong, rollback to old logic, as we make have correct the value of Offset
			/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
			//nTime = dp.x0 + trTag.OffSet.nVal;
			nTime = trTag.OffSet.nVal;
			if ( !bHasXCol )
				nTime += dp.x0;
			/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
			*/
			nTime = (int)dp.x0 + trTag.OffSet.nVal;
			/// end FIX_TAG_TIME_IS_WRONG_WHEN_CHECK_HOLDING_DURATION
			
			strTag.Format("Tag%lu sw:%d\n%ldms\n%s", nIndex, trTag.SweepNum.nVal, nTime, trTag.Comment.strVal);
			add_x_tag(gl2, grLine, grText, nTime, strTag);
			/// Hong 05/10/07 v8.0614 SPECIFY_OBJECT_NAME_FOR_PLOT_CONTROL
			grLine.SetName("pclamp_tag_line_" + nIndex);
			grText.SetName("pclamp_tag_text_" + nIndex);
			/// END SPECIFY_OBJECT_NAME_FOR_PLOT_CONTROL
			/// Hong 03/29/07 v8.0592 RESTRICT_MOVE_OF_TAG
			disable_go_move(grLine);
			disable_go_move(grText, true, false);
			/// end RESTRICT_MOVE_OF_TAG
			/// Hong 05/14/07 v8.0617 ALLOW_TAG_TO_DYNAMIC_UPDATE
			/* no need now, as it can be dynamic update in plot control
			/// Hong 05/11/07 v8.0616 MORE_INFO_FOR_PLOT_CONTROL
			if ( bCtrlPanel ) // when Control Panel is attach to Page, Tags should not be deletable by hand
			{
				set_go_user_deleteable(grLine, false);
				set_go_user_deleteable(grText, false);
			}
			*/
			/// END MORE_INFO_FOR_PLOT_CONTROL
			/// END ALLOW_TAG_TO_DYNAMIC_UPDATE
		}
	}
	
	/// Hong 03/16/07 MORE_OPTION_TO_ALLOW_SPECIAL_PLOT_GRAPH	
	int nResize = nSelChannels;
	if ( bStickStimulus ) ///---Sim 03-16-2007 ADD_STICK_STIMULUS_OPTION_ON_XF_GUI
	{
		int nStimulur = trPlotInfo.WavStimulu.nVal + trPlotInfo.DigStimulu.nVal; 
	
		if( 0 == nStimulur )
				return false;
		/// Hong 03/31/07 v8.0593 TURN_ON_PLOT_MODE
		//if( !_do_stimulur_plot(wksTarget, gp, trSetting, saStrUnits, nCurCol, nNumSweep, nSelSweeps, nWavLayer, nLayers, nSelChannels) )
		/// Hong 05/16/07 SPEED_UP_BY_SAVE_MORE_INFO
		//if( !_do_stimulur_plot(wksTarget, gp, trSetting, saStrUnits, nCurCol, nNumSweep, nSelSweeps, nWavLayer, nLayers, nSelChannels, nPlotMode) )
		/// Hong 05/18/07 MORE_FOR_FIX_REIMPORT_PROBELM
		//if( !_do_stimulur_plot(wksTarget, gp, trPlotInfo, trSetting, saStrUnits, nCurCol, nNumSweep, nSelSweeps, nWavLayer, nLayers, nSelChannels, nPlotMode) )
		/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
		//if( !_do_stimulur_plot(wksTarget, gp, trPlotInfo, trSetting, saStrUnits, nCurCol, nNumSweep, nSelSweeps, nWavLayer, nLayers, nSelChannels, nPlotMode, dX0) )
		if( !_do_stimulur_plot(wksTarget, gp, trPlotInfo, trSetting, saStrUnits, nCurCol, nNumSweep, nSelSweeps, nWavLayer, nLayers, nSelChannels, nPlotMode, dX0, nXCol) )
		/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
		/// end MORE_FOR_FIX_REIMPORT_PROBELM
		/// end SPEED_UP_BY_SAVE_MORE_INFO
		/// end TURN_ON_PLOT_MODE
			return false;
		nResize += nWavLayer;
	}
	/// end MORE_OPTION_TO_ALLOW_SPECIAL_PLOT_GRAPH
	/// Hong 03/19/07 FIX_STIMULUR_DISAPPEAR_IN_ONE_BASELAYER_CASE
	//_arrange_link_layers_and_add_scaler(gp, nSelChannels, saStrUnits, 0, nResize);	
	_arrange_link_layers_and_add_scaler(gp, nResize, saStrUnits, 0, nResize);	
	/// end FIX_STIMULUR_DISAPPEAR_IN_ONE_BASELAYER_CASE
	
	page_set_active_layer(gp, 0); // set first graphlayer to active layer before add axis_scrollbar
	
	/// Hong 01/12/07 ADD_SCROLLBAR_TO_PLOT
	if( bAddScrollbar )
	{
		double dXBegin = gl2.X.From;
		double dXEnd = gl2.X.To;
		XFBase xf("axis_scrollbar");	
		/// Hong 03/26/07 QA80-9457 v8.0589b IMPROVE_AXIS_SCROOLBAR
		//xf.SetArg("begin", dXBegin);
		//xf.SetArg("end", dXEnd);
		//xf.Evaluate();
		if( !xf )
			return false;
		
		int nErr;
		xf.ExecuteLabTalk(NULL, NULL, NULL, 0, &nErr, 0);
		/// end IMPROVE_AXIS_SCROOLBAR
	}
	/// end ADD_SCROLLBAR_TO_PLOT
	return true;
}

/// Hong 03/16/07 MORE_OPTION_TO_ALLOW_SPECIAL_PLOT_GRAPH
static bool _prepare_digit_stimulur_layers(GraphPage& gp, Worksheet& iw, int nStartCol, int nPlotLyNum, int nBaseLy, int nSweepNum, int nHeightChangeLayer)
{
	int nNumCols = iw.GetNumCols();
	int nIndexCol = nStartCol;
	GraphLayer gl;
	
	for( int ii = nBaseLy; ii < nPlotLyNum; ii++ )
	{		
		string strName = "";
		
		if(nIndexCol < nNumCols)
			strName = iw.Columns(nIndexCol).GetComments();
		
		if( 1 == ii )
		{
			gl = gp.Layers(1);
			layer_set_height(gl, 50.0);
			layer_set_position(gl, 0, -50);
			//nHeightChangeLayer -= 1; // Hong 01/05//06 FIX_ERROR_START_POSITION_FOR_SECOND_HEIGHT
		}
		else
			add_x_link_layer(gp, gl, 1, 0, nHeightChangeLayer);

		if( gl )
			gl.SetName(strName);	
		
		// Fisher 4/29/2008 QA80-10360	STIMULUS_WAVEFORM_PLOT_INCOMPLETE
		//nIndexCol += nSweepNum;
		++nIndexCol;
		// END STIMULUS_WAVEFORM_PLOT_INCOMPLETE
	}
	return true;
}

/// Hong 03/31/07 v8.0593 TURN_ON_PLOT_MODE
//static bool _do_stimulur_plot(Worksheet& iw, GraphPage& gp, TreeNode& trSetting, vector<string>& saStrUnits, int nCurCol, int nSweepNum, int nSelSweeps, int nWavLayer, int nPlotLyNum, int nBaseLy = 0)
/// Hong 05/16/07 SPEED_UP_BY_SAVE_MORE_INFO
//static bool _do_stimulur_plot(Worksheet& iw, GraphPage& gp, TreeNode& trSetting, vector<string>& saStrUnits, int nCurCol, int nSweepNum, int nSelSweeps, int nWavLayer, int nPlotLyNum, int nBaseLy = 0, int nPlotMode = PLOT_MODE_SWEEPS)
/// Hong 05/18/07 MORE_FOR_FIX_REIMPORT_PROBELM
//static bool _do_stimulur_plot(Worksheet& iw, GraphPage& gp, TreeNode& trPlotInfo, TreeNode& trSetting, vector<string>& saStrUnits, int nCurCol, int nSweepNum, int nSelSweeps, int nWavLayer, int nPlotLyNum, int nBaseLy = 0, int nPlotMode = PLOT_MODE_SWEEPS)
/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
//static bool _do_stimulur_plot(Worksheet& iw, GraphPage& gp, TreeNode& trPlotInfo, TreeNode& trSetting, vector<string>& saStrUnits, int nCurCol, int nSweepNum, int nSelSweeps, int nWavLayer, int nPlotLyNum, int nBaseLy = 0, int nPlotMode = mode_sweeps, double dX0 = 0.0)
static bool _do_stimulur_plot(Worksheet& iw, GraphPage& gp, TreeNode& trPlotInfo, TreeNode& trSetting, vector<string>& saStrUnits, int nCurCol, int nSweepNum, int nSelSweeps, int nWavLayer, int nPlotLyNum, int nBaseLy = 0, int nPlotMode = mode_sweeps, double dX0 = 0.0, int nXCol = -1)
/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
/// end MORE_FOR_FIX_REIMPORT_PROBELM
/// end SPEED_UP_BY_SAVE_MORE_INFO
/// end TURN_ON_PLOT_MODE
{
	GraphLayer gl;
	/// Hong 05/16/07 SPEED_UP_BY_SAVE_MORE_INFO
	///// Hong 05/15/07 MORE_RELIABLE_TIME_WHEN_PLOT
	//bool bCaculX0 = true;
	//double dX0 = 0.0;
	///// END MORE_RELIABLE_TIME_WHEN_PLOT
	//double dX0 = trPlotInfo.XOffset.dVal;
	/// end SPEED_UP_BY_SAVE_MORE_INFO
	int nNumCols = iw.GetNumCols();
	/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
	bool		bHasXCol = (-1 != nXCol ? true : false);
	/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
	for(int nIndexLy=nBaseLy; nIndexLy < nBaseLy + nWavLayer; nIndexLy++)
	{
		if( nCurCol > nNumCols ) // error check
			return false;
		
		string strUnits = iw.Columns(nCurCol).GetUnits();
			saStrUnits.Add(strUnits);
			
		DataRange dr;
		/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
		if ( bHasXCol )
			dr.Add(iw, nXCol, "X");
		/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
		gl = gp.Layers(nIndexLy); 
		
		foreach( TreeNode trSweep in trSetting.Sweeps.Children )
		{
			if ( 1 == trSweep.nVal )
			{
				dr.Add(iw, nCurCol++, "Y");
				/// Hong 05/16/07 SPEED_UP_BY_SAVE_MORE_INFO
				/*
				/// Hong 05/15/07 MORE_RELIABLE_TIME_WHEN_PLOT
				if ( bCaculX0 )
				{
					double dTempX = 0, dTempInc = 0;
					Column col(iw, nCurCol - 1);		
	   				col.IsEvenSampling(&dTempX, &dTempInc);
	   				
					trSweep.GetAttribute("PLCAMP_StartTime", dX0);		
					dX0 = dTempX - dX0;
					bCaculX0 = false;
				}
				/// end MORE_RELIABLE_TIME_WHEN_PLOT
				*/
				/// end SPEED_UP_BY_SAVE_MORE_INFO
			}
			/// Hong 05/10/07 v8.0614 GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE
			else if ( _is_tree_node_not_hidden(trSweep) ) // if not hidden
			/// END GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE
				nCurCol++;
		}
			
		int nPlot = gl.AddPlot(dr, IDM_PLOT_LINE, GAP_USE_X_FROM_SY);
			
		if(nPlot < 0)
			return false; // error plot
		
		/// Hong 03/31/07 v8.0593 TURN_ON_PLOT_MODE
		/*
		for(int mm=0; mm < nSelSweeps; mm++)
		{
			DataPlot dp = gl.DataPlots(mm);
			dp.x0 = 0;
		}
		*/
		/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
		if ( !bHasXCol ) // if have X col, should NOT change x0 and xInc
		{
		/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
			switch(nPlotMode)
			{
			case mode_sweeps:
				for(int ii=0; ii < nSelSweeps; ii++)
			   	{    
			       	DataPlot dp = gl.DataPlots(ii);
			       	/// Hong 05/15/07 MORE_RELIABLE_TIME_WHEN_PLOT
			       	//dp.x0 = 0;
			       	dp.x0 = dX0;
			       	/// END MORE_RELIABLE_TIME_WHEN_PLOT
			   	}
			   	gl.Rescale();
				break;
			case mode_continuous:   
				break;
			case mode_concatenated:
				axis_label_set_show(gl, AXIS_BOTTOM, false); // Hong 02/03/07 REMOVE_X_LABEL_AS_NOT_VALID_VALUE
				/// Hong 05/15/07 MORE_RELIABLE_TIME_WHEN_PLOT
				//double x2Last = 0;
				double x2Last = dX0;
				/// END MORE_RELIABLE_TIME_WHEN_PLOT
				for(int ii=0; ii < nSelSweeps; ii++)
			   	{    
			       	DataPlot dp = gl.DataPlots(ii);
			       	int nPts = dp.i2;
			       	/// Hong 02/12/07 START_TIME_ALREADY_IN_SAMPLING_INTERVAL
			       	//if(0 == ii)
			           	//dp.x0 = dvStartTime[0];
			       	//else
			           	//dp.x0 = x2Last; // connect to last data plot
			     	dp.x0 = x2Last; // connect to last data plot
			       	/// end START_TIME_ALREADY_IN_SAMPLING_INTERVAL
			       
			       	double xEnd = dp.x0 + dp.i2* dp.xInc;
			       	x2Last = xEnd;
			   	}		
				break;
			}
		/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
		}
		/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
		/// end TURN_ON_PLOT_MODE
		
		_set_color_to_grapglayer(gl); 
		gl.Rescale();
	}
	for(int nn= nBaseLy + nWavLayer; nn < nBaseLy + nPlotLyNum; nn++)
	{
		string strUnits = iw.Columns(nCurCol).GetUnits();
			saStrUnits.Add(strUnits);
			
		DataRange dr;
		/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
		if ( bHasXCol )
			dr.Add(iw, nXCol, "X");
		/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
		gl = gp.Layers(nn);
		
		/// Hong 05/18/07 v8.0621 REMOVE_DUPLICATE_DIGITAL_WAVEFORM
		// all the Episode share the same Digital waveform data
		//for(int mm=0; mm < nSweepNum; mm++)
		/// end REMOVE_DUPLICATE_DIGITAL_WAVEFORM
			dr.Add(iw, nCurCol++, "Y");
			
		int nPlot = gl.AddPlot(dr, IDM_PLOT_LINE, GAP_USE_X_FROM_SY);
			
		if(nPlot < 0)
			return false; // error plot

		/// Hong 05/18/07 v8.0621 REMOVE_DUPLICATE_DIGITAL_WAVEFORM
		//for(mm=0; mm < nSweepNum; mm++)
		/// end REMOVE_DUPLICATE_DIGITAL_WAVEFORM
		{
			DataPlot dp = gl.DataPlots(0);
			dp.x0 = 0;
		}
		
		_set_color_to_grapglayer(gl); 
		gl.Rescale();
	}
	
	return true;
}
/// end MORE_OPTION_TO_ALLOW_SPECIAL_PLOT_GRAPH

//static bool _add_stimulur(Worksheet& iw, TreeNode& trPlotInfo, int nCurCol, bool bAddPickValue)
//static bool _add_stimulur(Worksheet& iw, TreeNode& trPlotInfo, int nCurCol, bool bAddPickValue, bool bAddScrollbar)
//static bool _add_stimulur(Worksheet& iw, TreeNode& trPlotInfo, int nCurCol, bool bAddPickValue, bool bAddScrollbar, GraphPage& waveform) // Justin 02/03/07 OUTPUT_GRAPH
/// Hong 03/31/07 v8.0593 TURN_ON_PLOT_MODE
//static bool _add_stimulur(Worksheet& iw, TreeNode& trPlotInfo, TreeNode& trSetting, int nCurCol, bool bAddPickValue, bool bAddScrollbar, GraphPage& waveform) // Hong 02/08/07 ADD_DATA_SELECTION_SUPPORT
/// Hong 05/18/07 MORE_FOR_FIX_REIMPORT_PROBELM
//static bool _add_stimulur(Worksheet& iw, TreeNode& trPlotInfo, TreeNode& trSetting, int nCurCol, bool bAddPickValue, bool bAddScrollbar, GraphPage& waveform, int nPlotMode)
/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
//static bool _add_stimulur(Worksheet& iw, TreeNode& trPlotInfo, TreeNode& trSetting, int nCurCol, bool bAddPickValue, bool bAddScrollbar, GraphPage& waveform, int nPlotMode, double dXOffset)
static bool _add_stimulur(Worksheet& iw, TreeNode& trPlotInfo, TreeNode& trSetting, int nCurCol, bool bAddPickValue, bool bAddScrollbar, GraphPage& waveform, int nPlotMode, double dXOffset, int nXCol = -1)
/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
/// end MORE_FOR_FIX_REIMPORT_PROBELM
/// end TURN_ON_PLOT_MODE
{	
	/// Hong 02/08/07 ADD_DATA_SELECTION_SUPPORT
	//int nStimulur = trPlotInfo.WavStimulu.nVal + trPlotInfo.DigStimulu.nVal;
	int nSelChannels, nSelSweeps;
	if ( !_get_channel_sweep_number(trSetting, nSelChannels, nSelSweeps) )
		return false;
	
	//int nStimulur = nSelSweeps + trPlotInfo.DigStimulu.nVal;
	int nStimulur = trPlotInfo.WavStimulu.nVal + trPlotInfo.DigStimulu.nVal; // Hong 02/15/07 FIX_STIMULU_HAVE_OWN_CHANNEL_INDEX
	/// end ADD_DATA_SELECTION_SUPPORT
	/// Hong 02/15/07 FIX_STIMULU_HAVE_OWN_CHANNEL_INDEX
	int nImpChannels, nImpSweeps;
	if ( !_get_channel_sweep_number(trPlotInfo.trSetting, nImpChannels, nImpSweeps) )
		return false;
	/// end FIX_STIMULU_HAVE_OWN_CHANNEL_INDEX
	if( 0 == nStimulur )
		return false;
	
	GraphPage gp;
	// Justin 02/03/07 OUTPUT_GRAPH
	if(waveform != NULL)
		gp = waveform;
	///end 
	GraphLayer gl;
	string strName;
	strName = iw.GetName();
	_prepare_graph_page(gp, "stimulus", strName, bAddPickValue);
	
	int nSweepNum = trPlotInfo.SweepNum.nVal;
	/// Hong 12/26/06 QA80-8662 ADD_SECOND_HEIGHT_FOR_LINK_LAYER
	//int nLayers = nStimulur / nSweepNum;
	//_prepare_layers(gp, iw, nCurCol, nLayers, nSweepNum);
	/// Hong 02/08/07 ADD_DATA_SELECTION_SUPPORT
	//int nWavLayer = trPlotInfo.WavStimulu.nVal / nSweepNum;
	//int nLayers = nStimulur / nSweepNum;
	//int nWavLayer = nSelChannels;
	int nWavLayer = trPlotInfo.WavStimulu.nVal / nImpSweeps; // Hong 02/15/07 FIX_STIMULU_HAVE_OWN_CHANNEL_INDEX
	int nLayers = nWavLayer +  trPlotInfo.DigStimulu.nVal / nSweepNum;
	/// end ADD_DATA_SELECTION_SUPPORT
	//_prepare_layers(gp, iw, nCurCol, nWavLayer, nSweepNum);
	_prepare_layers(gp, iw, nCurCol, nWavLayer, nImpSweeps); // Hong 02/15/07 FIX_STIMULU_HAVE_OWN_CHANNEL_INDEX
	int nIndexCol = nCurCol + trPlotInfo.WavStimulu.nVal;
	//int nHeightChangeLayer = nWavLayer;
	int nHeightChangeLayer = nWavLayer - 1; // Hong 01/05//06 FIX_ERROR_START_POSITION_FOR_SECOND_HEIGHT
	/// Hong 03/16/07 MORE_OPTION_TO_ALLOW_SPECIAL_PLOT_GRAPH
	/*
	for( int ii = nWavLayer; ii < nLayers; ii++ )
	{
		string strName;
		strName = iw.Columns(nIndexCol).GetComments();
		bool bRescaleTemplateLayer = false;
		if( 1 == ii )
		{
			gl = gp.Layers(1);
			layer_set_height(gl, 50.0);
			layer_set_position(gl, 0, -50);
			//nHeightChangeLayer -= 1; // Hong 01/05//06 FIX_ERROR_START_POSITION_FOR_SECOND_HEIGHT
		}
		else
			add_x_link_layer(gp, gl, 1, 0, nHeightChangeLayer);

		if( gl )
			gl.SetName(strName);	
			
		nIndexCol += nSweepNum;
	}
	*/
	_prepare_digit_stimulur_layers(gp, iw, nIndexCol, nLayers, nWavLayer, nSweepNum, nHeightChangeLayer);
	/// end MORE_OPTION_TO_ALLOW_SPECIAL_PLOT_GRAPH
	/// end ADD_SECOND_HEIGHT_FOR_LINK_LAYER
	StringArray saStrUnits;
	/// Hong 03/16/07 MORE_OPTION_TO_ALLOW_SPECIAL_PLOT_GRAPH
	/*
	/// Hong 02/08/07 ADD_DATA_SELECTION_SUPPORT
	//for(int nn=0; nn < nLayers; nn++)
	/// Hong 02/15/07 FIX_STIMULU_HAVE_OWN_CHANNEL_INDEX
	*/
	/*
	int nIndexLy = 0;
	foreach( TreeNode trChannel in trSetting.Channels.Children )
	{
		if ( 1 == trChannel.nVal )
		{
	*/
	/*
	for(int nIndexLy=0; nIndexLy < nWavLayer; nIndexLy++)
	/// end FIX_STIMULU_HAVE_OWN_CHANNEL_INDEX
	{
			string strUnits = iw.Columns(nCurCol).GetUnits();
				saStrUnits.Add(strUnits);
				
			DataRange dr;
			//gl = gp.Layers(nIndexLy++);
			gl = gp.Layers(nIndexLy); // Hong 02/15/07 FIX_STIMULU_HAVE_OWN_CHANNEL_INDEX
			
			foreach( TreeNode trSweep in trSetting.Sweeps.Children )
			{
				if ( 1 == trSweep.nVal )
					dr.Add(iw, nCurCol++, "Y");
				else
					nCurCol++;
			}
				
			int nPlot = gl.AddPlot(dr, IDM_PLOT_LINE, GAP_USE_X_FROM_SY);
				
			if(nPlot < 0)
				return false; // error plot
				       	
			for(int mm=0; mm < nSelSweeps; mm++)
			{
				DataPlot dp = gl.DataPlots(mm);
				dp.x0 = 0;
			}
			
			_set_color_to_grapglayer(gl); 
			gl.Rescale();
		//}// Hong 02/15/07 FIX_STIMULU_HAVE_OWN_CHANNEL_INDEX
	}
	for(int nn=nWavLayer; nn < nLayers; nn++)
	/// end ADD_DATA_SELECTION_SUPPORT
	{
		string strUnits = iw.Columns(nCurCol).GetUnits();
			saStrUnits.Add(strUnits);
			
		DataRange dr;
		gl = gp.Layers(nn);
		for(int mm=0; mm < nSweepNum; mm++)
			dr.Add(iw, nCurCol++, "Y");
			
		int nPlot = gl.AddPlot(dr, IDM_PLOT_LINE, GAP_USE_X_FROM_SY);
			
		if(nPlot < 0)
			return false; // error plot
			       	
		for(mm=0; mm < nSweepNum; mm++)
		{
			DataPlot dp = gl.DataPlots(mm);
			dp.x0 = 0;
		}
		
		_set_color_to_grapglayer(gl); 
		gl.Rescale();
	}
	*/
	/// Hong 03/31/07 v8.0593 TURN_ON_PLOT_MODE
	//if( !_do_stimulur_plot(iw, gp, trSetting, saStrUnits, nCurCol, nSweepNum, nSelSweeps, nWavLayer, nLayers) )
	/// Hong 05/16/07 SPEED_UP_BY_SAVE_MORE_INFO
	//if( !_do_stimulur_plot(iw, gp, trSetting, saStrUnits, nCurCol, nSweepNum, nSelSweeps, nWavLayer, nLayers, 0, nPlotMode) )
	/// Hong 05/18/07 MORE_FOR_FIX_REIMPORT_PROBELM
	/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
	//if( !_do_stimulur_plot(iw, gp, trPlotInfo, trSetting, saStrUnits, nCurCol, nSweepNum, nSelSweeps, nWavLayer, nLayers, 0, nPlotMode, dXOffset) )
	if( !_do_stimulur_plot(iw, gp, trPlotInfo, trSetting, saStrUnits, nCurCol, nSweepNum, nSelSweeps, nWavLayer, nLayers, 0, nPlotMode, dXOffset, nXCol) )
	/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
	/// end MORE_FOR_FIX_REIMPORT_PROBELM
	/// end SPEED_UP_BY_SAVE_MORE_INFO
	/// end TURN_ON_PLOT_MODE
		return false;
	/// end MORE_OPTION_TO_ALLOW_SPECIAL_PLOT_GRAPH
	
	_arrange_link_layers_and_add_scaler(gp, nLayers, saStrUnits, 0, nWavLayer);
	
	/// Hong 01/12/07 ADD_SCROLLBAR_TO_PLOT
	page_set_active_layer(gp, 0); // set first graphlayer to active layer before add axis_scrollbar
	
	GraphLayer gl2 = gp.Layers();
	if( bAddScrollbar )
	{
		double dXBegin = gl2.X.From;
		double dXEnd = gl2.X.To;
		XFBase xf("axis_scrollbar");	
		/// Hong 03/26/07 QA80-9457 v8.0589b IMPROVE_AXIS_SCROOLBAR
		//xf.SetArg("begin", dXBegin);
		//xf.SetArg("end", dXEnd);
		//xf.Evaluate();
		if( !xf )
			return false;
		
		int nErr;
		xf.ExecuteLabTalk(NULL, NULL, NULL, 0, &nErr, 0);
		/// end IMPROVE_AXIS_SCROOLBAR
	}
	/// end ADD_SCROLLBAR_TO_PLOT
	/// Hong 12/26/06 QA80-8662 ADD_SECOND_HEIGHT_FOR_LINK_LAYER
	/// Hong 03/27/07 QA80-9457-P11 v8.0590 FIX_ERROR_RESCALE_ONE_LAYER_WAVEFORM
	//if(nWavLayer < 2)// no need rearrange template layer
		//nWavLayer = 2;
	/// end FIX_ERROR_RESCALE_ONE_LAYER_WAVEFORM
	/// end ADD_SECOND_HEIGHT_FOR_LINK_LAYER
	return true;
}


void plotpClamp(const Worksheet& iw, const int& findex, const int& tag, const int& stimulur, const int& septstim, const int& pickval, const int& scrollbar, const int& ctrl, const int& mode, const TreeNode& trsetting, GraphPage& plot, GraphPage& waveform)
{
	/// Hong 08/08/08 v8.0918b MORE_INVALID_CHECKING
	if ( !iw )
		XF_THROW(CER_INVALID_WKS);
	/// end MORE_INVALID_CHECKING
	Page pg;
	iw.GetParent(pg);
	Tree tr;
	if( !tree_get_binary_storage(tr, pg, IFI_BINARY_STORAGE_NAME) )
		XF_THROW(CER_INVALID_WKS);
	
	
	TreeNode trPlot;
	int nIndex = iw.GetIndex();
	int nFile = findex;
	int nStartCol, nEndCol;
	/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
	int	nXCol(-1);
	/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
	foreach(TreeNode tn in tr.Children)
	{
		TreeNode trRange = tree_get_node_by_tagname(tn, "DataRange", true);
		if(!trRange.IsValid())
			continue;
		
		/// Hong 03/09/07 SKIP_INVALID_RANGE
		if( tn.Info.CoveredByAnotherImport && (0 == tn.Info.CoveredByAnotherImport.strVal.CompareNoCase("Yes")) )
			continue;
		/// end SKIP_INVALID_RANGE
		Worksheet wksTemp;		
		DataRange dr;
		/// Hong 02/07/07 CREATE_DATARANGE_BY_UID
		//dr.Create(trRange);
		/// Hong 03/08/07 SUPPORT_RELATIVE_DATA_RANGE
		//UINT uid = trRange.RangeUID.nVal;
		//dr = (DataRange)Project.GetObject(uid);
		dr = get_and_check_range(trRange, pg.GetName());
		/// end SUPPORT_RELATIVE_DATA_RANGE
		/// end CREATE_DATARANGE_BY_UID
		///---Sim 02-06-2007 CHECK_DATA_RANGE_TREE
		if ( !dr.IsValid() && (0 == dr.GetNumData()) )
			continue;
		///---END CHECK_DATA_RANGE_TREE
		dr.GetRange(wksTemp, nStartCol, nEndCol);
		
		///-- skip time column if have when do plot
		Column col(wksTemp, nStartCol);
		if ( OKDATAOBJ_DESIGNATION_X == col.GetType() )
		{
			/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
			nXCol = nStartCol;
			/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
			nStartCol++;
		}
		///--
		
		if( nIndex == wksTemp.GetIndex() )
		{
			if(!nFile)
			{
				trPlot = tn.Import;
				tr = tn; /// Hong 05/05/07 QA80-9716 ADD_PLOT_CONTROL_XF_FOR_GRAPH_WINDOW
				break;
			}
			nFile--;
		}
	}
	/// Hong 05/18/07 v8.0621 MORE_VALID_INPUT_CHECKING
	if ( !trPlot )
		XF_THROW(CER_INVALID_WKS);
	/// end MORE_VALID_INPUT_CHECKING
	
	int nSelChannels, nSelSweeps;
	//justin 02/07/2007 
	if(trsetting.IsEmpty())
		_convert_trSetting(trsetting, trPlot.trSetting);
	//end 
	
	if ( !_get_channel_sweep_number(trPlot.trSetting, nSelChannels, nSelSweeps) )
	{
		/// Hong 08/20/09 QA80-13483 -P2 REMOVE_UNFRIENDLY_ERR_MSG_WHEN_REPLOT_FROM_PCLAMP_PLOT_CONTROL
		//XF_THROW(XFERR_NO_DATA_SELECT);
		if ( PLOT_CTRL_NO_UPDATE == ctrl )
			return ;
		else
			XF_THROW(XFERR_NO_DATA_SELECT);
		/// end REMOVE_UNFRIENDLY_ERR_MSG_WHEN_REPLOT_FROM_PCLAMP_PLOT_CONTROL
	}
	
	if(tag)
	{
		TreeNode trTagsNode = tree_get_node_by_tagname(tn, "FileTags", true);
		trPlot.AddNode(trTagsNode);
	}
	
	
	
	//if ( !_add_plot(iw, trPlot, trsetting, nStartCol, addtag, plotmode, addpickvalue) )
	//if ( !_add_plot(iw, trPlot, trsetting, nStartCol, addtag, plotmode, addpickvalue, addscrollbar) ) // Hong 01/12/07 ADD_SCROLLBAR_TO_PLOT
	//if ( !_add_plot(iw, trPlot, trsetting.FileSetting, nStartCol, addtag, plotmode, addpickvalue, addscrollbar, plot) ) // Justin 02/03/07 OUTPUT_GRAPH
	/// AW 05/08/07 MORE_ON_PCLAMP_PLOT
	//if ( !_add_plot(iw, trPlot, trsetting.FileSetting, nStartCol, addtag, plotmode, addpickvalue, addscrollbar, plot, (addstimulur && !septstim)) ) ///---Sim 03-16-2007 ADD_STICK_STIMULUS_OPTION_ON_XF_GUI
	/// Hong 05/11/07 v8.0616 MORE_INFO_FOR_PLOT_CONTROL
	/// AW 05/17/07 FIX_REIMPORT_PROBELM
	//if ( !_add_plot(iw, trPlot, trsetting, nStartCol, addtag, plotmode, addpickvalue, addscrollbar, plot, (addstimulur && !septstim), ctrl) )
	double dXOffset = 0;	
	/// Hong 06/04/07 v8.0623 USE_MACRO_FOR_MORE_FRIENDLY_NAME
	//TreeNode trSkipPointsOptions = trsetting.SkipPointsOptions;
	TreeNode trSkipPointsOptions = trsetting.GetNode(STR_FILTER_PARTIAL_NODE);;
	/// end USE_MACRO_FOR_MORE_FRIENDLY_NAME
	if ( trSkipPointsOptions )
	///---Sim 04-16-2009 QA80-13318 IMPROVE_HONG_FIX_REIMPORT_FAIL_GET_CORRECT_ROW_NUM
		//trSkipPointsOptions.GetAttribute(STR_PARTIAL_START_TIME, dXOffset);
	{
		if ( fuGetPartialImport(trSkipPointsOptions) )
			dXOffset = fuGetStartTime(trSkipPointsOptions);
	}
	///---END QA80-13318 IMPROVE_HONG_FIX_REIMPORT_FAIL_GET_CORRECT_ROW_NUM
	/// END FIX_REIMPORT_PROBELM
	/// Hong 01/15/09 FIX_PCLAMP_PLOT_FAIL_HANDLE_TIME_OFFSET_OF_HOLDING_DURATION	
	if ( trsetting.bHoldingDuration && 1 == trsetting.bHoldingDuration.nVal )
	{
		double		dHoldingDuration(0.0);
		trsetting.bHoldingDuration.GetAttribute(STR_HOLDING_DURATION, dHoldingDuration);
		dXOffset += dHoldingDuration;
	}
	/// end FIX_PCLAMP_PLOT_FAIL_HANDLE_TIME_OFFSET_OF_HOLDING_DURATION
	/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
	//if ( !_add_plot(iw, trPlot, trsetting, nStartCol, tag, mode, pickval, scrollbar, plot, (stimulur && !septstim), ctrl, dXOffset) )
	if ( !_add_plot(iw, trPlot, trsetting, nStartCol, tag, mode, pickval, scrollbar, plot, (stimulur && !septstim), ctrl, dXOffset, nXCol) )
	/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
	/// END MORE_INFO_FOR_PLOT_CONTROL
	/// END MORE_ON_PCLAMP_PLOT
	{
		/// Hong 08/20/09 QA80-13483 -P2 REMOVE_UNFRIENDLY_ERR_MSG_WHEN_REPLOT_FROM_PCLAMP_PLOT_CONTROL
		//	XF_THROW(XFERR_NO_DATA_SELECT);
		if ( PLOT_CTRL_NO_UPDATE == ctrl )
			/// Hong 02/26/10 QA80-10360-P16 FIX_LAST_EPISODE_UNCHECKED_FAIL_SAVE_WHEN_REOPEN_XF
			//return ;
			;
			/// end FIX_LAST_EPISODE_UNCHECKED_FAIL_SAVE_WHEN_REOPEN_XF
		else
			XF_THROW(XFERR_NO_DATA_SELECT);
		/// end REMOVE_UNFRIENDLY_ERR_MSG_WHEN_REPLOT_FROM_PCLAMP_PLOT_CONTROL
	}
	
	/// Hong 05/05/07 QA80-9716 ADD_PLOT_CONTROL_XF_FOR_GRAPH_WINDOW
	/// Hong 05/17/07 v8.0621 ALWAYS_SAVE_PLOT_CONTROL_INFO
	//if ( ctrl )
	//{
	/// end ALWAYS_SAVE_PLOT_CONTROL_INFO
		/// Hong 05/08/07 v8.0613 CORRECT_WAY_TO_ATTACH_XF_TO_PAGE
		/*
		XFBase xf("pclampplotcontrol");
		
		if ( xf )
		{
			xf.SetArg("fname", tr.Info.FilePath.strVal);
			xf.SetArg("addtag", addtag);
			xf.SetArg("addpickvalue", addpickvalue);
			xf.SetArg("addscrollbar", addscrollbar);
			xf.SetArg("plotmode", plotmode);
			xf.SetArg("trsetting", trsetting);
			
			Tree trJunk; // for memory of tree
			TreeNode trGetN;
			xf.GetGUI(trJunk, trGetN);
			if ( trGetN.trsetting && trGetN.trsetting.GetNodeCount() > 0 )
			{
				xf.SetArg("trsetting", trsetting);
			}
			else
			{
				trGetN.trsetting.Replace(trsetting, true, true); // need to check if there is a better way
				xf.SetGUI(trGetN);
			}
			
			int nErr;
			xf.ExecuteLabTalk(NULL, NULL, NULL, 0, &nErr, LTXF_SHOW_DIALOG | LTXF_XFBAR); // have bug, fail to attach to graph page
		}
		else
			XF_THROW(0); // need add error message into DLL by "Fail add plot control panel"
		
		*/
	Tree trCtrlInfo;
	trCtrlInfo.AddTextNode(tr.Info.FilePath.strVal, "fname");
	trCtrlInfo.AddNumericNode(tag, "addtag");
	trCtrlInfo.AddNumericNode(pickval, "addpickvalue");
	trCtrlInfo.AddNumericNode(scrollbar, "addscrollbar");
	trCtrlInfo.AddNumericNode(mode, "plotmode");
	// more info for target data
	/// Hong 08/08/08 QA80-10360 FIX_MULTI_PCLAMP_FAIL_REPLOT_IN_PLOT_CONTROL
	//trCtrlInfo.AddNumericNode(mode, "findex");
	trCtrlInfo.AddNumericNode(findex, "findex");
	/// end FIX_MULTI_PCLAMP_FAIL_REPLOT_IN_PLOT_CONTROL
	TreeNode trRange = tree_get_node_by_tagname(tr, "DataRange", true);
	trCtrlInfo.AddNode(trRange);
		
	int nStimulur = 0;
	if (stimulur && !septstim)
		nStimulur = 1;
	trCtrlInfo.AddNumericNode(nStimulur, "addstimulur"); // for reimport from graph, only when plot stilur in same graph page is supported
	
	TreeNode trNode = trCtrlInfo.AddNode("trsetting");
	trNode.Replace(trsetting, true, true, true);
	
	/// Hong 05/14/07 v8.0617 ALLOW_TAG_TO_DYNAMIC_UPDATE
	TreeNode trTagsNode = tree_get_node_by_tagname(tn, "FileTags", true);
	if ( trTagsNode )
		trCtrlInfo.AddNode(trTagsNode.Clone());
	/// END ALLOW_TAG_TO_DYNAMIC_UPDATE
	
	trCtrlInfo.AddNode(trPlot.Clone());/// Hong 05/10/07 v8.0614 GRAPH_REIMPORT_NEED_KEEP_TREE_STRUCTURE
	
	plot.PutBinaryStorage("pclamp_info", trCtrlInfo); // this binary storage is used for pclamp plot control XF cause by limite of XFBar
	/// Hong 05/21/07 ALWAYS_SAVE_PLOT_CONTROL_TO_PAGE
	/*
	/// Hong 05/17/07 v8.0621 ALWAYS_SAVE_PLOT_CONTROL_INFO
	if ( ctrl )
	{	
	/// end ALWAYS_SAVE_PLOT_CONTROL_INFO
		show_xf_bar(plot, SXFB_OPEN_INDEPENDENT, "pclampplotcontrol");
		/// end CORRECT_WAY_TO_ATTACH_XF_TO_PAGE
	}
	/// END ADD_PLOT_CONTROL_XF_FOR_GRAPH_WINDOW
	*/
	/// Hong 05/22/07 v8.0623 FIX_CRASH_CAUSE_BY_REATTACH_XFBAR
	if ( PLOT_CTRL_NO_UPDATE != ctrl )
	/// end FIX_CRASH_CAUSE_BY_REATTACH_XFBAR
		show_xf_bar(plot, SXFB_OPEN_INDEPENDENT, "pclampplotcontrol", ctrl ? false : true);
	/// end ALWAYS_SAVE_PLOT_CONTROL_TO_PAGE
	/// Hong 07/31/07 QA80-9709-P10 v8.0671 ALWAYS_ATTACH_PLOT_CONTROL_TO_PAGE
	string strPageXFName;
	if ( !get_page_xf_bar(plot, strPageXFName) || strPageXFName.IsEmpty() )
	{
		set_page_xf_bar(plot, "pclampplotcontrol", SXFB_OPEN_INDEPENDENT);
	}
	/// end ALWAYS_ATTACH_PLOT_CONTROL_TO_PAGE
	if ( stimulur && septstim ) ///---Sim 03-16-2007 ADD_STICK_STIMULUS_OPTION_ON_XF_GUI
	{
		int nStiCol = nStartCol + nSelChannels * nSelSweeps;
		//if( addstimulur )
		//{
			/// Hong 01/12/07 ADD_SCROLLBAR_TO_PLOT
			//if( !_add_stimulur(iw, trPlot, nStiCol, addpickvalue) )
			//if( !_add_stimulur(iw, trPlot, nStiCol, false) ) // no need add pick value line in stimulur page
			//if( !_add_stimulur(iw, trPlot, nStiCol, false, addscrollbar) )
			//if( !_add_stimulur(iw, trPlot, nStiCol, false, addscrollbar, waveform) ) // Justin 02/03/07 OUTPUT_GRAPH
			/// Hong 03/31/07 v8.0593 TURN_ON_PLOT_MODE
			//if( !_add_stimulur(iw, trPlot, trsetting.FileSetting, nStiCol, false, addscrollbar, waveform) ) // Hong 02/08/07 ADD_DATA_SELECTION_SUPPORT
			/// AW 05/08/07 MORE_ON_PCLAMP_PLOT
			//if( !_add_stimulur(iw, trPlot, trsetting.FileSetting, nStiCol, false, addscrollbar, waveform, plotmode) ) 
			/// Hong 05/18/07 MORE_FOR_FIX_REIMPORT_PROBELM
			/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
			//if( !_add_stimulur(iw, trPlot, trsetting, nStiCol, false, scrollbar, waveform, mode, dXOffset) ) 
			if( !_add_stimulur(iw, trPlot, trsetting, nStiCol, false, scrollbar, waveform, mode, dXOffset, nXCol) ) 
			/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
			/// end MORE_FOR_FIX_REIMPORT_PROBELM
			/// END MORE_ON_PCLAMP_PLOT
			/// end TURN_ON_PLOT_MODE
			/// end ADD_SCROLLBAR_TO_PLOT
				XF_THROW(XFERR_NO_DATA_SELECT);
		//}
	}
}

//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 plotpClamp_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return plotpClamp_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	if( 0 == lstrcmp(lpcszNodeName, "iw") )
	{
		if( !_list_imported_data_and_init_trSetting(trGetN) )
		{
			bOKEnable = false;
			strErrMsg = CER_INVALID_IMPORT_DATA_FILE; /// Hong 05/21/07 add error message 
		}
		
		return true;
	}
	
	Worksheet Wks = Project.ActiveLayer();
	if( 0 == lstrcmp(lpcszNodeName, "findex") )
	{
		if( !_update_trSetting(trGetN) )
			bOKEnable = false;
		
		return true;
	}
	///Joseph 01/28/07 CHANGE_XF_APPLY_BUTTON
	if(GETNE_ON_INIT == nEventID || GETNE_ON_THEME == nEventID) ///---Sim 03-16-2007 ADD_STICK_STIMULUS_OPTION_ON_XF_GUI
	{
		///---Sim 04-02-2007 CHANGE_CUSTOM_BUTTON_FORMAT
		//strAux = "Button:Plot";
		///---END CHANGE_CUSTOM_BUTTON_FORMAT
		
		///---Sim 03-16-2007 ADD_STICK_STIMULUS_OPTION_ON_XF_GUI
		//trGetN.stickstim.Show = trGetN.addstimulur.Show && trGetN.addstimulur.nVal;
		/// AW 05/14/07 MORE_ON_ADDSTIMULUR
		if ( !trGetN.stimulur.Show )
			trGetN.stimulur.nVal = 0;
		/// END MORE_ON_ADDSTIMULUR
		
		trGetN.septstim.Show = trGetN.stimulur.nVal;
		
		/// Hong 04/08/09 QA80-13222 ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
		if ( trGetN.trsetting.ShowTimeCol && 1 == trGetN.trsetting.ShowTimeCol.nVal )
		{
			trGetN.mode.nVal = mode_sweeps;
			trGetN.mode.Enable = ENABLE_READ_ONLY;
		}
		/// end ALLOW_PLOT_PCLAMP_EVEN_SHOW_TIME_COL
		
		/// Hong 05/21/07 MORE_ERROR_MESSAGE
		/// Hong 06/16/08 QA80-10360 FIX_PLOT_SELECTION_FAIL_UPDATE_AFTER_CHANGE_FILE_INDEX
		/*
		if( !_list_imported_data_and_init_trSetting(trGetN) )
		{
			bOKEnable = false;
			strErrMsg = CER_INVALID_IMPORT_DATA_FILE; /// Hong 05/21/07 add error message 
		}
		*/
		/// end FIX_PLOT_SELECTION_FAIL_UPDATE_AFTER_CHANGE_FILE_INDEX
		/// end MORE_ERROR_MESSAGE
	
		return true; 
		///---END ADD_STICK_STIMULUS_OPTION_ON_XF_GUI
	}	
	///End CHANGE_XF_APPLY_BUTTON
	///---Sim 03-16-2007 ADD_STICK_STIMULUS_OPTION_ON_XF_GUI
	if( 0 == lstrcmp(lpcszNodeName, "stimulur") )
	{
		//trGetN.stickstim.Show = trGetN.addstimulur.Show && trGetN.addstimulur.nVal;
		trGetN.septstim.Show = trGetN.stimulur.nVal;
		return true;
	}
	///---END ADD_STICK_STIMULUS_OPTION_ON_XF_GUI
	
	return false;

}

int plotpClamp_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 plotpClamp_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	///---Sim 04-28-2007 FIX_CALL_XF_FROM_OC
	/*
	/// Hong 04/23/07 v8.0606 FIX_SETTING_RESET_TO_DEFAULT
	// use 0 but not -1 because to XFbar will pass 0 when click "plot" button which i think it's a bug, so this can be temp fix
	if ( nGetNDialog > 0 ) 
	/// end FIX_SETTING_RESET_TO_DEFAULT
	*/
	
	
	if ( nGetNDialog >= 0 ) 
	///---END FIX_CALL_XF_FROM_OC
	{
		if ( !_list_imported_data_and_init_trSetting(trGetN) )
		{	
			nRet = XFEVT_ABORT;
			warning_msg_box(CER_INVALID_IMPORT_DATA_FILE, false); /// Hong 05/21/07 add error message 
			return ;
		}
		
		trGetN.trsetting.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);			///// AW 05/17/07 MORE_IN_PLOT_PCLAMP_GUI
	}
	//// 05/17/07 GET_RIGHT_ACTIVE_WKS_IN_MULTI_SHEETS
	else
	{
		Worksheet wksActive = Project.ActiveLayer();
		/// YuI 07/15/09 QA70-13230_P4 PCLAMP_FAILS_TO_PLOT_WITH_NUMERIC_WKS_NAME
		//	string	strName;
		//	Wks.GetName(strName);
		//	trGetN.iw.strVal = strName;
		if( wksActive )
		{
			string	strWksRange;
			wksActive.GetRangeString(strWksRange);
			trGetN.iw.strVal = strWksRange;
		}
		/// end PCLAMP_FAILS_TO_PLOT_WITH_NUMERIC_WKS_NAME		
	}
	/// END GET_RIGHT_ACTIVE_WKS_IN_MULTI_SHEETS
}
//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 plotpClamp_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
