/*------------------------------------------------------------------------------*
 * File Name:PlotSetup.c														*
 * Creation: CPY 6/12/2003														*
 * Purpose: OriginC Source C file for Plot Setup dialog							*
 * Copyright (c) Originlab Corp. 2003, 2004, 2005, 2006, 						*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	CPY 7/30/03 PLOT_TYPE_LIST_SEL_SUPPORT										*
 *	CPY 8/17/03 ROW_NUMBER_ROW_ONLY_X_ALLOWED									*
 *	CPY 8/18/03 AUTO_ENTER_EDIT_WHEN_DATAPLOT_SELECTED							*
 *	CPY 8/21/03 QA70-5034 COL_WKS_CONTEXT_MENU_IMPROVEMENT						*
 *	RVD 8/25/2003 QA70-5042 v7.0674 DATAPLOT_LIMITS_DISPLAY						*
 *	CPY 9/6/03 v7.5686 RESIZEING_CLEAN_UP										*
 *	CPY 9/9/03 v7.5689 TERNARY_PLOT_USE_2D_TYPES								*
 *	RVD 9/3/2003 QA70-5078 v7.0682 PLOT_RANGE_APPLY								*
 *	CPY 10/26/03 AUTO_SEL_LAST_ACTIVE_WKS_MATRIX								*
 *------------------------------------------------------------------------------*/
 
////////////////////////////////////////////////////////////////////////////////////
// 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 <Dialog.h>	// this file is needed for DialogBuilder support

#include "ODlg.h" // resource IDs in ODlg.dll which this dialog is based upon
#include "HelpID.h" // our Dialog's ID is in this file so that it can be connected to our help system

#include "GridControl.h" // wrapper classes for vsFlexGrid control that provides centrlized functions that we should use as base class for all vsFlex grids
#include "ResizeDialog.h" // helper class derived from Dialog class that supports placement and arrangement of controls, and resizing of the dialog

#include <Profiler.h>
////////////////////////////////////////////////////////////////////////////////////////////////
// string localization section
// here we define all the strings that is longer and best to use macro, other strings can
// appear directly inside code using the _L() macro
#define _CAT "Plot Setup"	// category for localization table, not always needed, used only for short string that might otherwise be confusing
#define SCP_DLG_TITLE_LEFT_NEW_PLOT 		_L("Plot Setup: Select Data to Create New Plot")
#define SCP_DLG_TITLE_LEFT_LAYER_CONTENTS	_L("Plot Setup: Configure Data Plots in Layer")

#define SCP_DLG_X_ROW_NUM_TITLE				_L("Use Row Number as X")
#define	SCP_DLG_X_ROW_NUM_LABEL				_L("Please enter initial X value and increment")
////////////////////////////////////////////////////////////////////////////////////////////////

// we need to indicate function to be diff from dataset, but there is no such EXIST type in 
// Origin, so we will steal another EXIST const that is not being used
#define EXIST_FUNC_PLOT		EXIST_PLOT
//
//----- communication by PostMessage between controls and dialog
//WM_USER_ON_CONTROL_CHANGE wParam
enum {ON_CONTROL_CHANGE_COL_DESIGNATIONS = 1};


#define HOUR_GLASS			waitCursor junk;
#define PROFILE_HRGLASS		HOUR_GLASS	//Profiler junk;

//---- CPY 9/9/03 v7.5689 TERNARY_PLOT_USE_2D_TYPES
// this function is needed in several classes, we should not call GetPlotTypeInfo directly, need all these additional fix up
static int	get_plot_type_info(int nPlotID, int nPageType, DWORD dwTargetLayer, DWORD& dwAuxTypeInfo, DWORD& dwAuxPlotInfo, string& strColPattern)
{
	int nPlotType = 0;
	
	if(nPlotID)
		nPlotType = Project.GetPlotTypeInfo(nPlotID, dwAuxTypeInfo, dwAuxPlotInfo, strColPattern);
	if(nPageType)
	{
		if(EXIST_DATA == nPageType || EXIST_FUNC_PLOT == nPageType)
			dwAuxTypeInfo &= ~PCD_CAN_ADD_E_H_L;
		if(EXIST_FUNC_PLOT == nPageType)
			dwAuxTypeInfo |= PCD_NO_X;
	}
	
	if (PCD_LAYER_TRI == dwTargetLayer)
	{
		DWORD dwSaveModifiers = dwAuxTypeInfo & ( PCD_MODIFIER_SIZE | PCD_MODIFIER_COLOR );
		dwAuxTypeInfo = PCD_LAYER_TRI | PCD_EXACT_YCOLS | PCD_Z_PREFER_Y | PCD_GROUP_MULTI_YS | PCD_PREFER_X | PCD_CAN_ADD_E_H_L | PCD_HIDE_ERR_BARS;
		dwAuxTypeInfo |= dwSaveModifiers;
	}
	else if (PCD_LAYER_SMITH == dwTargetLayer)
		dwAuxTypeInfo |= PCD_HIDE_ERR_BARS;
	return nPlotType;
}
//---- 
#include "ColDesignations.h"		// middle pane, PlotDesignations, or Column List, this class supports the control to pick XY checkboxes
#include "WksListControl.h"			// top pane, listing of worksheets
#include "PlotTypeListControl.h"	// left list control of middle of dialog, manage the plot types
#include "PlotListControl.h"		// bottom pane, Layer Contents, and Plots List

//////-------- CPY 7/30/03
// the following are implemented here because of class pointer ColListControl, so menu needs ColListControl, and has to be done outside class declaration
enum {
	CLCMENU_APPLY_DESTINATIONS, 
	CLCMENU_CHECK_ALL_UP, 
	CLCMENU_CHECK_ALL_DOWN, 
		CLCMENU_SEPARATOR0, 
	CLCMENU_CLEAR_ABOVE_DESIGNATIONS, 
	CLCMENU_CLEAR_BELOW_DESIGNATIONS, 
	CLCMENU_CLEAR_ALL_DESIGNATIONS, 
		CLCMENU_SEPARATOR, 
	CLCMENU_SHOW_ALL_COLS, 
		CLCMENU_SEPARATOR1, 
	CLCMENU_ERR_X, 
	CLCMENU_ERR_Y_POS_NEG, 
		CLCMENU_SEPARATOR2, 
	CLCMENU_ROW_AS_X,
		CLCMENU_SEPARATOR3, 
	CLCMENU_INCREASE,
	CLCMENU_DECREASE,
	
	CLCMENU_END
};
bool ColListControlMenu::GetCommand(int& nChoice)
{
	if(m_nChoice >= CLCMENU_APPLY_DESTINATIONS && m_nChoice < CLCMENU_END)
	{
		nChoice = m_nChoice;
		return true;
	}
	return false;
}

ColListControlMenu::ColListControlMenu(ColListControl* pCLcntrl, int nRow, int nCol)
{
	m_nChoice = -1;
	UINT nFlags = 0;
	DWORD dwEnable = 0;
//	Button btnApplyWks = pCLcntrl->GetItem(IDC_SELCOLS_APPLY_WKS);
//	if(btnApplyWks)
//		nFlags = btnApplyWks.Check?MF_CHECKED : MF_UNCHECKED;
	
	Add(_L("Apply Designations"), OnMenuItem, nFlags);
	nFlags = nRow < 0? MF_DISABLED | MF_GRAYED : MF_ENABLED;
	Add(_L("Set All to Top"), OnMenuItem, nFlags);
	Add(_L("Set All to Bottom"), OnMenuItem, nFlags);
Add(NULL, OnMenuItem);//--------------- separator
	nFlags = pCLcntrl->GetNumDesignationsAssigned()? MF_ENABLED : MF_DISABLED | MF_GRAYED;
	if(MF_ENABLED == nFlags && nRow < 0) // outside
		nFlags = MF_DISABLED | MF_GRAYED;	
	Add(_L("Clear All to Top"), OnMenuItem, nFlags);
	Add(_L("Clear All to Bottom"), OnMenuItem, nFlags);
	// reset
	nFlags = pCLcntrl->GetNumDesignationsAssigned()? MF_ENABLED : MF_DISABLED | MF_GRAYED;
	Add(_L("Clear All Designations"), OnMenuItem, nFlags);
	
Add(NULL, OnMenuItem);//--------------- separator
		nFlags = pCLcntrl->m_chkShowAllCols.Check? MF_CHECKED : MF_UNCHECKED;
		dwEnable = pCLcntrl->IsWorksheetPages()? MF_ENABLED : MF_DISABLED | MF_GRAYED;
	Add(_L("Show Disregarded(and hidden) Columns"), OnMenuItem, nFlags | dwEnable);	//CLCMENU_SHOW_ALL_COLS
Add(NULL, OnMenuItem);//--------------- separator
		dwEnable = pCLcntrl->IsAllowErrbars()? MF_ENABLED : MF_DISABLED | MF_GRAYED;
		nFlags = pCLcntrl->m_chkXErrBars.Check?MF_CHECKED : MF_UNCHECKED;
	Add(_L("X Error Bars"), OnMenuItem, nFlags | dwEnable);
		nFlags = pCLcntrl->m_chkPosNegErrBars.Check?MF_CHECKED : MF_UNCHECKED;
	Add(_L("Y Error Bars Plus/Minus"), OnMenuItem, nFlags | dwEnable);
Add(NULL, OnMenuItem);//--------------- separator
		dwEnable = pCLcntrl->IsAllowX()? MF_ENABLED : MF_DISABLED | MF_GRAYED;
		nFlags = pCLcntrl->m_chkAddRowNumX.Check?MF_CHECKED : MF_UNCHECKED;
	Add(_L("Allow Row# as X"), OnMenuItem, nFlags | dwEnable);
Add(NULL, OnMenuItem);//--------------- separator
		Add(STR_INCREASE_HEIGHT, OnMenuItem);
		Add(STR_DECREASE_HEIGHT, OnMenuItem);		
}

void ColListControl::OnBeforeMouseDown(Control cntrl, short nButton, short nShift, float X, float Y, BOOL* pCancel)
{
	int nRow = m_flx.MouseRow;
	int nCol = m_flx.MouseCol;
	if(MK_RBUTTON == nButton && 0 == nShift)
	{
		int nx = XTwipsToPixels(X);
		int ny = YTwipsToPixels(Y);
		ClientToScreen(nx, ny);
		//printf("nx = %d, ny = %d\n", nx, ny);
		ColListControlMenu	myMenu(this, nRow, nCol);
		myMenu.TrackPopupMenu(0,  nx, ny, GetDlgSafeHwnd());
		int nCmd;
		if(myMenu.GetCommand(nCmd))
		{
			switch(nCmd)
			{
			case CLCMENU_APPLY_DESTINATIONS:
				ApplyWksColDesignations(true);
				break;
				break;
			case CLCMENU_CLEAR_ALL_DESIGNATIONS:
				ClearColDesignations();
				break;
			case CLCMENU_CLEAR_ABOVE_DESIGNATIONS:
				ClearColDesignations(nRow, nCol, false);
				break;
			case CLCMENU_CLEAR_BELOW_DESIGNATIONS:
				ClearColDesignations(nRow, nCol, true);
				break;				
			case CLCMENU_CHECK_ALL_UP:
				SetColDesginations(nRow, nCol, false);
				break;
			case CLCMENU_CHECK_ALL_DOWN:
				SetColDesginations(nRow, nCol, true);
				break;				
			case CLCMENU_SHOW_ALL_COLS:
				m_chkShowAllCols.Check = m_chkShowAllCols.Check?false:true;
				updateShowColsRows();
				updateDesignations(true);
				break;
			case CLCMENU_ERR_X:
				m_chkXErrBars.Check = m_chkXErrBars.Check?false:true;
				break;
			case CLCMENU_ERR_Y_POS_NEG:
				m_chkPosNegErrBars.Check = m_chkPosNegErrBars.Check?false:true;
				break;
			case CLCMENU_ROW_AS_X:
				m_chkAddRowNumX.Check = m_chkAddRowNumX.Check?false:true;
				break;
			case CLCMENU_INCREASE:
				PostDlgMessage(WM_USER_RESIZE_CONTROLS, 1 , LPARAM_RESIZE_CONTROLS_INCREASE);
				break;
			case CLCMENU_DECREASE:
				PostDlgMessage(WM_USER_RESIZE_CONTROLS, 1 , LPARAM_RESIZE_CONTROLS_DECREASE);
				break;					
			}
			if(CLCMENU_ERR_X == nCmd || CLCMENU_ERR_Y_POS_NEG == nCmd)
				OnChangeErrBarOptions();
			if(CLCMENU_ROW_AS_X == nCmd)
				OnChangeAddRowNumbers();
		}
		return;
	}
	//----- CPY 8/17/03 ROW_NUMBER_ROW_ONLY_X_ALLOWED
	if(nRow == getRowNumberRow() && !isXCol(nCol))
		return;
	//-----
	GridListControl::OnBeforeMouseDown(nButton, nShift, X, Y, pCancel);
}
//////-------- end CPY 7/30/03

//------ CPY 8/21/03 QA70-5034 COL_WKS_CONTEXT_MENU_IMPROVEMENT
//	void ClearColDesignations(int nRow = -1, int nCol = -1, bool bAllDown = false, bool bKeepX = false, bool bRepaint = true);
void ColListControl::ClearColDesignations(int nRowCurrent, int nCol, bool bAllDown, bool bKeepX, bool bRepaint)// = -1 = -1 = false  false true);
{
	HOUR_GLASS
	
	int nR1 = m_flx.FixedRows;
	int nR2 = m_flx.Rows;
	
	if(nRowCurrent >= nR1)
	{
		bKeepX = true;
		if(bAllDown)
			nR1 = nRowCurrent;
		else
			nR2 = nRowCurrent+1;
	}
	for(int nRow = nR1; nRow < nR2; nRow++)
	{
		if(bKeepX && getColDesignation(nRow) == COLDESIG_X)
			continue;
		setDesignationRadioChoice(nRow, 0);
	}
	if(bRepaint)
		updateDesignations();
	notifyDlgOnDesignationChanges();
}
void ColListControl::SetColDesginations(int nRowCurrent, int nCol, bool bAllDown, bool bRepaint)// otherwise all up, = true
{
	HOUR_GLASS
	
	int nR1 = m_flx.FixedRows;
	int nR2 = m_flx.Rows;
	if(bAllDown)
		nR1 = nRowCurrent;
	else
		nR2 = nRowCurrent+1;
	
	for(int nRow = nR1; nRow < nR2; nRow++)
	{
		setDesignationRadioChoice(nRow, nCol);
	}
	if(bRepaint)
		updateDesignations();
	
	notifyDlgOnDesignationChanges();
}

string ColListControl::getColHeadingTooltips(int nCol)
{
	string str;
	int nDesignation = getDesignationOfCol(nCol);
	if(nDesignation >= 0)
	{
		switch(nDesignation)
		{
		case COLDESIG_LABEL:
			str = _L("Data Label");
			break;
		case COLDESIG_SIZE:
			str = _L("Symbol Size");
			break;
		case COLDESIG_COLOR:
			str = _L("Symbol Color");
			break;
		case COLDESIG_VECTOR_ANGLE:
			str = _L("Angle");
			break;
		case COLDESIG_VECTOR_MAGNITUDE:			
			str = _L("Magnitude");
			break;
		}
	}
	return str;
}

//------

#define		DBG_TREE_OUT(_tr, _lpcsMsg)		//tree_dump(_tr, _lpcsMsg, 4);

///////////// WAIT_FIX, this is needed until we can have class static member function and static data member
static	int s_nLeft = -1, s_nTop = -1;

static	bool get_n_box_event(TreeNode& myTree, int nRow, int nType, Dialog& dlgGetNBox)
{
	if(nRow < 0 && s_nLeft> 0 && s_nTop > 0) // init
	{
		RECT r1;
		Window wnd = dlgGetNBox.GetWindow();
		wnd.GetWindowRect(&r1);
		OffsetRect(&r1, s_nLeft - r1.left, s_nTop - r1.top);
		wnd.MoveWindow(&r1);
		s_nLeft = s_nTop = -1;
	}
	return false;
}
/////////////

#define		STR_AVAIL_DATA_CHOICE			"AvailData"
#define		STR_DATA_PLOTS					"DataPlots"

//////////////////////////////
//////////////////////////////
#define		STR_LAYER_NODE_NAME_PREFIX		"Layer"
#define		STR_LAYER_NODE_NAME_DISPLAY		_LC("Layer", _CAT)

BOOL	init_tree_num_layers(TreeNode &tr, int nNumLayers = 1)
{
	if (nNumLayers < 1)
		nNumLayers = 1;
	
	tr.RemoveChild(STR_DATA_PLOTS);
	TreeNode		trRoot = tr.AddNode(STR_DATA_PLOTS);
	if (!trRoot.IsValid())
	{
		ASSERT(FALSE);
		return FALSE;
	}
	
	for (int ii = 0; ii < nNumLayers; ii++)
	{
		string			strLayerNodeName;
		string			strLabel;
		//strLayerNodeName.Format("Layer%d", ii);
		strLayerNodeName.Format("%s%d", STR_LAYER_NODE_NAME_PREFIX, ii);
		TreeNode		trLayerNode = trRoot.AddNode(strLayerNodeName);
		if (trLayerNode.IsValid())
		{
			strLabel.Format("%s %d", STR_LAYER_NODE_NAME_DISPLAY, ii + 1);
			trLayerNode.SetAttribute(STR_LABEL_ATTRIB, strLabel);
			// Let the internal code know that this is a branch (since it will
			// be empty for now)
			trLayerNode.SetAttribute(STR_ID_ATTRIB, ONODETYPE_BRANCH);
		}
		else
			ASSERT(FALSE);
	}

	return TRUE;
}

static bool is_plot_list_empty(TreeNode &tr)
{
	foreach (TreeNode trLayer in tr.Children)
	{
		if(trLayer.GetNodeCount() > 0)
			return false;
	}
	return true;
}
	
typedef	void (*PFNApplySystemThemeToPage)(OriginObject& obj);
static bool	apply_plot_list_tree_to_page(GraphPage &pg, TreeNode &tr, DWORD dwCtrl)
{
	if (!pg)
	{
		ASSERT(FALSE);
		return FALSE;
	}

	HOUR_GLASS
	
	foreach (TreeNode trLayer in tr.Children)
	{
		string			strName = trLayer.tagName;
		string			strPrefix;
		
		int				nIndex = string_to_prefix_end_number(strPrefix.GetBuffer(MAXLINE), strName);
		strPrefix.ReleaseBuffer();
		
		if (strPrefix.CompareNoCase(STR_LAYER_NODE_NAME_PREFIX) == 0)
		{
			GraphLayer	grl = pg.Layers(nIndex);
			if (grl)
				grl.AddPlots(trLayer, dwCtrl);
			else
				return false;	// cannot find the layer
		}
		else
			return false;	// there are other nodes?
	}
	
	if( dwCtrl & ADDPLOTSFROMTREE_NEW )
	{
		PFNApplySystemThemeToPage pfn = Project.FindFunction("ApplySystemThemeToPage", "Originlab\\OriginEvents.c");
		if( pfn )
			pfn(pg);
	}
	
	return true;
}
//////////////////////////////

// this function opens the Plot Setup dialog
//when calling from a graph layer, this dialog work with treenodes, 
//
// return 0 if user cancel, otherwise, return the DWORD that will be passed into grl.AddPlots
// nExVal = -1 to indicate that we are using template library
static DWORD SelColsPlottingDlg(bool bNewPlot, TreeNode& trPlotList, int nPlotID, int nExVal, HWND hWndParent = NULL)
{	
	SelColsForPlottingDlg MyDlg(bNewPlot, trPlotList, nPlotID, nExVal);
	
 	return MyDlg.DoModalEx(hWndParent);
}

static bool get_gpage_plot_contents_and_check_plot_type(const GraphPage &pg, TreeNode &trPlots, int& nPlotType)
{
	HOUR_GLASS
	
	int nTemplatePlotType = gpage_get_plots(pg, trPlots);
		
	if ( 0 == nTemplatePlotType )
		return false;
	if(0 == nPlotType || IDM_PLOT_UNKNOWN == nPlotType)
	{
		if(nTemplatePlotType != IDM_PLOT_UNKNOWN)
			nPlotType = nTemplatePlotType;
		else
			nPlotType = 0;
	}
	return true;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Main function
// this function is called from inside Origin to bring up the Plot Setups dialog
// 
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
BOOL PlotSetup(BOOL bNewPlot = FALSE, int nPlotID = IDM_PLOT_LINE, LPCSTR lpcszTemplate = NULL, HWND hWndParent = NULL)
{
	Tree	trPlots;
	DWORD	dwAddPlotCntrl = 0;

	if(!bNewPlot) // open from graph window, layer contents
	{
		//Tree		trPage;
		GraphPage	pg = Project.Pages();
		bool		bFromLayerContents = 0==nPlotID? true : false;
		
		if ( !get_gpage_plot_contents_and_check_plot_type(pg, trPlots, nPlotID) )
			return FALSE;
		
		if(bFromLayerContents)
			nPlotID = 0; // this is the only way to indicate that we are from layer contents
		
		if(dwAddPlotCntrl = SelColsPlottingDlg(false, trPlots, nPlotID, 0, hWndParent))
		{
			apply_plot_list_tree_to_page(pg, trPlots.DataPlots, dwAddPlotCntrl);
			return TRUE;
		}
		return FALSE;
	}
	//
	// from here on, we are making new plots, so no current graph window to be considered, a new graph window is always created
	//
	string strTemplate = lpcszTemplate; // possible TemplateName:nExval, template name might be followed by int value that specify additional plotting info
	int nExVal = 0; // additional plotting info
	if(strTemplate.GetLength() > 3) // assume template name of at least 2 chars, like "AB:3"
	{
		int nExValPos = strTemplate.ReverseFind(':');
		if(nExValPos > 1) // to avoid "c:\c\vc32\line.otp"
		{
			nExVal = atoi(strTemplate.Mid(nExValPos + 1));
			strTemplate = strTemplate.Left(nExValPos);
		}
	}
	string strTemplatePath = GetFilePath(strTemplate); 
	bool bTemplateLib = strTemplatePath.IsEmpty()? false:true;
	GraphPage gp;
	if(!gp.Create(strTemplate, CREATE_HIDDEN))
		return false;
	
	if(bTemplateLib)
		nExVal = -1;// nExVal = -1 to indicate template library

	if(get_gpage_plot_contents_and_check_plot_type(gp, trPlots, nPlotID))
	{
		dwAddPlotCntrl = SelColsPlottingDlg(true, trPlots, nPlotID, nExVal, hWndParent);
		if(dwAddPlotCntrl && trPlots.DataPlots.IsValid()) // = 0 if user cancel
		{
			gp.SetShow();
			apply_plot_list_tree_to_page(gp, trPlots.DataPlots, dwAddPlotCntrl);
			if(dwAddPlotCntrl & ADDPLOTSFROMTREE_NEW)
				gp.LT_execute("legend -s");
			return true;
		}
		gp.Destroy();
	}
	return false;
}

#define OFFSET_WKS_LIST_SUPPORT_ITEMS 1
#define OFFSET_COL_LIST_SUPPORT_ITEMS 4
#define OFFSET_COL_LIST_LAYER_CONTENTS 1


static 	uint s_nWksListCntrlIDs[] = {IDC_SELCOLS_WKSTREE, IDC_SELCOLS_AVAILABLE_DATA_LABEL, IDC_SELCOLS_AVAILABLE_DATA, IDC_SELCOLS_APPLY_WKS_LABEL, 0};//IDC_SELCOLS_APPLY_WKS, 0};
static	uint s_nColListCntrlIDs[] = {IDC_SELCOLS_SHOW_PLOTS, IDC_SELCOLS_SHOW_DATA, IDC_SELCOLS_COLS_LABEL, IDC_SELCOLS_COLS, IDC_SELCOLS_PLOT_TYPES_LABEL, IDC_SELCOLS_PLOT_TYPES,0};//, IDC_SELCOLS_X_ERR, IDC_SELCOLS_POS_NEG_ERR, IDC_SELCOLS_ADD_ROW_NUMBER, 0};

//-------- CPY 8/18/03 AUTO_ENTER_EDIT_WHEN_DATAPLOT_SELECTED
//static 	uint s_nCntrlButtons[] = {IDC_SELCOLS_ADD, IDC_SELCOLS_REPLACE, IDC_SELCOLS_EDIT, 0};
static 	uint s_nCntrlButtons[] = {IDC_SELCOLS_ADD, IDC_SELCOLS_REPLACE, 0};
//-------- end

//static 	uint s_nCntrlButtonsShowPlotList[] = {IDC_SELCOLS_SHOW_PLOTS, IDC_SELCOLS_ADD, IDC_SELCOLS_REPLACE, IDC_SELCOLS_EDIT, 0};
static 	uint s_nCntrlButtonsShowPlotList[] = {IDC_SELCOLS_SHOW_PLOTS, IDC_SELCOLS_ADD, IDC_SELCOLS_REPLACE, 0};
static  uint s_nCtrlsVertResize[] = {IDC_SELCOLS_WKSTREE, IDC_SELCOLS_COLS, IDC_SELCOLS_PLOTS, 0};
#define TOTAL_NUM_OF_PANELS  		3

#define IDC_SELCOLS_SHOW_COLS	IDC_SELCOLS_SHOW_PLOTS

//--- CPY 9/26/03 EDIT_PLOT_SHOW_HIGHLIGHT_IN_WKS_LIST
// m_bReady replaced by m_nReadyState
enum {STATE_NOT_READY, STATE_READY, STATE_WAIT_READY};
//---
////////////////////////////////////////////////////////
// class SelColsForPlottingDlg   
////////////////////////////////////////////////////////     
class SelColsForPlottingDlg : public ResizeDialog
{
public:
	SelColsForPlottingDlg(bool bNewPlot, TreeNode& trPlotList, int nPlotID = 0, int nExVal = 0) : ResizeDialog(IDD_SEL_COLS_PLOTTING, "ODlg")
	{
		m_bTemplateLib = false;
		m_bFromColList = false;
		
		if(nExVal < 0)
		{
			m_bTemplateLib = true;
			m_nMakeNewPlotExVal = 0;
		}
		else
			m_nMakeNewPlotExVal = nExVal; // for additional control info when making new plot
		
		m_bMakeNewPlot = bNewPlot;
		m_bAddToGraph = false;
		if(nPlotID > 0)
		{
			m_nPlotIDCaller = nPlotID;
			if(!bNewPlot)
				m_bAddToGraph = true;
		}
		m_nReadyState = STATE_NOT_READY;
		m_trCallerPlotList = trPlotList;
		
		m_bApplyWasDone = false;
	}
	DWORD	DoModalEx(HWND hParent)
	{
		DWORD dwRet = m_bMakeNewPlot? ADDPLOTSFROMTREE_NEW | ADDPLOTSFROMTREE_RESCALE: ADDPLOTSFROMTREE_EDIT;
		InitMsgMap();// will be called from internal later
		int nRet = DoModal(hParent);
		if(IDOK == nRet)
		{
			if (m_bFromColList)
				dwRet |= ADDPLOTSFROMTREE_IMPLICIT_STYLEHOLDERS;
			return dwRet;
		}
		return 0;
	}
	
protected:
	uint	GetCurrentPlotID(DWORD& dwAuxTypeInfo) 
	{
		return m_cntrlPlotTypes.GetCurrentPlotType(dwAuxTypeInfo);
	}
///----------------- Message Map ----------------
EVENTS_BEGIN
	ON_INIT(OnInitDialog) 
	ON_OK(OnOK)
	ON_DESTROY(OnDestroy)
	ON_BN_CLICKED(IDC_SELCOLS_SHOW_DATA, OnCheckShowWks)
	ON_BN_CLICKED(IDC_SELCOLS_SHOW_PLOTS, OnCheckShowPlots)
	
	ON_BN_CLICKED(IDC_SELCOLS_X_ERR, OnChangeErrBarOptions)
	ON_BN_CLICKED(IDC_SELCOLS_POS_NEG_ERR, OnChangeErrBarOptions)
	ON_BN_CLICKED(IDC_SELCOLS_ADD_ROW_NUMBER, OnChangeAddRowNumbers)
	ON_BN_CLICKED(IDC_SELCOLS_APPLY_WKS, OnApplyWksDesignations)

	ON_BN_CLICKED(IDC_SELCOLS_ADD, OnAdd)
//	ON_BN_CLICKED(IDC_SELCOLS_EDIT, OnEdit)
//	ON_BN_CLICKED(IDC_SELCOLS_REPLACE, OnReplace)
	ON_BN_CLICKED(IDC_APPLY, OnApply) //CPY 9/16/03 

	ON_CBN_SELCHANGE(IDC_SELCOLS_AVAILABLE_DATA, OnAvilableDataComboChange)
	ON_CBN_SELCHANGE(IDC_SELCOLS_PLOTS, OnDataPlotSelChange)
	
	//--- WM_USER
	ON_USER_MSG(WM_USER_ON_CONTROL_CHANGE, OnControlChange)
	ON_USER_MSG(WM_USER_RESIZE_CONTROLS, OnIncreaseDecreasePanelSize)
	
	//--- vsFlex realted
	ON_GRID_BUTTON_CLICK(IDC_SELCOLS_COLS, OnButtonClickColList)
	ON_GRID_BEFORE_EDIT(IDC_SELCOLS_COLS, OnBeforeEditColList)
	ON_GRID_AFTER_EDIT(IDC_SELCOLS_COLS, OnAfterEditColList)
	ON_GRID_BEFORE_MOUSE_DOWN(IDC_SELCOLS_COLS, OnBeforeMouseDownColList)
	ON_GRID_MOUSE_MOVE(IDC_SELCOLS_COLS, OnMouseMoveColList)
	
	ON_GRID_SEL_CHANGE(IDC_SELCOLS_WKSTREE, OnWksSelChange)
	ON_GRID_BEFORE_MOUSE_DOWN(IDC_SELCOLS_WKSTREE, OnBeforeMouseDownWksList)
	
	ON_GRID_SEL_CHANGE(IDC_SELCOLS_PLOT_TYPES, OnPlotTypeChange)//---- CPY 7/30/03 PLOT_TYPE_LIST_SEL_SUPPORT
	//---	
	/// TD 8-26-03 RESIZING
	ON_SIZE(OnResize)
	ON_GETMINMAXINFO(OnMinMaxInfo)
	/// ----TD 8-26-03 RESIZING
	ON_INIT_SIZE(OnInitSize)
EVENTS_END
///----------------------------------------------

	///////////////////////////////////////////////////////
	/// Event Handlers
	///////////////////////////////////////////////////////
	BOOL OnInitDialog()
	{
		//waitCursor junk;
		PROFILE_HRGLASS
		/// RVD 9/3/2003 QA70-5078 v7.0682 PLOT_RANGE_APPLY
		//string strRegForDlgInfo = "PlotSetupDlg"; //"SelColsForPlottingDlg";
		string strRegForDlgInfo = STR_PLOT_SETUP_DLG;
		/// end PLOT_RANGE_APPLY
		ResizeDialog::OnInitDialog();

		initUpDownShowButtons();
		
		m_cntrlPlotTypes.Init(IDC_SELCOLS_PLOT_TYPES, IDC_SELCOLS_PLOT_TYPES_STYLEHOLDER, *this);
		m_cntrlCols.Init(IDC_SELCOLS_COLS, *this, m_nPlotIDCaller, strRegForDlgInfo, m_nMakeNewPlotExVal, IDC_SELCOLS_X_ERR, IDC_SELCOLS_POS_NEG_ERR, IDC_SELCOLS_ADD_ROW_NUMBER, IDC_SELCOLS_COLS_LABEL, IDC_SELCOLS_SHOW_ALL_COLS);
		//m_cntrlPlotTypes.SetPlotType(m_cntrlCols.GetPlotType(), m_nPlotIDCaller, m_nMakeNewPlotExVal);
		DWORD		dwAuxTypeInfo = 0;
		int			nPlotType = m_cntrlCols.GetPlotType(&dwAuxTypeInfo);
		m_cntrlPlotTypes.SetPlotType(nPlotType, m_nPlotIDCaller, dwAuxTypeInfo, m_nMakeNewPlotExVal);

		m_cntrlWks.Init(IDC_SELCOLS_WKSTREE, *this, m_bMakeNewPlot, strRegForDlgInfo, IDC_SELCOLS_APPLY_WKS, IDC_SELCOLS_AVAILABLE_DATA);
		m_cntrlPlots.Init(IDC_SELCOLS_PLOTS, *this);
		
		if(!m_trCallerPlotList.DataPlots.IsValid())
			init_tree_num_layers(m_trCallerPlotList, m_cntrlCols.GetNumLayers());
		
		m_cntrlPlots.SetTree(m_trCallerPlotList);
				
		m_staticAvailDataLabel = GetItem(IDC_SELCOLS_AVAILABLE_DATA_LABEL);
		m_staticPlotListLabel = GetItem(IDC_SELCOLS_PLOTS_LABEL);
		m_btnAddReplacePlot = GetItem(IDC_SELCOLS_ADD);
		m_btnOK = GetItem(IDOK);
		m_btnApply = GetItem(IDC_APPLY);
		//------ CPY 9/6/03 v7.5686 RESIZEING_CLEAN_UP
		/*
		//// save the group size so we can resize the whole dialog
		RECT r1;
		m_cntrlWks.GetRect(r1);
		m_nWksListGroupHeight = r1.bottom;
		m_cntrlCols.GetRect(r1);
		m_nPlotListGroupHeight = GetDlgExtent() - r1.bottom;
		m_nColListGroupHeight = RECT_HEIGHT(r1);
		*/
		//m_comboPlotTypes = GetItem(IDC_SELCOLS_PLOT_TYPES);
		//m_btnEditPlot = GetItem(IDC_SELCOLS_EDIT);
		//m_btnReplacePlot = GetItem(IDC_SELCOLS_REPLACE);
		
		//--- use diff reg section as the settings might have diff preferences between these cases
		string strRegSection = "LayerContentsDlg";
		if(m_bMakeNewPlot)
			strRegSection = strRegForDlgInfo;
		//---	
		ResizeDialog::LoadCheckBoxSettings(strRegSection, IDC_SELCOLS_SHOW_DATA, IDC_SELCOLS_SHOW_PLOTS, IDC_SELCOLS_X_ERR, IDC_SELCOLS_POS_NEG_ERR, IDC_SELCOLS_ADD_ROW_NUMBER, IDC_SELCOLS_APPLY_WKS, IDC_SELCOLS_SHOW_ALL_COLS);
		if(m_bAddToGraph)
		{
			m_chkShowWks.Check = true;
			m_chkShowPlots.Check = true;
		}
		else if(m_bTemplateLib)
			m_chkShowPlots.Check = true;
			
		showWksListGroup(isAvailDataListShown());
		//----CPY 8/19/03, show order important, otherwise can seem like bad drawing of dialog, old code always show/hide PlotList, then follow by ColList
		if(isColListShown()) 
		{
			showPlotListGroup(isPlotListShown());
			showColListGroup(true);
		}
		else
		{
			showColListGroup(false);
			showPlotListGroup(isPlotListShown());
			
			// temp
			m_cntrlPlotTypes.SetVisible(false);
		}
		//----


		m_cntrlWks.OnReady(getAvailDataListLastChoice(), m_bMakeNewPlot, dwAuxTypeInfo);// if making new plot, then sel current wks
		m_cntrlPlotTypes.OnReady(dwAuxTypeInfo, m_cntrlWks.GetCurrentPageType());
		/// RVD 9/3/2003 QA70-5078 v7.0682 PLOT_RANGE_APPLY
		DWORD dwView = 0;
		if( dlg_load_registry(STR_PLOT_SETUP_DLG, STR_PLOT_VIEW, dwView) )
			m_cntrlPlots.OnReady(m_bMakeNewPlot, m_bTemplateLib, dwView);
		else
		/// end PLOT_RANGE_APPLY
			m_cntrlPlots.OnReady(m_bMakeNewPlot, m_bTemplateLib);
			
		m_cntrlCols.OnReady();

		if(!isAvailDataListShown())
			m_cntrlCols.UpdateList();
		
		if(m_bMakeNewPlot)
		{
			m_wndDlg.Text = SCP_DLG_TITLE_LEFT_NEW_PLOT;// + getCurrentPlotType();
		}
		else
			m_wndDlg.Text = SCP_DLG_TITLE_LEFT_LAYER_CONTENTS;
		
		//if ( m_btnEditPlot )
		//	m_btnEditPlot.Enable = FALSE;
		
		//if ( m_btnReplacePlot )
		//	m_btnReplacePlot.Enable = FALSE;
		//--- CPY 9/6/03 v7.5686 RESIZEING_CLEAN_UP
		AddPanel(&m_cntrlWks);
		AddPanel(&m_cntrlCols);
		AddPanel(&m_cntrlPlots);
		LoadSizeOfPanels();
		//--- end CPY 9/6/03 v7.5686 RESIZEING_CLEAN_UP
		m_nReadyState = STATE_READY;
		
		enableOKbutton(false);// CPY, startup with OK disabled, must have proper settings to enable
		return TRUE;	
	}
	BOOL OnInitSize(int &left, int &top, int &right, int  &bottom)
	{
		RECT rect;
		rect.left =left;
		rect.top =top;
		rect.right =right;
		rect.bottom =bottom;
		repositionPanels(true, false, &rect);

		return FALSE;
	}
	BOOL OnIncreaseDecreasePanelSize(uint wParam, uint lParam)
	{
		if(ResizeDialog::OnIncreaseDecreasePanelSize(wParam, lParam))
		{
			repositionPanels();
		}
		return TRUE;
	}
	BOOL OnResize(int nType, int cx, int cy)
	{
		if(ResizeDialog::OnResize(nType, cx, cy))
			repositionPanels();
		
		return TRUE;
	}
	BOOL OnAvilableDataComboChange( Control ctrl )
	{
		m_cntrlWks.OnAvilableDataComboChange();
		return TRUE;
	}
	BOOL OnDataPlotSelChange(Control ctrl )
	{
		//-------- CPY 8/18/03 AUTO_ENTER_EDIT_WHEN_DATAPLOT_SELECTED
		//if ( m_btnEditPlot )
		//{
		//	BOOL			bEnableEdit = m_cntrlPlots.IsEditAllowed();
		//	m_btnEditPlot.Enable = bEnableEdit;
		//}
		//m_cntrlPlots.OnSelChange(m_cntrlPlotTypes);
		if(!isReadyEventHandling(true))
			return TRUE;

		//---- CPY 9/9/03 WKS_1000_COLS_TOO_SLOW
		if(m_cntrlPlots.IsSelSameRow())
			return TRUE;
		//----

		m_cntrlPlots.EndEdit(m_cntrlCols);
		checkStartEdit();
		return TRUE;
	}
	BOOL OnControlChange(uint wParam, uint lParam)
	{
		// we may get here from some other internal PostMessage, so check if lParam=NULL to avoid those, 
		// sinice lparam is typically hWnd if posted internally
		/// RVD 8/25/2003 QA70-5042 v7.0674 DATAPLOT_LIMITS_DISPLAY
		//if(0== lParam && ON_CONTROL_CHANGE_COL_DESIGNATIONS == wParam)
		if( lParam )
		{
			short	shMsg = LOWORD(wParam);
			if (shMsg <= 0)
			{
				if(ONCTRLCHNG_DELETE_ROWS == shMsg)
				{
					short		shRow = HIWORD(wParam);
					OnRemove(shRow);// need to change 1 to layer Row
				}
					
				return TRUE;		
			}
			m_cntrlPlots.UpdateDataPlotLimits(wParam);
		}
		else if( ON_CONTROL_CHANGE_COL_DESIGNATIONS == wParam )
		/// end DATAPLOT_LIMITS_DISPLAY
		{
			//m_btnAddReplacePlot.Enable = m_cntrlCols.IsReadyAddReplacePlot();
			enablePlottingButton();
		}
		return TRUE;
	}
	BOOL OnOK()
	{		
		if(isPlotListShown())
		{
			m_bFromColList = false;
			m_cntrlPlots.GetTree(m_trCallerPlotList);
			// call to make plot
		}
		else // no need to get from control, directly make plot
		{
			Tree trLayer;
			m_bFromColList = true;
			m_cntrlCols.GetDataPlots(trLayer);			
			m_trCallerPlotList.DataPlots.Layer0.XML = trLayer.Layer.XML;
		}
			
		return TRUE;
	}
	BOOL OnApply(Control cntrl)
	{
		m_bFromColList = false;
		Tree trTemp;
		m_cntrlPlots.GetTree(trTemp);
		if(trTemp.DataPlots.IsValid())
		{
			GraphPage	pg = Project.Pages();
			DWORD dwApplyFlags = ADDPLOTSFROMTREE_EDIT;
			apply_plot_list_tree_to_page(pg, trTemp.DataPlots, dwApplyFlags);
			// we need to update the layer contents after apply, so the correct tree is in the PlotList
			Tree trPlots;
			gpage_get_plots(pg, trPlots);			
			m_cntrlPlots.EndEdit(m_cntrlCols);
			updateGUIOnEditReplace(FALSE);
			m_cntrlPlots.SetTree(trPlots);
			
			m_bApplyWasDone = true;
		}
		return TRUE;
	}
	BOOL OnDestroy()
	{
		/// RVD 9/3/2003 QA70-5078 v7.0682 PLOT_RANGE_APPLY
		dlg_save_to_registry(STR_PLOT_SETUP_DLG, STR_PLOT_VIEW, m_cntrlPlots.GetView());
		/// end PLOT_RANGE_APPLY
		saveAvailDataListLastChoice(m_cntrlWks.GetAvailableDataChoice());
		SaveCheckBoxSettings();
		SaveSizeOfPanels();
		return TRUE;
	}
	BOOL OnAdd(Control cntrl)
	{
		if(m_cntrlCols.IsInEditMode())
		{
			//updateGUIOnEditReplace(FALSE); CPY 9/3/03 this is removed since Replace will no longer change selection after Marko changed in TreeEditor
			return doAddOrReplace(TRUE);
		}
		doAddOrReplace();
		m_cntrlCols.ClearAllDesignations();
		return TRUE;
	}
	void OnRemove(int nRowToSel)
	{
		m_cntrlPlots.OnRemove(nRowToSel);
	}
	void OnChangeAddRowNumbers(Control cntrl)
	{
		m_cntrlCols.OnChangeAddRowNumbers();
	}
	void OnChangeErrBarOptions(Control cntrl)
	{
		m_cntrlCols.OnChangeErrBarOptions();
	}
//public:
	//---- CPY 7/30/03 PLOT_TYPE_LIST_SEL_SUPPORT
	void OnPlotTypeChange(Control cntrl)
	{
		/// ML 9/28/2003
		//if(isReadyEventHandling())
		if(isReadyEventHandling(true))
			m_cntrlPlotTypes.OnPlotTypeChange(m_cntrlCols);
	}
	//----
	void OnApplyWksDesignations(Control cntrl)
	{
		Button chkboxApplyWks = cntrl;
		if(chkboxApplyWks.Check)
			m_cntrlCols.ApplyWksColDesignations(true);
	}
	void OnBeforeMouseDownWksList(Control flxControl, short nButton, short nShift, float X, float Y, BOOL* pCancel)
	{
		if(isReadyEventHandling(true))
			m_cntrlWks.OnBeforeMouseDown(m_cntrlCols, nButton, nShift, X, Y, pCancel);
	}
	void OnWksSelChange(Control flxControl)
	{
		if(isReadyEventHandling())
		{
			//printf("m_bReady and OnWksSelChange\n");
			
			m_cntrlPlots.OnWksSelChange(m_cntrlCols);	//---- CPY 9/25/03 v7.5707 EDIT_PLOT_SHOW_HIGHLIGHT_IN_WKS_LIST
			int nPageType = m_cntrlWks.OnSelChange(m_cntrlCols);
			bool bIncludeStyleHolders = m_cntrlPlots.HasStyleHolders();
			bool bRetOK = m_cntrlPlotTypes.OnNewPageType(nPageType, bIncludeStyleHolders);
			m_cntrlPlotTypes.OnPlotTypeChange(m_cntrlCols, bRetOK);

		}
	}
	void OnCheckShowWks(Control cntrl)
	{
		showWksListGroup(isAvailDataListShown());
		repositionPanels(true, true);
	}
	void OnCheckShowPlots(Control cntrl)
	{
		if(m_bMakeNewPlot)
		{
			showPlotListGroup(isPlotListShown());
			repositionPanels();
			if(m_btnAddReplacePlot.Visible)
				enableOKbutton(false, true);
			else
				enablePlottingButton();
		}
		else
		{
			showColListGroup(isColListShown());
			repositionPanels(true, true);
		}
	}
	//// vsFlex events
	void OnButtonClickColList(Control flxControl, int nRow, int nCol)
	{
		m_cntrlCols.OnButtonClick(flxControl, nRow, nCol);
	}
	void OnAfterEditColList(Control flxControl, int nRow, int nCol)
	{
		m_cntrlCols.OnAfterEdit(flxControl, nRow, nCol);
	}
	void OnBeforeEditColList(Control cntrl, long nRow, long nCol, BOOL* pCancel)
	{
		m_cntrlCols.OnBeforeEdit(cntrl, nRow, nCol, pCancel);
	}
	void OnBeforeMouseDownColList(Control cntrl, short nButton, short nShift, float X, float Y, BOOL* pCancel)
	{
		m_cntrlCols.OnBeforeMouseDown(cntrl, nButton, nShift, X, Y, pCancel);
	}
	void OnMouseMoveColList(Control cntrl, short nButton, short nShift, float X, float Y)
	{
		m_cntrlCols.OnMouseMove(cntrl, nButton, nShift, X, Y);
	}
		
private:
	void initUpDownShowButtons()
	{
		m_chkShowWks = GetItem(IDC_SELCOLS_SHOW_DATA);
		m_chkShowPlots = GetItem(IDC_SELCOLS_SHOW_PLOTS);

		vector<string>  vstrTipsUpDown;
		vstrTipsUpDown.SetSize(2);
		vstrTipsUpDown[0] = _L("Show Available Data");
		vstrTipsUpDown[1] = _L("Hide Available Data");
		m_chkShowWks.Init(2, IDB_UPDOWN_BTN, 12, vstrTipsUpDown);
			
		if(m_bMakeNewPlot)
		{
			vstrTipsUpDown[0] = _L("Show Plot List");
			vstrTipsUpDown[1] = _L("Hide Plot List");
			m_chkShowPlots.Init(2, IDB_DOWNUP_BTN, 12, vstrTipsUpDown);
		}
		else
		{
			vstrTipsUpDown[0] = _L("Show Plot Designations");
			vstrTipsUpDown[1] = _L("Hide Plot Designations");
			m_chkShowPlots.Init(2, IDB_UPDOWN_BTN, 12, vstrTipsUpDown);
		}
	}
	BOOL	updateGUIOnEditReplace(BOOL bEdit)  // bEdit is TRUE OnEdit and FALSE on Replace/Cancel
	{
		if (bEdit)
			m_btnAddReplacePlot.Text = _L("Replace");
		else
		{
			m_btnAddReplacePlot.Text = _L("Add");
			// need to tell other controls
			m_cntrlPlotTypes.OnEndEditPlot();
		}
		return TRUE;
	}
	bool isInEditMode() 
	{
		if(m_btnAddReplacePlot)
		{
			if(m_btnAddReplacePlot.Visible && m_btnAddReplacePlot.Enable && m_cntrlCols.IsInEditMode())
				return true;
		}
		return false;
	}
	BOOL doAddOrReplace(BOOL bReplace = FALSE)
	{
		HOUR_GLASS //PROFILE_HRGLASS
		
		Tree	trDPList;
		/// RVD 9/3/2003 QA70-5078 v7.0682 PLOT_RANGE_APPLY
		//if(m_cntrlCols.GetDataPlots(trDPList))
		if(m_cntrlCols.GetDataPlots(trDPList, false, m_cntrlPlots.GetView()))
		/// end PLOT_RANGE_APPLY
		{
			if (bReplace)
				return m_cntrlPlots.AddDataPlots(trDPList, bReplace);
			else
			{
				vector<uint>		vnPlotIDs;
				if ( m_cntrlPlotTypes.GetPlotTypes(vnPlotIDs) )
				{
					enableOKbutton(true);
					return m_cntrlPlots.AddDataPlots(trDPList, vnPlotIDs);
				}
			}
		}
		return FALSE;
	}
	
	void showWksListGroup(bool bShow)
	{
		ShowControls(s_nWksListCntrlIDs, bShow);
//		if(!m_chkShowPlots.Visible) // Layer Contents must be show, that means we must connect the other two together
//			showColListGroup(bShow);
	}
	void showPlotListGroup(bool bShow)
	{
		uint nNewPlotCntrlIDs[] = {IDC_SELCOLS_PLOTS_LABEL, IDC_SELCOLS_PLOTS,  0};
		uint nLayerContentsCntrlIDs[] = {IDC_SELCOLS_SHOW_COLS, IDC_SELCOLS_PLOTS_LABEL, IDC_SELCOLS_PLOTS,  0};
		if(m_bMakeNewPlot)
			ShowControls(nNewPlotCntrlIDs, bShow);
		else
			ShowControls(nLayerContentsCntrlIDs, bShow);
			
		showLayerContentsEditButtons();
	}
	// col plot designation box is always show, but the plot type list may be not
	void showColListGroup(bool bShow)
	{
		if(m_bMakeNewPlot)
			ShowControls(s_nColListCntrlIDs, bShow);
		else
		{
			if(!bShow && m_chkShowWks.Check)
			{
				m_chkShowWks.Check = false;
				showWksListGroup(false);
			}
			ShowControls(&s_nColListCntrlIDs[OFFSET_COL_LIST_LAYER_CONTENTS], bShow);
			//---- CPY 10/26/03 AUTO_SEL_LAST_ACTIVE_WKS_MATRIX 
			if(bShow && !isInEditMode())
				checkStartEdit(false);
			//---- end AUTO_SEL_LAST_ACTIVE_WKS_MATRIX
		}
		showLayerContentsEditButtons();
	}
	// LayerContents buttons should be shown only if both ColList and PlotList are both visible
	void showLayerContentsEditButtons()
	{
		bool bShow = (m_cntrlCols.IsVisible() && m_cntrlPlots.IsVisible())? true:false;
		ShowControls(s_nCntrlButtons, bShow);
	}
	string getCurrentPlotType()
	{
		DWORD dwAuxTypeInfo;
		int nPlotType = GetCurrentPlotID(dwAuxTypeInfo);//Project.GetPlotTypeInfo(GetCurrentPlotID(), dwAuxTypeInfo, dwAuxPlotInfo, strColPattern);
		return GetPlotTypeName(nPlotType, dwAuxTypeInfo); // need to convert to text later from internal
	}
	//virtual 
	BYTE GetPanelsOrientation()
	{
		return PANEL_ORIENT_VERTICAL;
	}
	//virtual
	void repositionPanels(bool bResizeDlg = true, bool bMoveDlgUpDown = false, RECT *pDlgRect = NULL)
	{
		SetMoveRepaint(false);

		int cx = pDlgRect ? (pDlgRect->right - pDlgRect->left) : GetDlgExtent(false);
		int ny = positionWksListGroup(0, cx);
		ny = positionColListGroup(ny, cx);
		ny = positionPlotListGroup(ny, cx);
		ny = positionShowChecksAndOKCancel(ny, cx);
		if(bResizeDlg)
		{
			int ndy = ny - GetDlgExtent();
			ny += GetControlGap();
			RECT rWnd;
			m_wndDlg.GetWindowRect(&rWnd);
			if(bMoveDlgUpDown)
				rWnd.top -= ndy;
			else
				rWnd.bottom += ndy;
			
			if(rWnd.top < 0)
			{
				rWnd.bottom -= rWnd.top;
				rWnd.top = 0;
			}
			/// TD 8-26-03 RESIZING
			DisableOnSize();
			/// ----TD 8-26-03 RESIZING
			/// TD 9-9-03 RPOSIZION_TO_ORIGINAL_SIZE
			if(pDlgRect)
			{
				rWnd.bottom -= rWnd.top - pDlgRect->top;
				rWnd.top = pDlgRect->top;
				rWnd.left = pDlgRect->left;
				rWnd.right = rWnd.left +cx;
			}
			/// end RPOSIZION_TO_ORIGINAL_SIZE
			m_wndDlg.MoveWindow(&rWnd);
			/// TD 8-26-03 RESIZING
			DisableOnSize(false);
			/// ----TD 8-26-03 RESIZING
			UpdateWindow();
			
			SaveDlgHeight();//--- CPY 9/6/03 v7.5686 RESIZEING_CLEAN_UP
		}
		SetMoveRepaint(true);
	}
	int positionWksListGroup(int ny, int cx)
	{
		int nx = GetControlGap();
		if(isAvailDataListShown())
		{
			//uint nCntrlIDs[] = {IDC_SELCOLS_AVAILABLE_DATA_LABEL, IDC_SELCOLS_AVAILABLE_DATA, IDC_SELCOLS_APPLY_WKS_LABEL, IDC_SELCOLS_APPLY_WKS, 0};
			int nx1 = ArrangControlsTopDown(&s_nWksListCntrlIDs[OFFSET_WKS_LIST_SUPPORT_ITEMS], nx, ny, 0);
			ny = StretchControlWide(IDC_SELCOLS_WKSTREE, nx1 + GetControlGap(), ny, cx); 
		}
		return ny;
	}
	int positionColListGroup(int ny, int cx)
	{
		int nx = GetControlGap();
		// assume always show
		//	uint nCntrlIDs[] = {IDC_SELCOLS_PLOT_TYPES, IDC_SELCOLS_X_ERR, IDC_SELCOLS_POS_NEG_ERR, IDC_SELCOLS_ADD_ROW_NUMBER, 0};
		if(ny > 0)
			ny += GetControlGap();
		int nx1 = ArrangControlsTopDown(&s_nColListCntrlIDs[OFFSET_COL_LIST_SUPPORT_ITEMS], nx, ny, 0);
		ny = StretchControlLeftRight(IDC_SELCOLS_COLS_LABEL, IDC_SELCOLS_SHOW_DATA, nx1 + GetControlGap(), ny, cx);
		PositionControl(IDC_SELCOLS_PLOT_TYPES_STYLEHOLDER, nx, ny, true, false);
		ny = StretchControlWide(IDC_SELCOLS_COLS, nx1 + GetControlGap(), ny, cx);
		//---- CPY 7/30/03
		vector<uint> vnGrids = {IDC_SELCOLS_COLS, IDC_SELCOLS_PLOT_TYPES, 0};
		MakeSameSize(vnGrids);
		//----
		return ny;
	}
	
	int positionPlotListGroup(int ny, int cx)
	{
		int nx = GetControlGap();
		if(m_cntrlPlots.IsVisible())
		{
			if(ny > 0)
				ny+= GetControlGap();
			Control cntrl = GetItem(s_nCntrlButtons[0]);
			if(cntrl.Visible)
				ny = ArrangeControlsRightLeft(s_nCntrlButtonsShowPlotList, cx, ny);
			else
			{
				/*
				RECT r1;
				cntrl.GetWindowRect(&r1);
				ny += RECT_HEIGHT(r1);
				*/
				uint nShowColList[] = {IDC_SELCOLS_SHOW_COLS, 0};
				ny = ArrangeControlsRightLeft(nShowColList, cx, ny);
			}
			ny+= GetControlGap();

			PositionControl(IDC_SELCOLS_PLOTS_LABEL, nx, ny, false);
			ny = StretchControlWide(IDC_SELCOLS_PLOTS, nx, ny, cx); 
		}
		return ny;
	}
	int positionShowChecksAndOKCancel(int ny, int cx)
	{
		uint nNoPlotListCntrlIDs[] = {IDC_SELCOLS_SHOW_PLOTS, IDCANCEL, IDOK, 0};// IDC_SELCOLS_SHOW_DATA, IDC_SELCOLS_SHOW_PLOTS, 0};
		uint nHasPlotListCntrlIDs[] = {IDC_APPLY, IDCANCEL, IDOK, 0};// IDC_SELCOLS_SHOW_DATA, IDC_SELCOLS_SHOW_PLOTS, 0};
		ny+= GetControlGap();
		if(m_cntrlPlots.IsVisible())
			return ArrangeControlsRightLeft(nHasPlotListCntrlIDs, cx, ny);
		else
			return ArrangeControlsRightLeft(nNoPlotListCntrlIDs, cx, ny);
	}
	bool isColListShown()
	{
		if(m_bMakeNewPlot)
			return true;
		
		return m_chkShowPlots.Check;
	}
	bool isPlotListShown()
	{
		if(!m_bMakeNewPlot)
			return true;
		
		return m_chkShowPlots.Check;
	}
	bool isAvailDataListShown()
	{
		return m_chkShowWks.Check;
	}
	int getAvailDataListLastChoice()
	{
		// valled after LoadCheckBoxSettings for dialog, so can skip dialog name
		return LoadSetting(STR_AVAIL_DATA_CHOICE, -1);
	}
	void saveAvailDataListLastChoice(int nSel)
	{
		SaveSetting(STR_AVAIL_DATA_CHOICE, nSel);
	}
	//virtual 
	string GetRuntimeClass()
	{
		return "PlotSetup";
	}
	void enablePlottingButton()
	{
		bool bEnable = m_cntrlCols.IsReadyAddReplacePlot();
		
		if(m_btnAddReplacePlot.Visible)
			m_btnAddReplacePlot.Enable = bEnable;
		else if (m_bMakeNewPlot)
			m_btnOK.Enable = bEnable;
	}
	void enableOKbutton(bool bEnable, bool bTestPlotExist = false)
	{
		if(!m_bMakeNewPlot)
		{
			m_btnApply.Enable = true;
			return; // only when making new plot that we need to disable OK button
		}
		//if(!m_btnAddReplacePlot.Visible)
		//	return; // if Add button invisible, then OK button was not controlled by plot list info
		
		if(bTestPlotExist)
		{
			bEnable = m_cntrlPlots.HasDataPlots();
		}
		m_btnOK.Enable = bEnable;
		m_btnApply.Enable = false;// if making new plot, can never apply
	}
	bool isReadyEventHandling(bool bCheckWaitReadyState = false)
	{
		if(bCheckWaitReadyState && STATE_WAIT_READY == m_nReadyState)
			m_nReadyState = STATE_READY;

		return STATE_READY == m_nReadyState? true:false;
	}
	//------ CPY 10/26/03 AUTO_SEL_LAST_ACTIVE_WKS_MATRIX
	// separete this out to be reused
	void checkStartEdit(bool bOnSelChange = true)
	{
		updateGUIOnEditReplace(FALSE);

		bool bEnableEdit = m_cntrlCols.IsVisible() && m_cntrlPlots.IsEditAllowed();
		if(bOnSelChange)
			m_cntrlPlots.OnSelChange(m_cntrlPlotTypes, m_cntrlCols);
		if(bEnableEdit)
		{
			m_nReadyState = STATE_NOT_READY;
			if(m_cntrlPlots.StartEdit(m_cntrlCols, m_cntrlPlotTypes, m_cntrlWks))
			{
				updateGUIOnEditReplace(TRUE);
			}
			m_nReadyState = STATE_WAIT_READY;
		}
	}
	//------ end AUTO_SEL_LAST_ACTIVE_WKS_MATRIX
private:
	//bool	m_bReady;
	int		m_nReadyState;
	
	bool	m_bMakeNewPlot;
	bool	m_bTemplateLib;
	bool	m_bAddToGraph;
	int		m_nMakeNewPlotExVal;
	int		m_nPlotIDCaller; // the id passed in when class started
	bool	m_bFromColList;		// does the tree (on OK) come from the second table?
	int		m_nWksListGroupHeight;
	int		m_nPlotListGroupHeight;
	int		m_nColListGroupHeight;
	/// TD 8-26-03 RESIZING

	//int		m_nWksTreeHt;
	//int		m_nPlotTypeHt;
	//int		m_nPlotsHt;
	//bool	m_bDoNotHandleOnSize;
	/// ----TD 8-26-03 RESIZING
private:
	TreeNode	m_trCallerPlotList; // tree from caller
	// main tables
	WksListControl		m_cntrlWks;			// AD
	ColListControl		m_cntrlCols;		// PD
	PlotListControl		m_cntrlPlots;		// DP
	
	//
	PlotTypeListControl	m_cntrlPlotTypes;	// just a list of plot types available to this dialog
	/// other controls
	//Button	m_chkShowWks;
	//Button	m_chkShowPlots;
	BitmapRadioButton	m_chkShowWks;	
	BitmapRadioButton	m_chkShowPlots;
	Control m_staticAvailDataLabel;
	Control m_staticPlotListLabel;
	//Button	m_btnEditPlot;
	//Button	m_btnReplacePlot;
	Button	m_btnAddReplacePlot;
	Control	m_btnOK;
	Control	m_btnApply;
	bool	m_bApplyWasDone;
};


