#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	option_page,
	option_folder,
	option_recursive,
	option_open,
	option_embed,
	option_project,
	option_specified,
};
enum{
	arrange_vertical,
	arrange_nm,
};
enum{
	embed_embed,
	embed_link,
};
//put additional include files here
#include <..\originlab\theme_utils.h>
//put your own support static functions here
///Folger 05/29/07 ADD_BOOL_ENABLE_EMBED_IN_PAGE_PREVIEW_LIST_DLG
#define	STR_PAGE_LIST_SEPARATOR 	'\n'
#define PAGE_OPTION_OFFSET			0
#define STR_COMBO_EMBED "Active Page|All in Active Folder|All in Active Folder (Recursive)|All in Active Folder (Open)|\
						All in Project|Specified"
#define STR_COMBO_LINK "Active Page|All in Active Folder|All in Active Folder (Recursive)|All in Active Folder (Open)|\
					All in Active Folder (Include Embedded)|All in Project|Specified"
///End ADD_BOOL_ENABLE_EMBED_IN_PAGE_PREVIEW_LIST_DLG


//enum
//{
	//GRAPHS_ALL_FOLDERS,
	//GRAPHS_CURRENT_FOLDER,
	//GRAPHS_ONE_FOLDER_ONE_WKS
//};

//enum 
//{
	//ARRANGE_VERTICALLY,
	//ARRANGE_NM_PANEL,
//};
//
//enum
//{
	//SET_CELL_EMBED,
	//SET_CELL_LINK
//};

//#define	NUM_GRAPH_COL		3

//#define	STR_MSG_BOX_TITLE	"Move Graphs to Worksheet Cells"

//static void _get_page_info(const PageBase& pg, vector<string>& vsDisplayNames, vector<string>& vsNames)
//{
	//if(EXIST_PLOT != pg.GetType())
		//return;
	//
	//string 	strName = pg.GetLongName();
	//if(strName.IsEmpty())
		//strName = pg.GetName();
	//vsDisplayNames.Add(strName);
	//
	//vsNames.Add(pg.GetName());	
//}


static void _prepareWks(Worksheet& ow, int arrange, int cols)
{
	///Folger 06/07/07 CHNAGE_WPG_TO_WKS
	//ow = wpg.Layers(index);
	//if(!ow)
	//{
		//int nLayer = wpg.AddLayer();
		//ow = wpg.Layers(nLayer);
	//}
	///End CHNAGE_WPG_TO_WKS
	// if arrange = 1, then we put graph name in 1st col, 
	// otherwise we put a row of text above each graph with graph names
	if(arrange == arrange_vertical)
		ow.SetSize(-1, 2);
	else
		ow.SetSize(-1, cols);
		
	wks_set_show_labels(ow, RCLT_LONG_NAME);
	if(arrange == arrange_vertical)
	{
		ow.Columns(0).SetLongName("Graph Names");
		ow.Columns(1).SetLongName("Graph Images");
	}
	//ow.Columns(2).SetLongName("Path in PE");
	ow.SetColDesignations("N");
}

static bool _embed(int embedType, Worksheet& ow, int nRow, int nCol, GraphPage& gp)
{
	if(embed_embed == embedType)
	{
		/// TD 10-10-2007 QA80-10510 UNDO_SUPPORT_FOR_ATTACHMENTS_IN_WKS_CELL
		//return ow.EmbedGraph(nRow, nCol, gp);
		return ow.EmbedGraph(nRow, nCol, gp, EMBEDGRAPH_DO_UNDO);
		/// end UNDO_SUPPORT_FOR_ATTACHMENTS_IN_WKS_CELL
	}
	
	//set graph:// to worksheet cell
	string str = "graph://" + gp.GetName();
	ow.SetCell(nRow, nCol, str);
	return true;
	
}
static void _embed_graph_to_wks(int embed, Worksheet& ow, int arrange, const vector<string>& vsDisplayNames, const vector<string>& vsNames)
{	
	int 	nn = vsNames.GetSize();
	for(int ii=0, nRow = 0, nCol = 0; ii<nn; ii++)
	{		
		GraphPage gp(vsNames[ii]);
		if(arrange == arrange_vertical)
		{
			///Folger 06/20/07 ADD_ROWS_WHEN_NEEDED
			if (nRow >= ow.GetNumRows())
			{
				ow.SetSize(nRow + 1, -1);
			}
			///End ADD_ROWS_WHEN_NEEDED
			//ow.EmbedGraph(ii, 1, gp);
			if( _embed(embed, ow, nRow, 1, gp) )
			{
				ow.SetCell(nRow, 0, vsDisplayNames[ii]);
				//ow.SetCell(nRow, 2, vsPaths[ii]); this is not needed anymore as we have saved this inside the cell
				nRow++;
			}
		}
		else // a row of name and then a row of graphs
		{
			//ow.EmbedGraph(nRow+1, nCol, gp);
			///Folger 06/20/07 ADD_ROWS_WHEN_NEEDED
			if (nRow + 1 >= ow.GetNumRows())
			{
				ow.SetSize(nRow + 2, -1);
			}
			///End ADD_ROWS_WHEN_NEEDED
			if( _embed(embed, ow, nRow+1, nCol, gp) )
			{
				ow.SetCell(nRow, nCol, vsDisplayNames[ii]);
				if(nCol < ow.GetNumCols()-1) 
					nCol++;
				else
				{
					wks_set_cell_heights(ow, nRow+1, nRow+1, 600, false);
					nCol = 0;
					nRow += 2;
				}
			}
		}
	}
	if(arrange != arrange_vertical)
		wks_set_cell_heights(ow, nRow+1, nRow+1, 600, false);
	
	//this does not work
	//autosize_rowcol(ow);
	
	if(arrange == arrange_vertical)
	{
		wks_set_cell_heights(ow, 1, 1, 200, true);
		wks_set_cell_heights(ow, 0, nn-1, 600, false);
	}
	else
		wks_set_cell_heights(ow, 0, -1, 200, true);
}

//static void _get_recursive_folders(Folder& fld, vector<string>& vsPath)
//{	
	//vsPath.Add(fld.GetPath());	
	//
	//if(0 != fld.Subfolders.Count())
	//{
		//foreach(Folder subfld in fld.Subfolders)
		//{
			//_get_recursive_folders(subfld, vsPath);
		//}
	//}
//}
///Folger 05/29/07 ADD_BOOL_ENABLE_EMBED_IN_PAGE_PREVIEW_LIST_DLG
static void _get_displaynames(const vector<string> &vsNames, vector<string> &vsDisplayNames)
{
	int nSize = vsNames.GetSize();
	for (int ii=0; ii<nSize; ii++)
	{
		PageBase pb(vsNames[ii]);
		string strName = pb.GetLongName();
		if (strName.IsEmpty())
			strName = vsNames[ii];
		vsDisplayNames.Add(strName);
	}
}

static void _refresh_graphs(TreeNode &trGetN)
{
//	printf ("option = %d\n", trGetN.option.nVal);
	bool bEmbed = trGetN.embed.nVal == embed_embed &&
						   trGetN.option.nVal >= OPTION_ALL_EMBEDDED_IN_ACTIVE_FOLDER;
	vector<string> vsGraphs;
	if (bEmbed) trGetN.option.nVal++;
	int nGraphs = get_folder_pages_name(vsGraphs, trGetN.option.nVal, PAGE_OPTION_OFFSET, trGetN.graphs.strVal);
	trGetN.graphs.strVal.SetTokens(vsGraphs, STR_PAGE_LIST_SEPARATOR);
	Worksheet ow = Project.ActiveLayer();
	if (trGetN.embed.nVal == embed_embed && trGetN.option.nVal == OPTION_ACTIVE_PAGE && ow)
		trGetN.graphs.strVal = "";
	///Kyle 07/16/08 SET_AS_ENABLE_READONLY_SCROLL_WHEN_IT_IS_NOT_SPECIFIED
	//trGetN.graphs.Enable = trGetN.option.nVal == OPTION_SPECIFIED;
	trGetN.graphs.Enable = trGetN.option.nVal == OPTION_SPECIFIED?ENABLE : ENABLE_READONLY_SCROLL;
	///End SET_AS_ENABLE_READONLY_SCROLL_WHEN_IT_IS_NOT_SPECIFIED
	if (bEmbed) trGetN.option.nVal--;
}

static void _refresh_xf(TreeNode &trGetN, bool bEmbed = false)
{
	if (trGetN.embed.nVal == embed_embed)
	{
		trGetN.option.SetAttribute(STR_COMBO_ATTRIB, STR_COMBO_EMBED);
		trGetN.graphs.SetAttribute(STR_ENABLE_EMBED_ATTRIB, 0);
		///Folger 06/21/07 IMPROVE_G2W_CODE
		if (bEmbed && trGetN.option.nVal >= OPTION_ALL_EMBEDDED_IN_ACTIVE_FOLDER)
		{
			trGetN.option.nVal--;
		}
		///End IMPROVE_G2W_CODE
	}
	else
	{
		trGetN.option.SetAttribute(STR_COMBO_ATTRIB, STR_COMBO_LINK);
		trGetN.graphs.SetAttribute(STR_ENABLE_EMBED_ATTRIB, 1);
		///Folger 06/21/07 IMPROVE_G2W_CODE
		if (bEmbed && trGetN.option.nVal >= OPTION_ALL_EMBEDDED_IN_ACTIVE_FOLDER)
		{
			trGetN.option.nVal++;
		}
		///End IMPROVE_G2W_CODE
	}
	_refresh_graphs(trGetN);
}

//static string g_strSpecified;
///End ADD_BOOL_ENABLE_EMBED_IN_PAGE_PREVIEW_LIST_DLG

void g2w(Worksheet& ow, const int& option, const string& graphs, const int& arrange, const double& cols, const int& embed)
{
	///Folger 05/29/07 ADD_BOOL_ENABLE_EMBED_IN_PAGE_PREVIEW_LIST_DLG
	///Folger 06/08/07 REMOVE_REMINDER_MSG
	//if (embed == embed_embed)
	//{
		//if(IDCANCEL == MessageBox(GetWindow(), "Are you sure you want to embed(move) graphs into worksheet cells?", 
						//STR_MSG_BOX_TITLE, MB_OKCANCEL))
		//{
			//ow.Destroy();			
			//return;
		//}
	//}
	///End REMOVE_REMINDER_MSG
	_prepareWks(ow, arrange, cols);
	vector<string> vsDisplayNames, vsNames;
	graphs.GetTokens(vsNames, STR_PAGE_LIST_SEPARATOR);
	_get_displaynames(vsNames, vsDisplayNames);
	_embed_graph_to_wks(embed, ow, arrange, vsDisplayNames, vsNames);
	///End ADD_BOOL_ENABLE_EMBED_IN_PAGE_PREVIEW_LIST_DLG
	//switch(option)
	//{
	//case GRAPHS_CURRENT_FOLDER:
		//Worksheet ow;
		//_prepareWks(wpg, ow, cols);
		//
		//vector<string>		vsDisplayNames, vsNames;
		//Folder				fld = Project.ActiveFolder();
		//foreach(PageBase pg in fld.Pages)
		//{
			//_get_page_info(pg, vsDisplayNames, vsNames);
		//}
		//_embed_graph_to_wks(embed, ow, cols, vsDisplayNames, vsNames);
		//break;
		//
	//case GRAPHS_ALL_FOLDERS:
		//Worksheet ow;
		//_prepareWks(wpg, ow, cols);
		//
		//vector<string>		vsDisplayNames, vsNames;
		////foreach(GraphPage gp in Project.GraphPages)
		////{
			////_get_page_info(gp, vsDisplayNames, vsNames);
		////}
		//foreach(PageBase pg in Project.Pages)
		//{
			//_get_page_info(pg, vsDisplayNames, vsNames);
		//}
		//_embed_graph_to_wks(embed, ow, cols, vsDisplayNames, vsNames);
		//break;
		//
	//case GRAPHS_ONE_FOLDER_ONE_WKS:
		//vector<string> 	vsPath;
		//_get_recursive_folders(Application.RootFolder, vsPath);
		//
		//for(int nn=0; nn<vsPath.GetSize(); nn++)
		//{
			//Worksheet 	ow;
			//_prepareWks(wpg, ow, cols, nn);
	//
			//Folder		fld(vsPath[nn]);
			//vector<string>	vsDisplayNames, vsNames;
			//foreach(PageBase pg in fld.Pages)
			//{
				//_get_page_info(pg, vsDisplayNames, vsNames);
			//}
			//_embed_graph_to_wks(embed, ow, cols, vsDisplayNames, vsNames);
			//
		//}
		//break;
	//}
		
}

//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 g2w_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return g2w_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	///Folger 05/29/07 ADD_BOOL_ENABLE_EMBED_IN_PAGE_PREVIEW_LIST_DLG
	
	trGetN.cols.Show = trGetN.arrange.nVal == arrange_nm;
	
	if (nEventID == GETNE_ON_THEME)
	{
		_refresh_xf(trGetN);
	}
	
	if (nEventID >0)
	{
		if (!lstrcmpi(lpcszNodeName, "option"))
		{
			_refresh_graphs(trGetN);			
		}
		else if (!lstrcmpi(lpcszNodeName, "graphs"))
		{
			vector<string> vsNames;
			trGetN.graphs.strVal.GetTokens(vsNames, STR_PAGE_LIST_SEPARATOR);
			for (int ii=0; ii<vsNames.GetSize(); ii++)
			{
				if (vsNames[ii].IsEmpty())
				{
					vsNames.RemoveAt(ii--);
					continue;
				}
				PageBase pb(vsNames[ii]);
				if (!pb)
				{
					strErrMsg = CER_PAGE_NAME_WRONG;
					bOKEnable = false;
					return false;
				}
			}
			trGetN.graphs.strVal.SetTokens(vsNames, STR_PAGE_LIST_SEPARATOR);
		}
		else if (!lstrcmpi(lpcszNodeName, "embed"))
		{
			///Folger 06/21/07 IMPROVE_G2W_CODE
			trGetN.graphs.strVal = "";
			_refresh_xf(trGetN, true);
			//if (trGetN.embed.nVal == embed_embed)
			//{
				////g_strSpecified = trGetN.graphs.strVal;
				////vector<string> vsNames;
				////trGetN.graphs.strVal.GetTokens(vsNames, STR_PAGE_LIST_SEPARATOR);
				////for (int ii=0; ii<vsNames.GetSize(); ii++)
				////{
					////GraphPage gp(vsNames[ii]);
					////if (gp && gp.GetEmbeddingInfo())
					////{
						////vsNames.RemoveAt(ii--);
					////}
				////}
				////trGetN.graphs.strVal.SetTokens(vsNames, STR_PAGE_LIST_SEPARATOR);
				//trGetN.graphs.strVal = "";
				//trGetN.option.SetAttribute(STR_COMBO_ATTRIB, STR_COMBO_EMBED);
				//trGetN.graphs.SetAttribute(STR_ENABLE_EMBED_ATTRIB, 0);
				//if (trGetN.option.nVal >= OPTION_ALL_EMBEDDED_IN_ACTIVE_FOLDER)
				//{
					//trGetN.option.nVal--;
				//}
				//_refresh_graphs(trGetN);
			//}
			//else
			//{
				////if (!g_strSpecified.IsEmpty())
					////trGetN.graphs.strVal = g_strSpecified;
				//trGetN.graphs.strVal = "";
				//trGetN.option.SetAttribute(STR_COMBO_ATTRIB, STR_COMBO_LINK);
				//trGetN.graphs.SetAttribute(STR_ENABLE_EMBED_ATTRIB, 1);
				//if (trGetN.option.nVal >= OPTION_ALL_EMBEDDED_IN_ACTIVE_FOLDER)
				//{
					//trGetN.option.nVal++;
				//}
				//_refresh_graphs(trGetN);
			//}
			///End IMPROVE_G2W_CODE
		}
	}
	
	if (trGetN.graphs.strVal.IsEmpty())
	{
		strErrMsg = CER_EMPTY_VARIABLE;
		strErrMsg += ":" + _L("Graphs");
		bOKEnable = false;
		return false;
	}
	
	if (trGetN.cols.dVal == NANUM)
	{
		strErrMsg = CER_EMPTY_VARIABLE;
		strErrMsg += ":" + _L("Input Columns");
		bOKEnable = false;
		return true;
	}
	else if (trGetN.cols.dVal <= 0)
	{
		strErrMsg = CER_INVALID_POSITIVE_INTEGER;
		strErrMsg += ":" + _L("Input Columns");
		bOKEnable = false;
		return true;
	}
	///End ADD_BOOL_ENABLE_EMBED_IN_PAGE_PREVIEW_LIST_DLG
	return false;

}

int g2w_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	return false;
}
//nGetNDialog = 0,1,2, corresponding to the XF GetN dropdown, 0 = dialog is not used
//you can change nRet to be one of XFEVT_PROCEED (defualt), XFEVT_ABORT, XFEVT_PROCEED_NO_DLG or XFEVT_PROCEED_WITH_DLG(when nGetNDialog = 0)
//nGetNDialog = -1 when Ok on GetN dialog to allow handler to preocess <auto> etc variables
//dwCntrl is combination of bits
//LTXF_FROM_GUI_MENU, LTXF_FROM_GUI_PROMPT, LTXF_FROM_AUTO_UPDATE, LTXF_FROM_FUNCTION, LTXF_THEME_USED, LTXF_CHANGE_PARAM
void g2w_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	if(!trGetN.IsValid())
		return;
	if (nGetNDialog >= 0)
	{
		_refresh_xf(trGetN);
	}
}
//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 g2w_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
