#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	scope_active,
	scope_all,
};
#include <..\originlab\palette_utils.h>
//put additional include files here

/***************************************************************************************
/// Modification Log :
*	Kyle 12/10/2008 QA80-12314 ADD_OPTION_TO_CHECK_APPLIED_SCOPE_OF_XF
*	Kyle 09/18/2009 SET_THE_PALETTE_INFO_INTO_THE_COLORMAP
*	Hong 06/30/10 ORG-234-P2 PAL_APPLY_SUPPORT_MATRIX_LAYER_INPUT
*	Kyle 07/02/2010 ORG-234-P2 PAL_LOAD_IS_CALLED_SEVERAL_TIMES
*	CPY 7/1/10 ORG-461 PAL_APPLY_LOGIC_CENTRALIZE
*	Kyle 07/12/2010 ORG-234-P6 SHOW_PROPER_WARNING_MESSAGE_FOR_MATRIX
*	Kyle 07/26/2010 ORG-234-P5 APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
*	Gareth 8/2/2010 ORG-678-S1 ADD_RECENT_FILES_DROPDOWNLIST
*	Kyle 08/27/2010 ORG-234-P10 DISABLE_APPLY_PALETTE_TO_DATA_MATRIX_WHEN_IT_IS_DATA_VIEW_MODE
*	Kyle 08/31/2010 ORG-234-P10 SHOW_ERROR_MESSAGE_ON_NO_ONE_SUCCESS_WHEN_ALL_SELECTED
***************************************************************************************/

//put your own support static functions here
#define PAL_FOLDER_PATH GetOriginPath(ORIGIN_PATH_SYSTEM)+"Palettes\\"

///Gareth 8/2/2010 ORG-678-S1 ADD_RECENT_FILES_DROPDOWNLIST
#define ITEM_SEPARATOR					'|'
#define	STR_ITEM_SEPARATOR				"|"
#define FILE_LIST_SEPARATOR				'\n'
#define STR_PATH_FINAL_BACKSLASH		"\\"


#define		STR_XF_NAME						"palApply"
#define		STR_FILE_LIST					"FileList"

#define		STR_EMPTY_COMBO					" " STR_ITEM_SEPARATOR	
///END ORG-678-S1 ADD_RECENT_FILES_DROPDOWNLIST

static bool _check_for_each_plot(GraphLayer igl, DataPlot dp, string& strErrMsg)
{
	//DataPlot dp = igl.DataPlots(-1);
	if(!dp.IsValid())
	{
		strErrMsg = XFERR_NO_DATA_PLOT;
		return false;
	}
	
	///Sandy 2007-8-7 Comment out the #if & #endif
	///Arvin 08/03/07 WRONG_FUNCTION_NAME
	//if(dp.GetType() == IDM_PLOT_MATRIX_IMAGE)
	int nPlotType;
//#if	_OC_VER >=0x0800
	nPlotType = dp.GetPlotType();
//#else
	//nPlotType = dp.GetType();
//#endif

	if(nPlotType == IDM_PLOT_MATRIX_IMAGE)
	///END 	WRONG_FUNCTION_NAME
	{
		string strName = dp.GetDatasetName();
		
		MatrixObject mImage(strName);
		if(!mImage.IsValid() || !mImage.HasData(false))
		{
			strErrMsg = XFERR_NO_ALLOW_ACCESS_IMAGE_PLOT_COLOR_MAP;
			return false;			
		}
	}
	
	Tree tr;
	if(!dp.GetColormap(tr))
	{
		strErrMsg = XFERR_DATAPLOT_NO_COLOR_MAP;
		return false;		
	}
	
	return true;
}

/// Hong 06/30/10 ORG-234-P2 PAL_APPLY_SUPPORT_MATRIX_LAYER_INPUT
/*
static bool  _check_inputs_valid(TreeNode& trGetN, string& strErrMsg)
{	
	GraphLayer igl;
	okxf_resolve_string_get_origin_object(trGetN.igl.strVal, &igl);
	
	if(!igl.IsValid())
	{
		strErrMsg = XFERR_INVALID_GRAPH_LAYER;
		return false;		
	}
	
	
	///Kyle 12/10/2008 QA80-12314 ADD_OPTION_TO_CHECK_APPLIED_SCOPE_OF_XF
	//foreach(DataPlot dp in igl.DataPlots)
	//{
		//if(!_check_for_each_plot(igl, dp, strErrMsg))
			//return false;
	//}
	if(igl.DataPlots.Count() <=0 )
	{
		strErrMsg = XFERR_NO_DATA_PLOT;
		return false;
	}
	if(trGetN.scope.nVal == scope_all)
	{
		int nPlotsHasColorMap = 0;
		string strTmpErrMsg;
		foreach(DataPlot dp in igl.DataPlots)
		{
			if(_check_for_each_plot(igl, dp, strTmpErrMsg))
				nPlotsHasColorMap++;
		}
		if(nPlotsHasColorMap == 0)
		{
			strErrMsg = strTmpErrMsg;
			return false;
		}
	}
	else
	{
		DataPlot dp;
		dp = igl.DataPlots();
		if(!_check_for_each_plot(igl, dp, strErrMsg))
			return false;
	}
	///End ADD_OPTION_TO_CHECK_APPLIED_SCOPE_OF_XF


	
	vector<int> rgb;
	if(okutil_palette_load(trGetN.fname.strVal, &rgb) < 0 )
	{
		strErrMsg = XFERR_INVALID_PALETTE_FILE;
		return false;
	}
	
	return true;
}
*/
static bool _check_input_graph_valid(GraphLayer& gl, bool bOnlyActive, string& strErrMsg)
{
	if ( !gl )
		return false;
	
	if ( gl.DataPlots.Count() <=0 )
	{
		strErrMsg = XFERR_NO_DATA_PLOT;
		return false;
	}

	if( bOnlyActive )
	{
		DataPlot dp;
		dp = gl.DataPlots();
		if(!_check_for_each_plot(gl, dp, strErrMsg))
			return false;
	}
	else
	{
		int 	nPlotsHasColorMap = 0;
		string 	strTmpErrMsg;
		foreach(DataPlot dp in gl.DataPlots)
		{
			if(_check_for_each_plot(gl, dp, strTmpErrMsg))
				nPlotsHasColorMap++;
		}
		if(nPlotsHasColorMap == 0)
		{
			strErrMsg = strTmpErrMsg;
			return false;
		}
	}
	return true;
}

///Kyle 08/27/2010 ORG-234-P10 DISABLE_APPLY_PALETTE_TO_DATA_MATRIX_WHEN_IT_IS_DATA_VIEW_MODE
static bool _can_apply_palette_to_mat_obj(const MatrixObject& mo)
{
	// has image
	if( !(mo && mo.HasImage()) )
		return false;

	if( mo.HasData(false) )
	{
		return mo.IsImageView();
	}
	else
	{
		return mo.HasPalette();
	}
}
///End DISABLE_APPLY_PALETTE_TO_DATA_MATRIX_WHEN_IT_IS_DATA_VIEW_MODE

static bool _check_input_matrix_valid(MatrixLayer& ml, bool bOnlyActive, string& strErrMsg)
{
	if ( !ml )
		return false;
	
	if ( bOnlyActive )
	{
		MatrixObject	mo = ml.MatrixObjects();
		///Kyle 07/26/2010 ORG-234-P5 APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
		/*
		if ( !mo || !mo.HasData(false) || !mo.HasImage() )
		{
			///Kyle 07/12/2010 ORG-234-P6 SHOW_PROPER_WARNING_MESSAGE_FOR_MATRIX
			//strErrMsg = XFERR_NO_ALLOW_ACCESS_IMAGE_PLOT_COLOR_MAP;
			strErrMsg = XFERR_NO_ALLOW_ACCESS_IMAGE_MATRIX;
			///End SHOW_PROPER_WARNING_MESSAGE_FOR_MATRIX
			return false;			
		}
		*/
		///Kyle 08/27/2010 ORG-234-P10 DISABLE_APPLY_PALETTE_TO_DATA_MATRIX_WHEN_IT_IS_DATA_VIEW_MODE
		//if ( !(mo && mo.HasImage() && (mo.HasData(false) || mo.HasPalette())) )
		if( !_can_apply_palette_to_mat_obj(mo) )
		///End DISABLE_APPLY_PALETTE_TO_DATA_MATRIX_WHEN_IT_IS_DATA_VIEW_MODE
		{
			strErrMsg = mo.HasData(false) ? XFERR_DATA_MATRIX_NO_IMAGE : XFERR_IMAGE_NO_PALETTE;
			return false;
		}
		///End APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
	}
	else
	{
		int 	nPlotsHasColorMap = 0;
		string 	strTmpErrMsg;
		foreach(MatrixObject mo in ml.MatrixObjects)
		{
			///Kyle 07/26/2010 ORG-234-P5 APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
			//if ( mo.HasData(false) && mo.HasImage() )
			///Kyle 08/27/2010 ORG-234-P10 DISABLE_APPLY_PALETTE_TO_DATA_MATRIX_WHEN_IT_IS_DATA_VIEW_MODE
			//if ( mo.HasImage() && (mo.HasData(false) || mo.HasPalette())  )
			if( _can_apply_palette_to_mat_obj(mo) )
			///End DISABLE_APPLY_PALETTE_TO_DATA_MATRIX_WHEN_IT_IS_DATA_VIEW_MODE
			///End APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
				nPlotsHasColorMap++;
		}
		if(nPlotsHasColorMap == 0)
		{
			///Kyle 07/26/2010 ORG-234-P5 APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
			/*
			///Kyle 07/12/2010 ORG-234-P6 SHOW_PROPER_WARNING_MESSAGE_FOR_MATRIX
			//strErrMsg = XFERR_NO_ALLOW_ACCESS_IMAGE_PLOT_COLOR_MAP;
			strErrMsg = XFERR_NO_ALLOW_ACCESS_IMAGE_MATRIX;
			///End SHOW_PROPER_WARNING_MESSAGE_FOR_MATRIX
			*/
			MatrixObject	mo = ml.MatrixObjects();
			strErrMsg = (mo && mo.HasData(false)) ? XFERR_DATA_MATRIX_NO_IMAGE : XFERR_IMAGE_NO_PALETTE;
			///End APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
			return false;
		}
	}
	return true;
}

static bool _check_inputs_valid(TreeNode& trGetN, string& strErrMsg, bool* pbMatrixLayer = NULL)
{	
	Layer		ly;
	okxf_resolve_string_get_origin_object(trGetN.igl.strVal, &ly);
	
	GraphLayer	gl = ly;
	MatrixLayer	ml = ly;
	
	if ( pbMatrixLayer )
		*pbMatrixLayer = ml.IsValid();
	
	if ( !gl && !ml )
	{
		strErrMsg = XFERR_INVALID_LAYER;
		return false;
	}
	bool		bOnlyActive = (scope_active == trGetN.scope.nVal);
	if ( !_check_input_graph_valid(gl, bOnlyActive, strErrMsg) && !_check_input_matrix_valid(ml, bOnlyActive, strErrMsg) )
		return false;
	
	vector<int>	rgb;
	if ( okutil_palette_load(trGetN.fname.strVal, &rgb) < 0 )
	{
		strErrMsg = XFERR_INVALID_PALETTE_FILE;
		return false;
	}
	
	return true;
}

static int _load_palette(vector<int>& rgb, string fname, int flip)
{
	if ( okutil_palette_load(fname, &rgb) < 0 )
	   	return XFERR_INVALID_PALETTE_FILE;
	
	//need to flip
	int nColor = rgb.GetSize();
	if ( flip )
	{
		vector<uint> vOrder(nColor);
		vOrder.Data(nColor-1, 0, -1);
		if(!rgb.Reorder(vOrder))
			return XFERR_FAIL_TO_FLIP_PALETTE_DATA;
	}
	return CER_NO_ERROR;
}
//---- CPY 7/1/10 ORG-461 PAL_APPLY_LOGIC_CENTRALIZE
//static void _prepare_fill_color(vector<uint>& vzColors, const vector<int>& rgb, int stretch)
// added vzLevels
// added bzLevelsHasExtraVal, since DataPlot zLevels has one extra value due to SetColormap and GetColormap method, while pure theme access does not
// change return from void to int
// change nLevel -> nColors
// change nColor -> nPalColors
//return size of vzColors if success, return <0 error code if failed
//----
static int _prepare_fill_color(const vector& vzLevels, vector<uint>& vzColors, const vector<int>& rgb, int stretch, bool bzLevelsHasExtraVal = true)
{
	//---- CPY 7/1/10 ORG-461 PAL_APPLY_LOGIC_CENTRALIZE
	//int			nLevels = vzColors.GetSize();
	//int			nColor = rgb.GetSize();
	int				nPalColors = rgb.GetSize();
	int				nColors = bzLevelsHasExtraVal? vzLevels.GetSize()-1 : vzLevels.GetSize();// number of colors is one less then number of z values for DataPlot GetColormap,SetColormap case
	vzColors.SetSize(nColors); 
	int 			nc = 0;
	//----
	///need to stretch
	if(stretch && nPalColors != nColors)//if(stretch)
	{
		if(nPalColors >= nColors)
		{
			int nSkip = max(nPalColors/nColors,1);
			for(int ii = 0; ii < nColors; ii++)
			{
				nc = (nc >= nPalColors ? 0:nc);
				vzColors[ii] = RGB2OCOLOR(rgb[nc]);
				nc+=nSkip;
			}
		}
		else
		{
			int nRepeat = nColors/nPalColors + 1;
			for(int ii = 0; ii < nColors; ii++)
			{
				nc = ii/nRepeat;
				vzColors[ii] = RGB2OCOLOR(rgb[nc]);
			}
		}
	}
	else
	{
		for(int ii = 0; ii < nColors; ii++)
		{
			nc = (nc >= nPalColors ? 0:nc);
			vzColors[ii] = RGB2OCOLOR(rgb[nc]);
			nc++;
		}
	}
	return vzColors.GetSize();//---- CPY 7/1/10 ORG-461 PAL_APPLY_LOGIC_CENTRALIZE, added this return
}

///Kyle 07/26/2010 ORG-234-P5 APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
/*
static int matrix_set_colormap(MatrixObject& mo, TreeNode& trFmt, const vector& vZLevels, const vector<uint>& vnFillColors, uint ncAbove, uint ncBelow)
{
	if ( !mo )
		return -1;
	
	//---- CPY 7/1/10 ORG-461 PAL_APPLY_LOGIC_CENTRALIZE, should not copy dataplot_set_colormap logic here since dataplot SetColormap method is not consistent with theme access to colormap 
	//if(vZLevels.GetSize() != vnFillColors.GetSize() + 1)
	if(vZLevels.GetSize() != vnFillColors.GetSize())
	//----
		return -2;

	trFmt.Root.ColorMap.Details.Levels.dVals = vZLevels; 
	trFmt.Root.ColorMap.Details.BelowColor.nVal = ncBelow; 
	trFmt.Root.ColorMap.Details.AboveColor.nVal = ncAbove; 
	trFmt.Root.ColorMap.Details.Colors.nVals = vnFillColors;
	if ( !mo.ApplyFormat(trFmt, true, true) )
		return -3;
	
	return 0;
}
*/
///End APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE

///Kyle 07/02/2010 ORG-234-P2 PAL_LOAD_IS_CALLED_SEVERAL_TIMES
//static int _do_palApply_for_matrix_object(MatrixObject& mo, string fname, int stretch, int flip)
///Kyle 07/26/2010 ORG-234-P5 APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
//static int _do_palApply_for_matrix_object(MatrixObject& mo, string fname, const vector<int> rgb, int stretch)
static int _do_palApply_for_matrix_object(MatrixObject& mo, string fname, int stretch, int flip)
///End APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
///End PAL_LOAD_IS_CALLED_SEVERAL_TIMES
{
	ASSERT(mo);
	///Kyle 08/27/2010 ORG-234-P10 DISABLE_APPLY_PALETTE_TO_DATA_MATRIX_WHEN_IT_IS_DATA_VIEW_MODE
	if( mo.HasData(false) && !mo.IsImageView() )
		return XFERR_DATA_MATRIX_NO_IMAGE;
	///End DISABLE_APPLY_PALETTE_TO_DATA_MATRIX_WHEN_IT_IS_DATA_VIEW_MODE
	
	///Kyle 07/26/2010 ORG-234-P5 APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
	/*
	Tree		trFmt;
	trFmt = mo.GetFormat(FPB_ALL, FOB_ALL, true, true);
	TreeNode	trClrMap = trFmt.Root.ColorMap;
	if ( !trClrMap )
		///Kyle 07/12/2010 ORG-234-P6 SHOW_PROPER_WARNING_MESSAGE_FOR_MATRIX
		//return XFERR_DATAPLOT_NO_COLOR_MAP;
		return XFERR_MATRIX_OBJ_NO_COLOR_MAP;
		///End SHOW_PROPER_WARNING_MESSAGE_FOR_MATRIX
	
	foreach ( TreeNode trNode in trFmt.Root.Children )
	{
		if ( trClrMap.tagName != trNode.tagName )
			trNode.Remove();
	}
	
	vector		vLevels;
	vLevels = trClrMap.Details.Levels.dVals;
	*/
	DWORD dwCntrl = (flip ? MOPAL_REVERSE : 0) | (stretch ? MOPAL_STRETCH : MOPAL_BY_ONE);
	int nRet = mo.ApplyPalette(fname, dwCntrl);
	if( nRet )
		return mo.HasData() ? XFERR_DATA_MATRIX_NO_IMAGE : XFERR_IMAGE_NO_PALETTE;
	return 0;
	///End APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE

	///Kyle 07/02/2010 ORG-234-P2 PAL_LOAD_IS_CALLED_SEVERAL_TIMES
	/*
	vector<int> rgb;
	int			nErr = _load_palette(rgb, fname, flip);
	if ( CER_NO_ERROR != nErr )
		return nErr;
	*/
	///End PAL_LOAD_IS_CALLED_SEVERAL_TIMES
	//---- CPY 7/1/10 ORG-461 PAL_APPLY_LOGIC_CENTRALIZE
	/*
	int			nLevel = vLevels.GetSize();
	vector<uint> vzColors(nLevel);
	_prepare_fill_color(vzColors, rgb, stretch);
	
	trFmt.Root.ColorMap.Palette.strVal = fname;

	if ( 0 != matrix_set_colormap(mo, trFmt, vLevels, vzColors, vzColors[nLevel - 1], vzColors[0]) )
		return XFERR_FAIL_TO_APPLY_PALETTE_TO_DATAPLOT;

	return CER_NO_ERROR;
	*/
	///Kyle 07/26/2010 ORG-234-P5 APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
	/*
	vector<uint> vzColors;
	int nColors = _prepare_fill_color(vLevels, vzColors, rgb, stretch, false);
	if(nColors < 0)
		return nColors;//must return size of vzColors if success
	trFmt.Root.ColorMap.Palette.strVal = fname;
	return matrix_set_colormap(mo, trFmt, vLevels, vzColors, vzColors[nColors - 1], vzColors[0]);
	*/
	///End APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
	//---- end PAL_APPLY_LOGIC_CENTRALIZE
}
/// end PAL_APPLY_SUPPORT_MATRIX_LAYER_INPUT

///Kyle 12/10/2008 QA80-12314 ADD_OPTION_TO_CHECK_APPLIED_SCOPE_OF_XF, centralized from the body function
///Kyle 07/02/2010 ORG-234-P2 PAL_LOAD_IS_CALLED_SEVERAL_TIMES
//static int _do_palApply_for_each_plot(DataPlot& dp, string fname, int stretch, int flip)
static int _do_palApply_for_each_plot(DataPlot& dp, string fname, const vector<int>& rgb, int stretch)
///End PAL_LOAD_IS_CALLED_SEVERAL_TIMES
{
	if(!dp.IsValid())
		return XFERR_NO_DATA_PLOT;

	///get level from dataplot
	vector vLevels;
	if(!dp.GetColormap(vLevels, FALSE))
		return XFERR_DATAPLOT_NO_COLOR_MAP;
	//---- CPY 7/1/10 ORG-461 PAL_APPLY_LOGIC_CENTRALIZE
	/*
	int nLevel = vLevels.GetSize();
	vector<uint> vzColors(nLevel - 1);
	_prepare_fill_color(vzColors, rgb, stretch);
	
	///Kyle 09/18/2009 SET_THE_PALETTE_INFO_INTO_THE_COLORMAP
	Tree tr;
	tr.ColorMap.Palette.strVal = fname;
	dp.SetColormap(tr);
	///End SET_THE_PALETTE_INFO_INTO_THE_COLORMAP
	
	///Update the color map tree
	if(0 != dataplot_set_colormap(dp, vLevels, vzColors, vzColors[nLevel - 2], vzColors[0]))
		return XFERR_FAIL_TO_APPLY_PALETTE_TO_DATAPLOT;
	return CER_NO_ERROR;
	*/
	vector<uint> vzColors;
	int nColors = _prepare_fill_color(vLevels, vzColors, rgb, stretch);
	if(nColors < 0)
		return nColors;//must return size of vzColors if success
	
	Tree tr;tr.ColorMap.Palette.strVal = fname; dp.SetColormap(tr);///Kyle 09/18/2009 SET_THE_PALETTE_INFO_INTO_THE_COLORMAP
	if(dataplot_set_colormap(dp, vLevels, vzColors, vzColors[nColors - 1], vzColors[0]) != 0)
		return XFERR_FAIL_TO_APPLY_PALETTE_TO_DATAPLOT;
	return CER_NO_ERROR;
	//---- end PAL_APPLY_LOGIC_CENTRALIZE
}
///End ADD_OPTION_TO_CHECK_APPLIED_SCOPE_OF_XF

///Gareth 8/2/2010 ORG-678-S1 ADD_RECENT_FILES_DROPDOWNLIST
static	bool	_load_recent_file_list(string& strRecentFileList)
{
	bool			bRet = dlg_load_registry(STR_XF_NAME, STR_FILE_LIST, strRecentFileList);

	return bRet;
}

static	void	_check_update_recent_file_list(string& strRecentFileList)
{
	vector<string>	vsRecentFiles;
	strRecentFileList.GetTokens(vsRecentFiles, ITEM_SEPARATOR);
	
	for ( int ii=vsRecentFiles.GetSize() - 1; ii>=0; --ii )
	{
		if ( !vsRecentFiles[ii].IsFile() )
			vsRecentFiles.RemoveAt(ii);
	}
	
	strRecentFileList.SetTokens(vsRecentFiles, ITEM_SEPARATOR);
}

static	void	_check_append_pipe_char(string& str)
{
	if ( str.IsEmpty() )
		str = STR_EMPTY_COMBO;
	
	if ( str.Find(ITEM_SEPARATOR) < 0 )
		str += STR_ITEM_SEPARATOR;
}
static void _save_recent_files_to_registry(string fname)
{
	///Gareth 8/2/2010 ORG-678-S1 ADD_RECENT_FILES_DROPDOWNLIST
	string		strRecentFileList;
	_load_recent_file_list(strRecentFileList);
	
	vector<string>	vsRecentFiles;
	strRecentFileList.GetTokens(vsRecentFiles, ITEM_SEPARATOR);
	int		nIndex = -1;
	if ( (nIndex = vsRecentFiles.Find(fname)) >= 0 )
	{
		vsRecentFiles.RemoveAt(nIndex);
	}
	vsRecentFiles.InsertAt(0, fname);	
	strRecentFileList.SetTokens(vsRecentFiles, ITEM_SEPARATOR);
	dlg_save_to_registry(STR_XF_NAME, STR_FILE_LIST, strRecentFileList);

}
///END ADD_RECENT_FILES_DROPDOWNLIST

void palApply(const Layer& igl, const string& fname, const int& stretch, const int& flip, const int& scope)
{
	
	vector<int> rgb;
	///Kyle 07/02/2010 ORG-234-P2 PAL_LOAD_IS_CALLED_SEVERAL_TIMES
	//if(okutil_palette_load(fname, &rgb) < 0 )
	//   	XF_THROW(XFERR_INVALID_PALETTE_FILE);
	int nErrCode = _load_palette(rgb, fname, flip);
	if ( CER_NO_ERROR != nErrCode )
		XF_THROW(nErrCode);
	///End PAL_LOAD_IS_CALLED_SEVERAL_TIMES
	/// Hong 06/30/10 ORG-234-P2 PAL_APPLY_SUPPORT_MATRIX_LAYER_INPUT
	MatrixLayer		ml = igl;	
	GraphLayer		gl = igl;
	ASSERT( ml || gl );
	
	_save_recent_files_to_registry(fname);		///Kyle 08/31/2010 ORG-234-P10 SHOW_ERROR_MESSAGE_ON_NO_ONE_SUCCESS_WHEN_ALL_SELECTED
	
	if ( ml )
	{
		if(scope == scope_all)
		{
			///Kyle 08/31/2010 ORG-234-P10 SHOW_ERROR_MESSAGE_ON_NO_ONE_SUCCESS_WHEN_ALL_SELECTED
			//int nFailed;
			//foreach(MatrixObject mo in ml.MatrixObjects )
			//{
				/////Kyle 07/02/2010 ORG-234-P2 PAL_LOAD_IS_CALLED_SEVERAL_TIMES
				////if(CER_NO_ERROR != _do_palApply_for_matrix_object(mo, fname, stretch, flip))
				/////Kyle 07/26/2010 ORG-234-P5 APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
				////if(CER_NO_ERROR != _do_palApply_for_matrix_object(mo, fname, rgb, stretch))
				//if(CER_NO_ERROR != _do_palApply_for_matrix_object(mo, fname, stretch, flip))
				/////End APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
				/////End PAL_LOAD_IS_CALLED_SEVERAL_TIMES
					//nFailed++;
			//}
			//if(nFailed > 0)
			//{
				/////Kyle 07/26/2010 ORG-234-P5 APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
				///*
				/////Kyle 07/12/2010 ORG-234-P6 SHOW_PROPER_WARNING_MESSAGE_FOR_MATRIX
				////XF_THROW(XFERR_DATAPLOT_NO_COLOR_MAP);
				//XF_THROW(XFERR_MATRIX_OBJ_NO_COLOR_MAP);
				/////End SHOW_PROPER_WARNING_MESSAGE_FOR_MATRIX
				//*/
				//MatrixObject mo = ml.MatrixObjects();
				//int nErrCode = (mo && mo.HasData(false)) ? XFERR_DATA_MATRIX_NO_IMAGE : XFERR_IMAGE_NO_PALETTE;
				//XF_THROW(nErrCode);
				/////End APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
			//}
			int nSuccess = 0;
			foreach(MatrixObject mo in ml.MatrixObjects )
			{
				if(CER_NO_ERROR == _do_palApply_for_matrix_object(mo, fname, stretch, flip))
					nSuccess++;
			}
			if(nSuccess == 0)
			{
				MatrixObject mo = ml.MatrixObjects();
				int nErrCode = (mo && mo.HasData(false)) ? XFERR_DATA_MATRIX_NO_IMAGE : XFERR_IMAGE_NO_PALETTE;
				XF_THROW(nErrCode);
			}
			///End SHOW_ERROR_MESSAGE_ON_NO_ONE_SUCCESS_WHEN_ALL_SELECTED
		}
		else
		{
			MatrixObject	mo;
			mo = ml.MatrixObjects();
			///Kyle 07/02/2010 ORG-234-P2 PAL_LOAD_IS_CALLED_SEVERAL_TIMES
			//int nErrCode = _do_palApply_for_matrix_object(mo, fname, stretch, flip);
			///Kyle 07/26/2010 ORG-234-P5 APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
			//int nErrCode = _do_palApply_for_matrix_object(mo, fname, rgb, stretch);
			int nErrCode = _do_palApply_for_matrix_object(mo, fname, stretch, flip);
			///End APPLY_PALETTE_TO_MTRIX_OBJECT_IMAGE
			///End PAL_LOAD_IS_CALLED_SEVERAL_TIMES
			if(nErrCode != CER_NO_ERROR)
				XF_THROW(nErrCode);
		}
		///Kyle 08/31/2010 ORG-234-P10 SHOW_ERROR_MESSAGE_ON_NO_ONE_SUCCESS_WHEN_ALL_SELECTED, moved up
		// ///Gareth 8/2/2010 ORG-678-S1 ADD_RECENT_FILES_DROPDOWNLIST
		// _save_recent_files_to_registry(fname);
		// ///END ADD_RECENT_FILES_DROPDOWNLIST
		///End SHOW_ERROR_MESSAGE_ON_NO_ONE_SUCCESS_WHEN_ALL_SELECTED
		return ;
	}
	/// end PAL_APPLY_SUPPORT_MATRIX_LAYER_INPUT
	
	if(gl.DataPlots.Count() <= 0)
		XF_THROW(XFERR_NO_DATA_PLOT);
	if(scope == scope_all)
	{
		///Kyle 08/31/2010 ORG-234-P10 SHOW_ERROR_MESSAGE_ON_NO_ONE_SUCCESS_WHEN_ALL_SELECTED
		/*
		int nFailed;
		foreach(DataPlot dp in gl.DataPlots)
		{
			///Kyle 07/02/2010 ORG-234-P2 PAL_LOAD_IS_CALLED_SEVERAL_TIMES
			//if(CER_NO_ERROR != _do_palApply_for_each_plot(dp, fname, stretch, flip))
			if(CER_NO_ERROR != _do_palApply_for_each_plot(dp, fname, rgb, stretch))
			///End PAL_LOAD_IS_CALLED_SEVERAL_TIMES
				nFailed++;
		}
		if(nFailed > 0)
			XF_THROW(XFERR_DATAPLOT_NO_COLOR_MAP);
		*/
		int nSuccess = 0;
		foreach(DataPlot dp in gl.DataPlots)
		{
			if(CER_NO_ERROR == _do_palApply_for_each_plot(dp, fname, rgb, stretch))
				nSuccess++;
		}
		if(nSuccess == 0)
			XF_THROW(XFERR_DATAPLOT_NO_COLOR_MAP);
		///End SHOW_ERROR_MESSAGE_ON_NO_ONE_SUCCESS_WHEN_ALL_SELECTED
	}
	else
	{
		DataPlot dp;
		dp = gl.DataPlots();
		///Kyle 07/02/2010 ORG-234-P2 PAL_LOAD_IS_CALLED_SEVERAL_TIMES
		//int nErrCode = _do_palApply_for_each_plot(dp, fname, stretch, flip);
		int nErrCode = _do_palApply_for_each_plot(dp, fname, rgb, stretch);
		///End PAL_LOAD_IS_CALLED_SEVERAL_TIMES
		if(nErrCode != CER_NO_ERROR)
			XF_THROW(nErrCode);
	}
	///End ADD_OPTION_TO_CHECK_APPLIED_SCOPE_OF_XF
	
	///Kyle 08/31/2010 ORG-234-P10 SHOW_ERROR_MESSAGE_ON_NO_ONE_SUCCESS_WHEN_ALL_SELECTED, moved up
	// ///Gareth 8/2/2010 ORG-678-S1 ADD_RECENT_FILES_DROPDOWNLIST
	// _save_recent_files_to_registry(fname);
	// ///END ADD_RECENT_FILES_DROPDOWNLIST
	///End SHOW_ERROR_MESSAGE_ON_NO_ONE_SUCCESS_WHEN_ALL_SELECTED
	
}

//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 palApply_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return palApply_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	///Gareth 8/2/2010 ORG-678-S1 ADD_RECENT_FILES_DROPDOWNLIST
	//if(nEventID == GETNE_ON_INIT)
	//{	string strFile = PAL_FOLDER_PATH + "grayscale.pal";
		//trGetN.fname.strVal = strFile;
		////tree_set_browse_combo_attrib(trGetN.fname);
	//}
	///END ADD_RECENT_FILES_DROPDOWNLIST
	
	/// Hong 06/30/10 ORG-234-P2 PAL_APPLY_SUPPORT_MATRIX_LAYER_INPUT
	//bOKEnable =  _check_inputs_valid(trGetN, strErrMsg);
	bool		bMatrixLayer = false;
	bOKEnable =  _check_inputs_valid(trGetN, strErrMsg, &bMatrixLayer);
	if ( nEventID == GETNE_ON_INIT )
	{
		trGetN.igl.SetAttribute(STR_LABEL_ATTRIB, bMatrixLayer ? _L("Input Matrix") : _L("Input Graph"));
		trGetN.scope.SetAttribute(STR_COMBO_ATTRIB, bMatrixLayer ? _L("Active Image|All Images") : _L("Active Plot|All Plots"));
	}
	/// end PAL_APPLY_SUPPORT_MATRIX_LAYER_INPUT
	
	string strNode = lpcszNodeName;
	if(bOKEnable && strNode == "fname")
		update_recent_path_list(trGetN.fname.strVal);
	
	return true;

}

int palApply_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	return 0;
}
//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 palApply_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	if ( (dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0 )
	{
		string strErrMsg;
		if ( true != _check_inputs_valid(trGetN, strErrMsg) )
			nRet = XFEVT_PROCEED_WITH_DLG;
	}
	
	///Gareth 8/2/2010 ORG-678-S1 ADD_RECENT_FILES_DROPDOWNLIST
	if ( is_xf_startup(nGetNDialog, dwCntrl) )
	{
		if ( nGetNDialog > 0 )
		{
			string		strRecentFileList;
			_load_recent_file_list(strRecentFileList);
			_check_update_recent_file_list(strRecentFileList);
			_check_append_pipe_char(strRecentFileList);
			
			
			string	strCombo;
			trGetN.fname.GetAttribute(STR_COMBO_ATTRIB, strCombo);
			trGetN.fname.SetAttribute(STR_COMBO_ATTRIB, strCombo + strRecentFileList);
			trGetN.fname.strVal = strRecentFileList.GetToken(0, ITEM_SEPARATOR);
			if(trGetN.fname.strVal == " ")
			{
				string strFile = PAL_FOLDER_PATH + "grayscale.pal";
				if(strFile.IsFile())
				{
					trGetN.fname.strVal = strFile;
				}
			}
		}
	}
	///END ADD_RECENT_FILES_DROPDOWNLIST
}
//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 palApply_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
