/*------------------------------------------------------------------------------*
 * File Name:PlotTypeListControl.h												*
 * Creation: CPY 7/30/2003														*
 * Purpose: OriginC Class for managing the plot type list control for the  		*
 * the Plot Setup dialog														*
 * Copyright (c) Originlab Corp. 2003, 2004, 2005, 2006, 						*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	CPY created 7/30/03 PLOT_TYPE_LIST_SEL_SUPPORT								*
 *	CPY 9/9/03 v7.5689 TERNARY_PLOT_USE_2D_TYPES								*
 *	CPY 9/20/03 MATRIX_SEL_SEE_3D_PLOTS_IN_2D_LAYERS							*
 * 	CPY 9/23/03 QA70-5134 v7.5704 3D_XYY_SHOULD_BE_NO_FUNCTION_PLOTS			*
 *	CPY 10/7/03 QA70-5309 v7.5714 CUSTOM_PLOT_TYPE_BROKEN_BY_END_EDIT			*
 *	Jasmine 04/05/07 QA80-9560 ADD_XYZ_CONTOUR_TO_PLOT_TYPE_LIST				*
 *	Jasmine 05/28/07 QA70-6714 REMEMBER_CUSTOM_PLOT_ID							*
 *	CPY 8/1/2007 QA70-9867 POLAR_XY_SWITCHED_FOR_XYZ_CONTOUR					*
 *	Jasmine 01/22/2009 QA80-12738 ALLOW_AREA_STACK_FOR_PS						*
 *	Sophy 8/24/2010 ORG-826-P1 WRONG_CURRENT_PAGE_TYPE_WHEN_FAIL_TO_LOAD_FROM_REGISTRY
 *	Sophy 9/10/2010 ORG-789 CREATE_3D_SCATTER_WITH_ERR_BAR_OR_VECTOR_IN_PLOT_SETUP_DIALOG
 *------------------------------------------------------------------------------*/

enum {IDM_PLOT_CUSTOM = 1, IDM_PLOT_STYLE_HOLDER};

//------ CPY 9/23/03 QA70-5134 v7.5704 3D_XYY_SHOULD_BE_NO_FUNCTION_PLOTS
//#define _DEBUG_PLOT_TYPE
//------

class PlotTypeListControl : public GridListControl
{
public:
	void Init(int nID, int nIDStatic, Dialog& dlg)
	{
		GridListControl::Init(nID, dlg);
		m_cntrlStyleHolder = dlg.GetItem(nIDStatic);
		
		int nFixedRows = 0;
		m_flx.FixedRows = nFixedRows;
		m_flx.Editable = flexEDNone;
		m_flx.Cols = 1;
		m_flx.Rows = nFixedRows;
		//m_flx.FormatString = "Plot Type";
		m_nSelPlotType = 0;
		m_dwAuxTypeInfo = 0;
		m_nCustomPlotID = 0;
		m_nCustomPlotExVal = 0;
		m_cntrlStyleHolder.Visible = false;
		m_dwLayerBits = 0;
		m_nCurrentDataPageType = 0;//undefined, EXIST_;
		m_nEditPlotPageType = 0;// undefined
		m_nEditPlotType = 0;
		m_dwEditAuxTypeInfo = 0;
		m_bAvailDataReady = false;
		//----- CPY 10/7/03 QA70-5309 v7.5714 CUSTOM_PLOT_TYPE_BROKEN_BY_END_EDIT
		m_nCustomPlotID_save = -1;// CPY 10/7/03, to indicate not yet initialized
		m_nCustomPlotExVal_save = 0;
		//-----
	}
	bool OnReady(DWORD dwAuxTypeInfo, int nPageType) // when all init done, may beed to do further initialization
	{
		m_nCurrentDataPageType = nPageType;
		SetTargetLayerType(dwAuxTypeInfo & MASK_PCD_LAYER_BITS);
		return true;
	}
	//nPlotType = internal plot type
	//nPlotID = Origin plot ID, might be a general plot ID like bubble, typically a menu res ID
	bool SetPlotType(uint nPlotType, int nPlotID = 0, DWORD dwAuxTypeInfo = 0, int nPlotExVal = 0)
	{
		bool bNeedUpdate = m_nSelPlotType == 0? true:false;
		m_nSelPlotType = nPlotType;
		m_dwAuxTypeInfo = dwAuxTypeInfo;
		m_nCustomPlotID = nPlotID;
		m_nCustomPlotExVal = nPlotExVal;
		return true; 
	}
	// when DataPlotList is changing selected item
	// return true if plot list is shown, so caller might set additional attributes
	bool OnChangeTarget(int nDPLtype, ColListControl& listCols)
	{
		//----CPY 8/21/03 TARAK_HELP_FIND_REASON_GRID_SHOWING_IN_LAYER_CONTENTS_OPEN
		if(!listCols.IsVisible())
			return false;
		//----
		if(nDPLtype >= DPL_STYLE_HOLDER_OUTSIDE_GROUP)
		{
			SetVisible(false);
			m_cntrlStyleHolder.Visible = true;
			return false;
		}
		else
		{
			m_cntrlStyleHolder.Visible = false;
			SetVisible(true);
			return true;
		}
	}
	///Sophy 8/3/2010 ORG-681-P2 PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
	//void SetTargetLayerType(DWORD dwLayerBits)
	void SetTargetLayerType(DWORD dwLayerBits, BOOL  bVirtualMatrix = FALSE)
	///end PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
	{
		//printf("nLayer = %d\n", HIWORD(dwLayerBits));
		m_dwLayerBits = dwLayerBits;
		///Sophy 8/3/2010 ORG-681-P2 PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
		//OnNewPageType();
		OnNewPageType(-1, false, bVirtualMatrix);
		///end PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
	}
	void Update()
	{
		int nFixedRows = m_flx.FixedRows;
		m_flx.Rows = m_vnPlotTypes.GetSize() + nFixedRows;
		
		for(int ii = nFixedRows, jj = 0; ii < m_flx.Rows; ii++, jj++)
		{
			SetTextMatrix(ii, 0, getPlotTypeStr(m_vnPlotTypes[jj]));
			SetRowData(ii, m_vnPlotTypes[jj]);
		}
	}
	// called from main dialog, after ColListControl is updated with current edited data plot details
	void OnStartEditPlot(const string& strWksName, int nPlotType, DWORD dwAuxTypeInfo, DWORD dwLTPlotInfo)
	{
		m_nEditPlotPageType = EXIST_DATA;
		Page  pg(strWksName);
		if(pg)
		{
			m_nEditPlotPageType = pg.GetType();
			///Sophy 8/24/2010 ORG-826-P1 WRONG_CURRENT_PAGE_TYPE_WHEN_FAIL_TO_LOAD_FROM_REGISTRY
			//m_nCurrentDataPageType only initialized when in OnReady(), but at that time, if delete relative registry item, it will fail to load and get default value EXIST_WKS(int PlotSetup.c getAvailDataListLastChoice), which is wrong
			m_nCurrentDataPageType = m_nEditPlotPageType;
			///end WRONG_CURRENT_PAGE_TYPE_WHEN_FAIL_TO_LOAD_FROM_REGISTRY
		}
		
		
		m_nEditPlotType = nPlotType;
		m_dwEditAuxTypeInfo = dwAuxTypeInfo;
		
#ifdef _DEBUG_PLOT_TYPE		
		printf("On start edit, PlotType = %d, AuxTypeInfo = %X, layer bits = %X\n", nPlotType, dwAuxTypeInfo, (dwAuxTypeInfo & MASK_PCD_LAYER_BITS));
#endif

		m_nCustomPlotID_save = m_nCustomPlotID;
		m_nCustomPlotExVal_save = m_nCustomPlotExVal;
		///Sophy 8/3/2010 ORG-681-P2 PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
		//updatePlotTypeList(m_nEditPlotPageType, nPlotType, 0, dwAuxTypeInfo, dwLTPlotInfo); 	
		updatePlotTypeList(m_nEditPlotPageType, nPlotType, 0, dwAuxTypeInfo, dwLTPlotInfo, okutil_is_virtual_matrix(strWksName)); 	
		///end PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
	}
	void OnEndEditPlot()
	{
		m_nEditPlotType = 0;
		m_nEditPlotPageType = 0;
		m_dwEditAuxTypeInfo = 0;
		//---- CPY 10/7/03 QA70-5309 v7.5714 CUSTOM_PLOT_TYPE_BROKEN_BY_END_EDIT
		if(m_nCustomPlotID_save >= 0) // CPY 10/7/03, check was actually saved , OnEndEditPlot could be called without OnStartEditPlot	
		{
			m_nCustomPlotID = m_nCustomPlotID_save;
			m_nCustomPlotExVal = m_nCustomPlotExVal_save;
		}
		//----
	}
	///Sophy 8/3/2010 ORG-681-P2 PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
	//bool OnNewPageType(int nPageType = -1, bool bAddStyleHolderEntry = false)
	bool OnNewPageType(int nPageType = -1, bool bAddStyleHolderEntry = false, BOOL bVirtualMatrix = FALSE)
	///end PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
	{
		if(nPageType >= 0)
		{
			m_nCurrentDataPageType = nPageType;
		}
		else
		{
			if(m_nCurrentDataPageType < 0)
				return false;
			nPageType = m_nCurrentDataPageType;
		} 
		if( is_page_type_incompatible( m_nEditPlotPageType, nPageType ) )
			return false; 
		
		if(m_nEditPlotPageType)
			///Sophy 8/3/2010 ORG-681-P2 PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
			//updatePlotTypeList(nPageType, m_nEditPlotType, 0, m_dwEditAuxTypeInfo);		
			updatePlotTypeList(nPageType, m_nEditPlotType, 0, m_dwEditAuxTypeInfo, 0, bVirtualMatrix);		
			///end PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
		else	
			///Sophy 8/3/2010 ORG-681-P2 PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
			//updatePlotTypeList(nPageType);
			updatePlotTypeList(nPageType, 0, 0, 0, 0, bVirtualMatrix);
			///end PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
		
		m_bAvailDataReady = true;
		return true;
	}
	int GetCurrentPlotType(DWORD& dwAuxTypeInfo, int* pPlotExVal = NULL)
	{
		uint nPlotID = getSelPlotID(pPlotExVal);
		if(nPlotID)
			return getPlotType(nPlotID, &dwAuxTypeInfo);
		
		return 0;// none available
	}
	uint GetPlotTypeByIndex(int nIndex = 0) 
	{
		if(m_vnPlotTypes.GetSize() > nIndex)
			return m_vnPlotTypes[nIndex];
		
		return 0;//IDM_PLOT_LINE;
	}
	void OnPlotTypeChange(ColListControl& listCols, bool bReady = true)
	{
		if(!m_bAvailDataReady)
			return;
		
		int	nPlotExVal = 0;
		uint nPlotID = getSelPlotID(&nPlotExVal);
		if(bReady && nPlotID)
			listCols.OnChangePlotType(m_dwLayerBits, nPlotID, m_nCurrentDataPageType, nPlotExVal);
		else
			//----- CPY 8/1/2007 QA70-9867 POLAR_XY_SWITCHED_FOR_XYZ_CONTOUR
			//listCols.OnChangePlotType(0);
			listCols.OnChangePlotType(m_dwLayerBits, 0);
			//-----
	}
	// get the list of selected plot types, currently only one can be selected
	bool	GetPlotTypes(vector<uint> &vnPlotTypes)
	{
		vnPlotTypes.SetSize(0);
		DWORD dwAuxTypeInfo;
		int nPlotType = GetCurrentPlotType(dwAuxTypeInfo);
		if(nPlotType)
		{
			vnPlotTypes.Add(nPlotType);
			return true;
		}
		
		return false;
	}
private:
	bool isPlotTypeSpecial(uint nPlotID, vector<uint>& vnPlotTypes)
	{
		if(0 == nPlotID)
			return false;
		DWORD 	dwCustom;
		uint	nTypeCustom = getPlotType(nPlotID, &dwCustom);
		for(int ii = 0; ii < vnPlotTypes.GetSize(); ii++)
		{
			DWORD dwCompare;
			int nTypeCompare = getPlotType(vnPlotTypes[ii], &dwCompare);
			//DWORD	dwCompare = dw & ~PCD_LTPLOTINFO_HAS_NEXVAL;
			//DWORD	dwCustomCompare = dwCustom & ~PCD_LTPLOTINFO_HAS_NEXVAL;
			//if(nTypeCustom == nType && dwCompare == dwCustomCompare)
			if(isPlotTypesTheSame(nTypeCustom, dwCustom, nTypeCompare, dwCompare))
				return false;
		}
		return true;
	}
	bool isPlotTypesTheSame(int nPlotType1, DWORD dwAuxTypeInfo1, int nPlotType2, DWORD dwAuxTypeInfo2, bool bIgnoreColorSize = false)
	{
		DWORD	dw1 = dwAuxTypeInfo1 & ~PCD_LTPLOTINFO_HAS_NEXVAL;
		DWORD	dw2 = dwAuxTypeInfo2 & ~PCD_LTPLOTINFO_HAS_NEXVAL;
		if(nPlotType1 != nPlotType2)
			return false;
		if(bIgnoreColorSize) 
		{
			dw2 = dw2 & ~(PCD_MODIFIER_SIZE | PCD_MODIFIER_COLOR | PCD_EXACT_YCOLS);
			dw1 = dw1 & ~(PCD_MODIFIER_SIZE | PCD_MODIFIER_COLOR | PCD_EXACT_YCOLS);
		}
		///Sophy 8/18/2010 ORG-826-P3 PROPER_FILTER_PLOTTYPES_ON_SELECT_PLOT_CHANGE
		//I notice that GraphLayer::GetLayerContents and Project.GetPlotTypeInfo use different code to get auxtype information of dataplot
		//one call COKPlotObj::GetAuxPlotTypeInfo and the other call LABUTIL_ok_get_plot_designation_str in VC level, and there two
		//return value is different in PCD_NO_X | PCD_LAYER_3D when is IDM_PLOT_3D_MESH type, as a OC workaround for Plot Setup dialog, the following code seems enough
		//what's more, change the return value of COKPlotObj::GetAuxPlotTypeInfo seems too dangerous
		if ( nPlotType1 == IDM_PLOT_3D_MESH )
		{
			if ( (dw2 & PCD_ONLY_ONE_Z) && (dw1 & PCD_ONLY_ONE_Z) )
			{
				dw1 = dw1 & ~(PCD_NO_X | PCD_LAYER_3D);
				dw2 = dw2 & ~(PCD_NO_X | PCD_LAYER_3D);
			}
		}
		///end PROPER_FILTER_PLOTTYPES_ON_SELECT_PLOT_CHANGE
		if(dw1 == dw2)
			return true;
		
#ifdef _DEBUG_PLOT_TYPE
		if(bIgnoreColorSize)
			printf("when bIgnoreColorSize, Plot Type dwAuxTypeInfo diff, %X vs %X\n", dw1, dw2);
		else
			printf("Plot Type dwAuxTypeInfo diff, %X vs %X\n", dw1, dw2);
#endif //#ifdef _DEBUG_PLOT_TYPE

		return false;
	}
	///Sophy 8/3/2010 ORG-681-P2 PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
	//void updatePlotTypeList(int nPageType, int nPlotID = 0, int nPlotExVal = 0, DWORD dwAuxTypeInfo = 0, DWORD dwLTPlotInfo = 0)
	void updatePlotTypeList(int nPageType, int nPlotID = 0, int nPlotExVal = 0, DWORD dwAuxTypeInfo = 0, DWORD dwLTPlotInfo = 0, BOOL bMatrixSeries = FALSE)
	///end PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
	{
		//printf("page %d, layer %d, plot %d\n", nPageType, HIWORD(m_dwLayerBits), nPlotID);
		
		vector<uint> nWksPlots = {
			IDM_PLOT_LINE,IDM_PLOT_SCATTER,IDM_PLOT_LINESYMB,
			IDM_PLOT_COLUMN,IDM_PLOT_AREA,IDM_PLOT_AREA_STACK, ///Jasmine 01/22/2009 QA80-12738 ALLOW_AREA_STACK_FOR_PS
			IDM_PLOT_FILL_COLOR_BAND,IDM_PLOT_HILOCLOSE,
			IDM_PLOT_COLUMN_FLOAT,IDM_PLOT_VECTOR,IDM_PLOT_FLOWVECTOR, IDM_PLOT_INDEX_SIZE, IDM_PLOT_INDEX_COLOR, IDM_PLOT_INDEX_SIZE_COLOR, 
			IDM_PLOT_PIE_TYPE, IDM_PLOT_BAR,IDM_PLOT_COLUMN_STACK, IDM_PLOT_BAR_STACK, 
			IDM_PLOT_TRI_CONTOUR,		///Jasmine 04/05/07 QA80-9560 ADD_XYZ_CONTOUR_TO_PLOT_TYPE_LIST
			IDM_PLOT_BOX, IDM_PLOT_HISTOGRAM_TYPE
		};
		vector<uint> nMatPlots = {
			IDM_PLOT_SURFACE_COLORMAP, IDM_PLOT_SURFACE_COLORFILL, IDM_PLOT_SURFACE_WIREFRAME, IDM_PLOT_SURFACE_BARS,
			IDM_PLOT_3D_SCATTER_MATRIX, ///Sophy 8/12/2010 ORG-797-P1 ADD_MATRIX_3D_SCATTER_TO_PLOT_TYPE_LIST
			IDM_PLOT_CONTOUR,IDM_PLOT_MATRIX_IMAGE};
		vector<uint> nDatasetPlots = {IDM_PLOT_LINE,IDM_PLOT_SCATTER,IDM_PLOT_LINESYMB}; 
		//vector<uint> n3DScatterPlots = {ID_3D_GRAPH_SCATTER, ID_3D_GRAPH_TRAJECTORY};
		///Sophy 9/10/2010 ORG-789 CREATE_3D_SCATTER_WITH_ERR_BAR_OR_VECTOR_IN_PLOT_SETUP_DIALOG
#ifndef	__ZERROR_DESIG_IN_PLOT_SETUP_DLG__
		vector<uint> n3DScatterPlots = {IDM_PLOT_3D_LINE, IDM_PLOT_3D_INDEX_SIZE, IDM_PLOT_3D_INDEX_COLOR, IDM_PLOT_3D_INDEX_SIZE_COLOR};
#else
		vector<uint> n3DScatterPlots = {IDM_PLOT_3D_LINE, IDM_PLOT_3D_INDEX_SIZE, IDM_PLOT_3D_INDEX_COLOR, IDM_PLOT_3D_INDEX_SIZE_COLOR, IDM_PLOT_3D_SCATTER_ERR};
#endif	//__ZERROR_DESIG_IN_PLOT_SETUP_DLG__
		///end CREATE_3D_SCATTER_WITH_ERR_BAR_OR_VECTOR_IN_PLOT_SETUP_DIALOG
		vector<uint> nPolarSmithTernaryPlots = {IDM_PLOT_LINE,IDM_PLOT_SCATTER,IDM_PLOT_LINESYMB,IDM_PLOT_INDEX_SIZE, IDM_PLOT_INDEX_COLOR, IDM_PLOT_INDEX_SIZE_COLOR,IDM_PLOT_FLOWVECTOR, IDM_PLOT_COLUMN, 
												IDM_PLOT_TRI_CONTOUR		///Jasmine 09/23/08 QA80-12247-P1
/// Fisher 04/28/2009 QA80-2935 ADD_TERNARY_CONTOUR_PLOT
#ifdef TERNARY_CONTOUR_PLOT_81
												,IDM_PLOT_TERNARY_CONTOUR
#endif	// TERNARY_CONTOUR_PLOT_81
/// End ADD_TERNARY_CONTOUR_PLOT
												};
		//vector<uint> nFuncPlots = {IDM_FUNCS_PLOT};
		vector<uint> n3DXYYPlots = {IDM_PLOT_3D_BAR, IDM_PLOT_3D_RIBBON, IDM_PLOT_3D_WALL};
		
		///Sophy 8/3/2010 ORG-681-P2 PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
		vector<uint> vnVirtualMatrix = {
			IDM_PLOT_3D_MESH,
			IDM_PLOT_3D_SCATTER_MATRIX,	///Sophy 8/12/2010 ORG-797-P1 ADD_MATRIX_3D_SCATTER_TO_PLOT_TYPE_LIST
			IDM_PLOT_CONTOUR
			//IDM_PLOT_TRI_CONTOUR,
			//IDM_PLOT_TERNARY_CONTOUR
		};
		///end PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
		
		if(EXIST_WKS == nPageType || EXIST_EXTERN_WKS == nPageType)
		{
			bool b3D = false;
			if(isTargetXYZLayer(b3D))
			{
				if(b3D)
					m_vnPlotTypes = n3DScatterPlots;
				else
					m_vnPlotTypes = nPolarSmithTernaryPlots;
			}
			else if (m_dwLayerBits == PCD_LAYER_POLAR)
				m_vnPlotTypes = nPolarSmithTernaryPlots;
			else if (m_dwLayerBits == PCD_LAYER_SMITH)
				m_vnPlotTypes = nPolarSmithTernaryPlots;
			else if (m_dwLayerBits == PCD_LAYER_3D_XYY)
				m_vnPlotTypes = n3DXYYPlots;
			else
				m_vnPlotTypes = nWksPlots;
			}
		else if(EXIST_MATRIX == nPageType)
			m_vnPlotTypes = nMatPlots;
		else
		{
			///Sophy 8/3/2010 ORG-681-P2 PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
			//m_vnPlotTypes = nDatasetPlots;
			if ( bMatrixSeries )
				m_vnPlotTypes = vnVirtualMatrix;
			else
				m_vnPlotTypes = nDatasetPlots;
			///end PROPER_SHOW_VIRTUAL_MATRIX_SERIES_INFO_IN_PLOTSETUP_DLG
		}

		
		///Sophy 8/18/2010 ORG-826-P3 PROPER_FILTER_PLOTTYPES_ON_SELECT_PLOT_CHANGE
		//int nIndexInList = removeInvalidPlotTypes(m_vnPlotTypes, nPlotID, dwAuxTypeInfo);
		int nIndexInList = removeInvalidPlotTypes(m_vnPlotTypes, nPlotID, dwAuxTypeInfo, dwLTPlotInfo);
		///end PROPER_FILTER_PLOTTYPES_ON_SELECT_PLOT_CHANGE
		
		//---- CPY 10/7/03 QA70-5309 v7.5714 CUSTOM_PLOT_TYPE_BROKEN_BY_END_EDIT
		//m_nCustomPlotID = 0;
		if(nPlotID)
			m_nCustomPlotID = 0;
		//----
		
		if(nPlotID && nIndexInList < 0)
		{
			m_nCustomPlotID = ConvertPlotIds(nPlotID, &dwAuxTypeInfo);//nPlotID;
			m_nCustomPlotExVal = nPlotExVal;
			m_nSelPlotType = nPlotID;
			m_dwAuxTypeInfo = dwAuxTypeInfo;// CPY 8/26/03 SPECIAL_PLOT_TYPES_SUPPORT, we first store m_nSelPlotType and m_dwAuxTypeInfo with plot type info, then if not in list check m_nCustomPlotID 
		}
		
		if(m_nCustomPlotID && m_nCustomPlotID != IDM_PLOT_UNKNOWN && (m_nCustomPlotExVal || isPlotTypeSpecial(m_nCustomPlotID, m_vnPlotTypes)))
		{
			m_nSelPlotType = IDM_PLOT_CUSTOM;
			m_dwAuxTypeInfo = 0;
			m_vnPlotTypes.InsertAt(0, IDM_PLOT_CUSTOM);
			nIndexInList = 0;
		}
		//else	///Jasmine 05/28/07 QA70-6714 REMEMBER_CUSTOM_PLOT_ID, don't know why reset here
			//m_nCustomPlotID = 0;
		
		Update();
		checkSelPlotType(nIndexInList, dwLTPlotInfo);
	}
	bool checkSelPlotType(int nIndexInList, DWORD dwLTPlotInfo = 0, bool bAlsoCheckBaseType = true, bool bSet1stIfNone = true)
	{
		if(!HasRows())
			return false;
		
		//----- CPY QA70-5134 9/22/03 v7.5701 BUBBLE_PLOT_EDIT_SEL_LINE
		if(nIndexInList >= 0)
		{
			m_nSelPlotType = GetPlotTypeByIndex(nIndexInList);
			m_dwAuxTypeInfo = 0;
			SelRow(nIndexInList);
			return true;
		}
		//-----
		
		//int nRow = findPlotTypeRow(m_nSelPlotType);
		////----- CPY 8/26/03 SPECIAL_PLOT_TYPES_SUPPORT
		////DWORD	dwAuxTypeInfoPlotTypeBits = m_dwAuxTypeInfo & PCD_PLOT_TYPE_AUX_BITS;
		////int		nPlotTypeSearch = ConvertPlotIds(m_nSelPlotType, &dwAuxTypeInfoPlotTypeBits);
		//int		nPlotTypeSearch = ConvertPlotIds(m_nSelPlotType, &m_dwAuxTypeInfo); 
		////----- end SPECIAL_PLOT_TYPES_SUPPORT
		int		nPlotTypeSearch = ConvertPlotIds(m_nSelPlotType, &m_dwAuxTypeInfo, &dwLTPlotInfo); 

		int nRow = findPlotTypeRow(nPlotTypeSearch); 
		if(nRow >= 0)
			SelRow(nRow);
		else if(bAlsoCheckBaseType)
		{
			if(m_nSelPlotType >0 && (nRow = findPlotTypeRow(m_nSelPlotType, true)) >= 0)
				SelRow(nRow);
			else
			{
				if(bSet1stIfNone)
				{
				//	out_int("Cannot find sel plot type, setting it to 1st:", m_nSelPlotType);
					m_nSelPlotType = GetPlotTypeByIndex();
					m_dwAuxTypeInfo = 0;
					return checkSelPlotType(-1, dwLTPlotInfo, true, false);
				}
				out_str("Error, Cannot find sel plot type at all!");				
				return false;
			}
		}
		return true;
	}
	uint getSelPlotID(int* pPlotExVal = NULL)
	{
		uint nPlotID = 0;
		int	nPlotExVal = 0;
		int nRow = GetSelectedRow();
		if(nRow >= 0)
		{
			uint nPlotType;
			int nn = GetRowData(nRow);
			if(0 == nn)
			{
				out_str("Err, we should never come here, better get out");
				return 0;
			}
			m_nSelPlotType = nn;
			if(IDM_PLOT_CUSTOM == m_nSelPlotType)
			{
				nPlotExVal = m_nCustomPlotExVal;
				nPlotID = m_nCustomPlotID;
				m_dwAuxTypeInfo = 0;
			}
			else
			{
				nPlotID = m_nSelPlotType;
				getPlotType(nPlotID, &m_dwAuxTypeInfo);
			}
		}
		if(pPlotExVal)
			*pPlotExVal = nPlotExVal;
		return nPlotID;
	}
	uint getPlotType(uint nPlotID, DWORD* pdwAuxTypeInfo = NULL)
	{
		DWORD dwAuxTypeInfo = 0, dwPlotInto = 0;
		string strColPattern;
		//---- CPY 9/9/03 v7.5689 TERNARY_PLOT_USE_2D_TYPES
		//uint nPlotType = Project.GetPlotTypeInfo(nPlotID, dwAuxTypeInfo, dwPlotInto, strColPattern);
		uint nPlotType = get_plot_type_info(nPlotID, m_nCurrentDataPageType, m_dwLayerBits, dwAuxTypeInfo, dwPlotInto, strColPattern);
		//----
		if(pdwAuxTypeInfo)
			*pdwAuxTypeInfo = dwAuxTypeInfo;
		return nPlotType;
	}
	string getPlotTypeStr(uint nPlotType)
	{
		if(IDM_PLOT_CUSTOM == nPlotType)
		{
			string str = "(";
			str += GetPlotTypeName(getPlotType(m_nCustomPlotID));
			str += ")";
			return str;
		}
		return GetPlotTypeName(nPlotType);
	}
	int findPlotTypeRow(int nPlotType, bool bBaseType = false)
	{
		int nBaseType = get_base_plot_type(nPlotType);
		
		for(int nRow = m_flx.FixedRows; nRow < m_flx.Rows; nRow++)
		{
			DWORD dw = GetRowData(nRow);
			if(bBaseType)
			{
				if(get_base_plot_type(dw) == nBaseType)
					return nRow;
			}
			else if(dw == nPlotType)
				return nRow;
		}
		return -1;
	}
	bool isTargetXYZLayer(bool& is3D)
	{
		if(PCD_LAYER_TRI == m_dwLayerBits || PCD_LAYER_3D == m_dwLayerBits)
		{
			is3D = (PCD_LAYER_3D == m_dwLayerBits)? true:false;
			return true;
		}
		return false;
	}
	//return index in list if nPlotTypeCheckCompatible > 0 and is in vnPlotTypes
	//return -1 if not in list
	///Sophy 8/18/2010 ORG-826-P3 PROPER_FILTER_PLOTTYPES_ON_SELECT_PLOT_CHANGE
	//int removeInvalidPlotTypes(vector<uint>& vnPlotTypes, int nPlotTypeCheckCompatible = 0, DWORD dwAuxTypeInfoCheckCompatible = 0)
	int removeInvalidPlotTypes(vector<uint>& vnPlotTypes, int nPlotTypeCheckCompatible = 0, DWORD dwAuxTypeInfoCheckCompatible = 0, DWORD dwLTPlotInfo = 0)
	///end PROPER_FILTER_PLOTTYPES_ON_SELECT_PLOT_CHANGE
	{
		DWORD dwAuxTypeInfo;
		int nPlotType = 0;
		int nInListIndex = -1;
		for(int ii = 0; ii < vnPlotTypes.GetSize(); ii++)
		{
			dwAuxTypeInfo = 0;
			nPlotType = getPlotType(vnPlotTypes[ii], &dwAuxTypeInfo);
			
#ifdef _DEBUG_PLOT_TYPE
			printf("PlotID(%d) -> %d %X, %X\n", vnPlotTypes[ii], nPlotType, dwAuxTypeInfo, (dwAuxTypeInfo & MASK_PCD_LAYER_BITS));
#endif
			if(nInListIndex < 0 && isPlotTypesTheSame(nPlotTypeCheckCompatible, dwAuxTypeInfoCheckCompatible, nPlotType, dwAuxTypeInfo))
			{
				///Sophy 8/18/2010 ORG-826-P3 PROPER_FILTER_PLOTTYPES_ON_SELECT_PLOT_CHANGE
				//nInListIndex = ii;
				if ( nPlotTypeCheckCompatible == IDM_PLOT_3D_MESH )
				{
					int nConvertedID = ConvertPlotIds(nPlotType, &dwAuxTypeInfo, &dwLTPlotInfo);
					if ( nConvertedID == vnPlotTypes[ii] )
						nInListIndex = ii;
				}
				else
				{
					nInListIndex = ii;
				}
				///end PROPER_FILTER_PLOTTYPES_ON_SELECT_PLOT_CHANGE
				continue;
			}
				
			DWORD	dwThisLayerBitsTest;
			DWORD	dwAuxBitsTest;
			if(!is_layer_type_compatible(m_dwLayerBits, dwAuxTypeInfo & MASK_PCD_LAYER_BITS, vnPlotTypes[ii]) || 
				is_plot_type_incompatible(nPlotTypeCheckCompatible, dwAuxTypeInfoCheckCompatible, nPlotType, dwAuxTypeInfo))
			{
				vnPlotTypes.RemoveAt(ii);
				ii--;
			}
		}
		return nInListIndex;
	}
	DWORD getLayerBitsIgnoreExchange(DWORD dwLayerBits, bool bIgnorePolarSmith = true)
	{
		if(PCD_LAYER_EXCHANGE == dwLayerBits)
			return 0;
		if(bIgnorePolarSmith && dwLayerBits >= PCD_LAYER_POLAR && dwLayerBits <= PCD_LAYER_SMITH)
			return 0;
		return dwLayerBits;
	}
	bool is_layer_type_compatible(DWORD dwTargetLayerBits, DWORD dwPlotTypeBits, int nPlotType)
	{
		// PCD_LAYER_EXCHANGE is necessary to allow editing of scatter and other dataplots
		// when X-Y are reversed (otherwise there is no match).
		//-------- CPY 9/20/03 MATRIX_SEL_SEE_3D_PLOTS_IN_2D_LAYERS
		//DWORD dwTarget = dwTargetLayerBits & ~PCD_LAYER_EXCHANGE;
		//DWORD dwPlot = dwPlotTypeBits & ~PCD_LAYER_EXCHANGE;
		//if(dwTarget >= PCD_LAYER_POLAR && dwTarget <= PCD_LAYER_SMITH) dwTarget = 0;// basic xy 
		//if(dwPlot >= PCD_LAYER_POLAR && dwPlot <= PCD_LAYER_SMITH) dwPlot = 0;// basic xy
		DWORD dwTarget = getLayerBitsIgnoreExchange(dwTargetLayerBits);
		DWORD dwPlot = getLayerBitsIgnoreExchange(dwPlotTypeBits);
		//-------- MATRIX_SEL_SEE_3D_PLOTS_IN_2D_LAYERS
		
		if (dwTarget != dwPlot)
			return false;
			
		// some layer has additional type that they don't support
		if(PCD_LAYER_TRI == dwTargetLayerBits || PCD_LAYER_SMITH == dwTargetLayerBits)
		{
			if(IDM_PLOT_COLUMN == nPlotType)
				return false;
			if(PCD_LAYER_TRI == dwTargetLayerBits && IDM_PLOT_FLOWVECTOR == nPlotType)
				return false;
		}
		return true;
	}
	bool is_plot_type_incompatible(int nPlotTypeTest, DWORD dwAuxTypeInfoTest, int nPlotType, DWORD dwAuxTypeInfo)
	{
		if( 0 == nPlotTypeTest )
			return false;
		
		if ( nPlotTypeTest == nPlotType )
		{
			if(isPlotTypesTheSame(nPlotTypeTest, dwAuxTypeInfoTest, nPlotType, dwAuxTypeInfo, true))
				return false;
			return true;// same bPlotType, but not the same dwAuxTypeInfo, must be incompatible
		}
		return compare_plot_types(nPlotTypeTest, nPlotType) == 0? true:false;
	}
	bool is_page_type_incompatible(int nPageTypeTest, int nPageType)
	{
		if( 0 == nPageTypeTest )
			return false; // not specified is OK
		
		if( EXIST_MATRIX == nPageTypeTest && nPageType != EXIST_MATRIX)
			return true;
		if( nPageTypeTest != EXIST_MATRIX && EXIST_MATRIX == nPageType )
			return true;
		return false;
	}
private:
	vector<uint> m_vnPlotTypes;
	uint		m_nSelPlotType;
	DWORD		m_dwAuxTypeInfo;
	int			m_nCustomPlotID;
	int			m_nCustomPlotExVal;
	int			m_nCustomPlotID_save;
	int			m_nCustomPlotExVal_save;
	Control		m_cntrlStyleHolder;
	DWORD		m_dwLayerBits;
	int			m_nCurrentDataPageType;
	int			m_nEditPlotPageType;
	int			m_nEditPlotType;
	DWORD		m_dwEditAuxTypeInfo;
	bool		m_bAvailDataReady;
};

