/*------------------------------------------------------------------------------*
 * File Name: GetNBox.h															*
 * Creation: CPY 1/27/03														*
 * Purpose: Origin C support for a general parameters edit box as a replacement	*
 *	of the LabTalk GetNumber dialog												*
 * Copyright (c) OriginLab Corp.2003											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	CPY 4/23/03 v7.0568 OPERATION_CLASS_NEED_TRY_AND_AUTO_UPDATE				*
 *	CPY 5/13/03 v7.0584 QA70-4467 BUTTON_IN_EDIT_TEXT							*
 *	CPY 5/15/03 v7.0585 QA70-4477 TREE_BRANCH_SUPPORT							*
 *	CPY 8/24/03 v7.5674 QA70-5061 QA70-5061 ADD_DISPLAY_OPTIONS					*
 *	CPY v7.5723 QA70-5376 GETNBOX_ADD_SIG_DIGITS_SUPPORT						*
 *	CPY v7.5763 QA70-5162 11/18/03 GETNBOX_JUSTIFICATION_AND_ENABLE_EDIT		*
 *	CPY v7.5811 1/30/04 QA70-5910 PREVIEW_GETNBOX								*
 *	YuI 3/24/04 v7.5846 QA70-6118 NEW_DATA_SELECTOR_TOOL						*
 *  Danice v8.0870 5/11/04 QA70-6222 GETNTREE_AUTO_LOAD_DEFAULT					*
 *------------------------------------------------------------------------------*/

 
#ifndef _GET_N_BOX
#define _GET_N_BOX


#include <Dialog.h>
#include <tree_utils.h>

//--- CPY 5/13/03 v7.0584 BUTTON_IN_EDIT_TEXT
#define TRGP_STR_BUTTON	1000
//---
/**
	Example:
		#include <GetNBox.h>
		void run_tree_add_label()
		{
			GETN_TREE(testTree)
			GETN_COMBO(Order1,"Polynomial Order1", 2, "2|3|4|5|6")
			GETN_COMBO(Order2,"Polynomial Order2", 3, "2|3|4|5|6")
			TREE_ADD_LABEL( "Successive Number" );
			if( GetNBox(testTree,"Test","Test", NULL, NULL) )
   				out_tree( testTree );
		}
 */
#define TREE_ADD_LABEL(_NODE_LABEL)	_tmpSubNode.SetAttribute(STR_LABEL_ATTRIB, _NODE_LABEL) 

// declaration
/**
	Example:
		void run()
		{
			GETN_NAMED_TREE( trTest, GetNTree1 )
			GETN_STR(WksName, "Worksheet Name (please use short name)", "This is a test")
			if( GetNBox( trTest ))
				out_tree( trTest );
		}
*/
#define GETN_NAMED_TREE(_TR_NAME, _NODE_NAME)	Tree GetNBoxTree_##_TR_NAME; TreeNode _TR_NAME = GetNBoxTree_##_TR_NAME.AddNode(#_NODE_NAME); TreeNode _tmpNode = _TR_NAME; TreeNode _tmpSubNode; string _strTemp;

/**
	Example:
		void run_getn_tree()
		{
			GETN_TREE(testTree) 
    		GETN_CHECK(IsPath,"Path Control", false)    
    		GETN_BUTTON(Path, "File path", GetAppPath())
    		if( GetNBox(testTree,"Test Check and Button","Test Check...", NULL, NULL) )
    			out_tree( testTree );
		}
 */
#define GETN_TREE(_TR_NAME)	GETN_NAMED_TREE(_TR_NAME, GetNTree)	// for using as a tree, with tree look

/**
	Example:
		void run_getn_box()
		{
			GETN_BOX( treeTest );
			GETN_NUM(decayT1, "Number1", 12.3)
   			GETN_NUM(decayT2, "Number2", pi)
	
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define GETN_BOX(_TR_NAME)	GETN_NAMED_TREE(_TR_NAME, GetNBox) // for using as simple dialog, dialog look
// add parameter

// a check box
/**
	Example:
		void run_getn_check()
		{
			GETN_BOX( treeTest );
			GETN_CHECK(TZ,"Through Zero", false)
	
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define GETN_CHECK(_NODE_NAME, _NODE_LABEL, _DEFAULT_VAL)  _tmpSubNode = _tmpNode.AddNumericNode((int)_DEFAULT_VAL, #_NODE_NAME, TRGP_CHECK);TREE_ADD_LABEL(_NODE_LABEL);

// a Combo box, enum list, 0 offset
/**
	//Will show Correlation on the list box as default.
Example:
		void run_getn_combo()
		{
			GETN_BOX( treeTest );
			GETN_COMBO(Order,"Polynomial Order", 2, "2|3|4|5|6") // dropdown list
	
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define GETN_COMBO(_NODE_NAME, _NODE_LABEL, _DEFAULT_VAL, _COMBO_STR) _tmpSubNode = _tmpNode.AddNumericNode((int)_DEFAULT_VAL, #_NODE_NAME, TRGP_ENUM_COMBO); \
TREE_ADD_LABEL(_NODE_LABEL);\
_tmpSubNode.SetAttribute(STR_COMBO_ATTRIB, _COMBO_STR);

// a string, edit box
/**
	Example:
		void run_getn_str()
		{
			GETN_BOX( treeTest );
			GETN_STR(WksName, "Worksheet Name (please use short name)", "This is a test")
	
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define GETN_STR(_NODE_NAME, _NODE_LABEL, _DEFAULT_VAL)	_tmpSubNode = _tmpNode.AddTextNode(_DEFAULT_VAL, #_NODE_NAME, TRGP_STR);TREE_ADD_LABEL(_NODE_LABEL);

// a numeric, just simple edit box
/**
	Example:
		void run_getn_num()
		{
			GETN_BOX( treeTest );
			double ff = 1.23;
   			GETN_NUM(Factor, "Scale Factor", ff)
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define GETN_NUM(_NODE_NAME, _NODE_LABEL, _DEFAULT_VAL) _tmpSubNode = _tmpNode.AddNumericNode(_DEFAULT_VAL, #_NODE_NAME, TRGP_DOUBLE);TREE_ADD_LABEL(_NODE_LABEL);

// a list of str, with numeric offset
/**
	Example:
		void run_getn_list()
		{
			GETN_BOX( treeTest );
			GETN_LIST(Type, "Analysis Type", 1, "t-Test|Correlation|NLSF|Polynomial Fit|Statistics")
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define GETN_LIST(_NODE_NAME, _NODE_LABEL, _DEFAULT_VAL, _COMBO_STR)  _tmpSubNode = _tmpNode.AddNumericNode((int)_DEFAULT_VAL, #_NODE_NAME, TRGP_STR_LIST); \
TREE_ADD_LABEL(_NODE_LABEL);\
_tmpSubNode.SetAttribute(STR_COMBO_ATTRIB, _COMBO_STR);


// a color, pick from a list that is the system palette
/**
	Example:
		void run_getn_color()
		{
			GETN_BOX( treeTest );
			GETN_COLOR(LineColor, "Fit Curve color", 3)
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define GETN_COLOR(_NODE_NAME, _NODE_LABEL, _DEFAULT_VAL) _tmpSubNode = _tmpNode.AddNumericNode(_DEFAULT_VAL, #_NODE_NAME, TRGP_COLOR);TREE_ADD_LABEL(_NODE_LABEL);

//
/**
	Example:
		void run_getn_interactive()
		{
			GETN_BOX( treeTest );
			GETN_INTERACTIVE(interactive,"interactive","Default Value")
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define	GETN_INTERACTIVE(_NODE_NAME, _NODE_LABEL, _DEFAULT_VAL)		_tmpSubNode = _tmpNode.AddTextNode(_DEFAULT_VAL, #_NODE_NAME, TRGP_INTERACTIVE);TREE_ADD_LABEL(_NODE_LABEL);


/**
*/

/*
#define GETN_BEGIN_DATA_RANGE(_NODE_NAME, _NODE_LABEL, _DEFAULT_VAL) 	_tmpSubNode = _tmpNode.AddTextNode(_DEFAULT_VAL, #_NODE_NAME, TRGP_DATA_RANGE);TREE_ADD_LABEL(_NODE_LABEL);\
TreeNode _tmSave_##_NODE_NAME = _tmpNode; _tmpNode = _tmpSubNode;
#define GETN_END_DATA_RANGE(_NODE_NAME)					_tmpNode = _tmSave_##_NODE_NAME;
*/

#define GETN_BEGIN_DATA_RANGE(_NODE_NAME, _NODE_LABEL) 	_tmpSubNode = _tmpNode.AddNode(#_NODE_NAME, TRGP_DATA_RANGE);TREE_ADD_LABEL(_NODE_LABEL);\
TreeNode _tmSave_##_NODE_NAME = _tmpNode; _tmpNode = _tmpSubNode;
#define GETN_END_DATA_RANGE(_NODE_NAME)					_tmpNode = _tmSave_##_NODE_NAME;

/**#
	Example:
		void test()
		{
			string str = range_to_str(1,9);
			out_str(str);
		}		
*/
string range_to_str(int i1, int i2);

/**#
	Example:
		void test()
		{
			int i1,i2;
			string str("5-10");
			str_to_range(str,i1,i2);
			out_int("",i1);
			out_int("",i2);
		}
*/
bool str_to_range(LPCSTR lpcszRange, int& i1, int& i2);

/**#
	construct a string "min|max|steps"
*/
string range_to_str(double min, double max, int nSteps);
/**#
	from the string "min|max|steps" to return numeric values
	Example:
	void tt(double min, double max, int nsteps)
	{
		string str = range_to_str(min, max, nsteps);
		out_str(str);
		
		double a, b;
		int nn;
		if(str_to_range(str, a, b, nn))
			printf("It is from %f to %f and num steps = %d\n", a, b, nn);
	}
*/
bool str_to_range(LPCSTR lpcszRange, double& min, double& max, int& nSteps);

/**#
	Example:
		int test_SetRect()
		{
			RECT rect;
			SetRect( rect, 100, 200, 300, 400 );
			printf("left=%d top=%d right=%d bottom=%d\n", rect.left, rect.top, rect.top, rect.bottom);
			return 1;
		}
*/
void SetRect(RECT& rect, int nLeft, int nTop, int nRight, int nBottom);

/**#
	return -2 if totally diff, no way to compare
	return -1 if same
	return 0 offset index of 1st diff string otherwise
	
	Example:
		void run_get_changed()
		{
			int nRet;
			vector<string> vec1 = {"Worksheet", "Matrix", "abc", "def"};
			vector<string> vec2 = {"Worksheet", "MATRIX", "123", "456"};
			nRet = get_changed( vec1, vec2);
			printf("nRet=%d\n", nRet);
		}
*/
int get_changed(const vector<string>& vs1, const vector<string>& vs2, bool bCaseSensitive = true);

/**#
	Example:
		void run_is_same()
		{
			bool bRet;
			vector<int> vec1 = {1, 2, 3};
			vector<int> vec2 = {1, 2, 3};
			vector<int> vec3 = {2, 3, 1};
	
			bRet = is_same( vec1, vec2 );
			printf("Is the same: %d\n", bRet);
	
			bRet = is_same( vec1, vec3 );
			printf("Is the same: %d\n", bRet);
		}
*/
bool is_same(const vector<int>& v1, const vector<int>& v2);

/**#
	nSetEnable = 0,1 will force all child nodes to set Enable to same
	
	Example:
		void run_get_enables()
		{
			GETN_BOX( treeTest );
			GETN_NUM(decayT3, "Number", 45.6)
			GETN_STR(readOnly, "Testing item: ReadOnly", "Cann't modify")
   			GETN_READ_ONLY
   	
   			vector<int> vecEnables;
   			tree_get_enables( treeTest, vecEnables );
   			printf("Show: %d %d\n", vecEnables[0], vecEnables[1]);
		}
*/
void tree_get_enables(TreeNode& tr, vector<int>& vv, int nSetEnable = -1);

/**#
	nSetShow = 0,1 will force all child nodes to set Show to same
	
	Example:
		void run_get_shows()
		{	
			GETN_BOX( treeTest );
			GETN_NUM(decayT3, "Number", 45.6)
			GETN_STR(readOnly, "Testing item: ReadOnly", "Cann't modify")
			treeTest.readOnly.Show = false;
   	
   			vector<int> vecShows;
   			tree_get_shows( treeTest, vecShows );
   			printf("Show: %d %d\n", vecShows[0], vecShows[1]);
		}
*/
void tree_get_shows(TreeNode& tr, vector<int>& vv, int nSetShow = -1);

/**#
	Example:
		void run_is_node_need_numeric_validation()
		{
			GETN_BOX( treeTest );
			GETN_COMBO(Order,"Polynomial Order", 2, "|3|4|5|6")
			bool bRet = is_node_need_numeric_validation( treeTest.Order );
			if( bRet )
			{
				out_str("Yes, Order is numeric \n");
			}
			else
			{
				out_str("No, the value isnot numeric\n");
			};
			GETN_COMBO(Order1,"Polynomial Order1", 2, "2|3|4|5|6")
			bRet = is_node_need_numeric_validation( treeTest.Order1 );
			if( bRet )
			{
				out_str("Yes, Order is numeric \n");
			}
			else
			{
				out_str("No, the value isnot numeric\n");
			};
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
*/
bool is_node_need_numeric_validation(TreeNode& trNode);

/**#
	Example:
		void run_get_node_combo_str()
		{
			GETN_BOX( treeTest );
			GETN_COMBO(Order,"Polynomial Order", 2, "2|3|4|5|6")
			string strRet = get_node_combo_str( treeTest.Order );
			printf("strRet=%s\n", strRet);
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
*/
string get_node_combo_str(TreeNode& trNode);

///Danice GETNTREE_AUTO_LOAD_DEFAULT
/**#
	return true if load success, default setting is local in \Themes\(NodeID)-Default.ois
*/
bool tree_load_default_setting(TreeNode& tr, bool bCheckSettingBranch = true);
///END GETNTREE_AUTO_LOAD_DEFAULT


/**
	Example:
		void test()
		{
			GETN_TREE(myTree)	
			
			GETN_STR(str,"String","abc")
			
			GETN_LIST(Type,"Color", 1, "Red|Blue|White")
			
			GETN_RANGE(Range,"Range",0,10,1,6)			
			
			if(GetNBox(myTree,"Test","OK",NULL,NULL))
			{
				out_str(myTree.str.strVal);
				out_int("",myTree.Type.nVal);
			}	
		}
*/
#define GETN_RANGE(_NODE_NAME, _NODE_LABEL, _I0, _IMAX, _I1, _I2) _strTemp = range_to_str(_I1, _I2);_tmpSubNode = _tmpNode.AddTextNode(_strTemp, #_NODE_NAME, TRGP_RANGE);\
TREE_ADD_LABEL(_NODE_LABEL);_strTemp = (_I0);_strTemp+="|" + (_IMAX);_tmpSubNode.SetAttribute(STR_COMBO_ATTRIB, _strTemp);


///----- YuI 01/14/04 v7.5801 QA70-5799 SLIDER_CONTROL_TO_GETNBOX
/**
	Example:
		void run_getn_slider()
		{
			GETN_BOX( treeTest );
			GETN_SLIDER(min, "From", 0, "0|255|255")
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define	GETN_SLIDER(_NODE_NAME, _NODE_LABEL, _DEFAULT_VAL, _COMBO_STR)	_strTemp = _DEFAULT_VAL; _tmpSubNode = _tmpNode.AddTextNode(_strTemp, #_NODE_NAME, TRGP_SLIDER);TREE_ADD_LABEL(_NODE_LABEL);\
TREE_ADD_LABEL(_NODE_LABEL);_tmpSubNode.SetAttribute(STR_COMBO_ATTRIB, _COMBO_STR);

/**
	Example:
		void run_getn_slideredit()
		{
			GETN_BOX( treeTest );
			GETN_SLIDEREDIT(min, "To", 0, "0|255|255")
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define	GETN_SLIDEREDIT(_NODE_NAME, _NODE_LABEL, _DEFAULT_VAL, _COMBO_STR)	_strTemp = _DEFAULT_VAL; _tmpSubNode = _tmpNode.AddTextNode(_strTemp, #_NODE_NAME, TRGP_SLIDEREDIT);TREE_ADD_LABEL(_NODE_LABEL);\
TREE_ADD_LABEL(_NODE_LABEL);_tmpSubNode.SetAttribute(STR_COMBO_ATTRIB, _COMBO_STR);
//------

//---- CPY 4/23/03 OPERATION_CLASS_NEED_TRY_AND_AUTO_UPDATE
#define STR_OPERATION_TRY	"Try"
#define STR_ACTIVE_CURVE	"ActiveCurve"
#define STR_CLASS_NAME		"Class"

/**
	Example:
		void run_getn_operation()
		{
			GETN_OPERATION(testTree)
			GETN_STR(WksName, "Worksheet Name (please use short name)", "This is a test")
			if( GetNBox( testTree ))
				out_tree( testTree );
		}
 */
#define GETN_OPERATION(_TR_NAME)		GETN_NAMED_TREE(_TR_NAME, GUI) _tmpNode.SetAttribute(STR_OPERATION_TRY, "Try");

/**
 */
#define GETN_CURVE_OPERATION(_TR_NAME)	GETN_OPERATION(_TR_NAME) _tmpNode.SetAttribute(STR_ACTIVE_CURVE, "Input");
//----


//--- CPY 5/13/03 v7.0584 BUTTON_IN_EDIT_TEXT
// a string in edit box with button to bring up other dialog, like a FilePath dialog
/**
	Example:
		void run_button()
		{
			GETN_TREE(testTree)
			GETN_NUM(Factor, "Scale Factor", 12.3)
			GETN_BUTTON(Path, "File path", GetAppPath())
			GETN_OPTION_EVENT(button_event) 
			if(GetNBox(testTree, NULL, NULL, NULL, NULL))
      			out_tree(testTree);
		}
		bool button_event(TreeNode& myTree, int nRow, int nType, Dialog& theDlg)
		{
			if(TRGP_STR_BUTTON == nType && nRow >= 0)
   			{
       			string strPath = BrowseGetPath(myTree.Path.strVal);
       			myTree.Path.strVal = strPath;
       			return true;
   			}
   			else
       			return false;
		}
 */
#define GETN_BUTTON(_NODE_NAME, _NODE_LABEL, _DEFAULT_VAL) _tmpSubNode = _tmpNode.AddTextNode(_DEFAULT_VAL, #_NODE_NAME, TRGP_STR_BUTTON); \
TREE_ADD_LABEL(_NODE_LABEL);\
_tmpSubNode.SetAttribute(STR_COMBO_ATTRIB, "...");
//--- end CPY 5/13/03 v7.0584 BUTTON_IN_EDIT_TEXT

//------- CPY 5/15/03 v7.0585 QA70-4477 TREE_BRANCH_SUPPORT
//_tmSaveNode added in GETN_NAMED_TREE as well
/**
	Example:
		void run_branch()
		{
			GETN_TREE(testTree)
   
   			GETN_CHECK(FitAllCurves, "Fit All Curves", 0)
   
   			GETN_BEGIN_BRANCH(Fit, "Fitting Options")//Match GETN_END_BRANCH
       			GETN_CHECK(ThroughZero, "Through Zero", 0)
       			GETN_CHECK(FixSlope, "Fix Slope", 0)
   			GETN_END_BRANCH(Fit)	//Match GETN_BEGIN_BRANCH

   			GETN_NUM(Points, "Points", 20)
   
   			if(GetNBox(testTree, NULL, NULL, NULL, NULL))
      			out_tree(testTree);
		}
 */
#define GETN_BEGIN_BRANCH(_NODE_NAME, _NODE_LABEL) 	_tmpSubNode = _tmpNode.AddNode(#_NODE_NAME, TRGP_BRANCH);TREE_ADD_LABEL(_NODE_LABEL);\
TreeNode _tmSave_##_NODE_NAME = _tmpNode; _tmpNode = _tmpSubNode;
#define GETN_END_BRANCH(_NODE_NAME)					_tmpNode = _tmSave_##_NODE_NAME;

//------- end TREE_BRANCH_SUPPORT


//----- CPY 5/17/03 ALLOW_GETN_TREE_PASSED_INTO_FUNCTION
/**#
	Example:
			void run_getnuse( TreeNode &trN )
			{
				GETN_USE(trN)
			   	if(GetNBox(trN, NULL, NULL, NULL, NULL))
				out_tree(trN);
			}
			void run_GETN_USE()
			{
				GETN_TREE(testTree)
			 
				GETN_CHECK(FitAllCurves, "Fit All Curves", 0)
				  	GETN_BEGIN_BRANCH(Fit, "Fitting Options")//Match GETN_END_BRANCH
				   	GETN_CHECK(ThroughZero, "Through Zero", 0)
				    GETN_CHECK(FixSlope, "Fix Slope", 0)
			   	GETN_END_BRANCH(Fit)	//Match GETN_BEGIN_BRANCH
				GETN_NUM(Points, "Points", 20)
			   	
				run_getnuse(testTree);
			}
*/
#define GETN_USE(_TR_NAME)	TreeNode _tmpNode = _TR_NAME; TreeNode _tmpSubNode; string _strTemp;
//-----	

//---- CPY 8/24/03 v7.5674 QA70-5061 ADD_DISPLAY_OPTIONS
#define STR_ATTRIB_BRANCH			"Branch"
#define STR_ATTRIB_VERT_GRID_LINES	"GridLines"
#define STR_ATTRIB_LABEL_COLOR		"LabelColor"
#define STR_ATTRIB_BKGRND_COLOR		"BkGrndColor"
#define STR_ATTRIB_HANDLER			"Handler"
#define STR_ATTRIB_NUMFMT			"NumFormat"
#define STR_ATTRIB_DISPFMT			"DispFormat" //CPY v7.5763 QA70-5162 11/18/03 GETNBOX_JUSTIFICATION_AND_ENABLE_EDIT
// _VGLTYPE can be one of
#ifndef _VSFLEXGRID_H
	#define	flexGridFlatVert	8
	#define	flexGridInsetVert	9
	#define flexGridRaisedVert	10
#endif //_VSFLEXGRID_H

/**
	Example:
		void run_getn_option_gridline()
		{
			GETN_TREE( treeTest );
			GETN_OPTION_GRIDLINE(flexGridFlatVert) //--- 1. divider line
   			GETN_COLOR(FitCurveColor, "Fit Curve color", 1)
			if( GetNBox( treeTest ))	//a vertical line appears
				out_tree( treeTest );
		}
 */
#define GETN_OPTION_GRIDLINE(_VGLTYPE)		_strTemp = _VGLTYPE; _tmpNode.SetAttribute(STR_ATTRIB_VERT_GRID_LINES, _strTemp);

/**
	Example:
		void run_getn_option_branch()
		{
			GETN_TREE(trTemp)
			GETN_BEGIN_BRANCH(Range, "Intensity Range 1")
				GETN_OPTION_BRANCH(GETNBRANCH_OPEN) //open the branch, on showing
				GETN_SLIDEREDIT(min, "From", 0, "0|255|255")
				GETN_SLIDEREDIT(max, "To", 255, "0|255|255")
			GETN_END_BRANCH(Range)
			if( GetNBox( trTemp ))
				out_tree( trTemp );
		}
 */
#define GETN_OPTION_BRANCH(_DWOPTN)	_strTemp = _DWOPTN; _tmpNode.SetAttribute(STR_ATTRIB_BRANCH, _strTemp);
// can use RGB(r,g,b) or predefined COLOR_RED, COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_LTBLUE, COLOR_LTGREEN

/**
	Example:
		void run_getn_option_color_label()
		{
			GETN_TREE( treeTest );
			GETN_NUM(decayT2, "2nd Decay Time (t2)", 0.0)
    		GETN_OPTION_COLOR_LABEL(COLOR_ORANGE) //--- 2. color label
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define GETN_OPTION_COLOR_LABEL(_RGB)		_strTemp = _RGB;_tmpSubNode.SetAttribute(STR_ATTRIB_LABEL_COLOR, _strTemp);

/**
	Example:
		void run_getn_option_color_background()
		{
			GETN_TREE( treeTest );
			GETN_NUM(decayT1, "Number1", 12.3)
   			GETN_OPTION_COLOR_BACKGROUND( COLOR_GREEN )
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define GETN_OPTION_COLOR_BACKGROUND(_RGB)		_strTemp = _RGB;_tmpSubNode.SetAttribute(STR_ATTRIB_BKGRND_COLOR, _strTemp);

/**
	Example:
		void run_event()
		{
			GETN_TREE(testTree)
			GETN_NUM(Factor, "Scale Factor", 12.3)
			GETN_BUTTON(Path, "File path", GetAppPath())
			GETN_OPTION_EVENT(button_event) 
			if(GetNBox(testTree, NULL, NULL, NULL, NULL))
      			out_tree(testTree);
		}
		bool button_event(TreeNode& myTree, int nRow, int nType, Dialog& theDlg)
		{
			if(TRGP_STR_BUTTON == nType && nRow >= 0)
   			{
       			string strPath = BrowseGetPath(myTree.Path.strVal);
       			myTree.Path.strVal = strPath;
       			return true;
   			}
   			else
       			return false;
		}
 */
#define GETN_OPTION_EVENT(_PFN)	{PEVENT_FUNC __dfn = _PFN;DWORD _dw_fn = (DWORD)__dfn;\
if(_dw_fn) {_strTemp = _dw_fn;_tmpSubNode.SetAttribute(STR_ATTRIB_HANDLER, _strTemp);}}	

/**
	Example:
		void run_format()
		{
			GETN_BOX( treeTest );
   			GETN_NUM(decayT1, "Number1", pi)
   			GETN_OPTION_NUM_FORMAT( ".2" )
   			printf("pi = %f\n", pi);
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define GETN_OPTION_NUM_FORMAT(_STRFMT)	_tmpNode.SetAttribute(STR_ATTRIB_NUMFMT, _STRFMT); //CPY v7.5723 QA70-5376 GETNBOX_ADD_SIG_DIGITS_SUPPORT
//---- end QA70-5061 ADD_DISPLAY_OPTIONS

//--- CPY 4/25/04 NODE_ID_FOR_GETN
#define GETN_ID_BRANCH(_ID) _strTemp = _ID; _tmpNode.SetAttribute(STR_DATAID_ATTRIB,_strTemp);
#define GETN_ID(_ID) _strTemp = _ID; _tmpSubNode.SetAttribute(STR_DATAID_ATTRIB,_strTemp);
//---
	
//----- CPY v7.5763 QA70-5162 11/18/03 GETNBOX_JUSTIFICATION_AND_ENABLE_EDIT
enum {DISPLAY_LEFT, DISPLAY_CENTER, DISPLAY_RIGHT};
/**
	Example:
		void run_getn_option_display_format()
		{
			GETN_TREE( treeTest );
			GETN_NUM(decayT3, "Number", 45.6)
   			GETN_OPTION_DISPLAY_FORMAT( DISPLAY_RIGHT );
			if( GetNBox( treeTest ))
				out_tree( treeTest );
		}
 */
#define GETN_OPTION_DISPLAY_FORMAT(_DISPFMT)	_strTemp = _DISPFMT;_tmpSubNode.SetAttribute(STR_ATTRIB_DISPFMT, _strTemp);

/**
	Example:
		void run_Enable()
		{
			GETN_TREE(testTree) 
   			GETN_STR(WksName, "Worksheet Name:", "This is a test")
   			testTree.WksName.Enable = false;
   			if(GetNBox(testTree))
    			out_tree(testTree);
		}
		void run_read_only()
		{
			GETN_TREE(testTree) 
			GETN_STR(readOnly, "Testing item: ReadOnly", "Cann't modify")
   			GETN_READ_ONLY
   			if(GetNBox(testTree))
    			out_tree(testTree);
		}
 */
#define GETN_READ_ONLY							_tmpSubNode.Enable = false;
//----- end GETNBOX_JUSTIFICATION_AND_ENABLE_EDIT

/**
	Example:
		void run_apply()
		{
			GETN_TREE( treeTest );
			GetNBox(treeTest, "Test Apply Button", "Test...", test_apply, NULL)
		}
		bool test_apply(TreeNode& myTree)
		{
			printf("Apply pressed");
			return true;
		}
 */
typedef bool (* PAPPLY_FUNC)(TreeNode& tr);

/**
	Example:
		void run_evenhandler()
		{
			GETN_TREE(testTree)
			GETN_CHECK(TZ,"Through Zero", false)
			GETN_STR(WksName, "Do:", "Click check box")
			if(GetNBox(testTree, NULL, NULL, NULL, handler))//use a pointer to function.
       			out_tree(testTree);
		}
		bool handler(TreeNode& myTree, int nRow, int nType, Dialog& getNDlg)
		{
			if(ONODETYPE_CHECKBOX == nType)
			{
				myTree.WksName.Show = !myTree.WksName.Show;
			}
			return true;
		}  
 */
typedef bool (* PEVENT_FUNC)(TreeNode& tr, int nRow, int nCntrlType, Dialog& getNDlg); //CPY 5/30/03 added getNDlg

/** >User Interface
		Opens a simple dialog to get multiple values from user
	Parameters:
		trNode = a TreeNode constructed by the GETN_BOX or GETN_TREE macro
		lpcszTitle = Dialog title
		lpcszDescription = a line of text above the editable list of parameters
		pfnApply = if specified, an Apply button will show and call this handler
		pfnEvent = if specified, it will be called at the beginning with Row number = -1 for each control type, and if user change any editable parameters, the event handler will also be called
		hWndParent = parent window. If NULL, Origin main window will be used, also the location of the dialog will be reset to where it was brought up the time before. 
		If hWndParent is specified, the dialog will be open at its default location, so the event handler can move the dialog to a desired location.
	
	Return:
		TRUE if user click OK, FALSE if user click Cancel
	Example:
		// this will bring up the simple form with dialog look
		void test_get_n_box()
		{
			double x0, x1;
			GETN_BOX(trTemp)
			GETN_NUM(xFrom, "X From", 1.3)
			GETN_NUM(xStep, "X Step", -0.5)
			if(GetNBox(trTemp, "Row# as X", "Please specify initial X value and increment"))
			{
				x0 = trTemp.xFrom.dVal;
				x1 = trTemp.xStep.dVal;
				printf("X from %f with increment %f\n", x0, x1);
			}
		}
		// the following example shows a tree that allow more info to be edited
		static bool fit_expdecay_event(TreeNode& myTree, int nRow, int nType, Dialog& dlgGetNBox)	
		{
			if(nRow < 0) // On dialog init, nothing to do
				return false;
			
			// only handle the button for file path for now
			if(TRGP_STR_BUTTON == nType)
			{
				string str = BrowseGetPath(GetAppPath() + "OriginC\\", "Browse");
				myTree.Path.strVal = str;
				return true;
			}
			return false;
		}
		void test_get_n_tree()
		{
			GETN_TREE(myTree)
			GETN_COMBO(numExp, "Number of Terms", 1, "1|2|3")
			
			GETN_BEGIN_BRANCH(DecayTime, "Decay Times")
				GETN_NUM(decayT1, "1st Decay Time (t1)", 0.0)
				GETN_NUM(decayT2, "2nd Decay Time (t2)", 0.0)
				GETN_NUM(decayT3, "3rd Decay Time (t3)", 0.0)
			GETN_END_BRANCH(DecayTime)
			
			GETN_CHECK(PartialRange, "Fit Partial Data", false)
			GETN_BUTTON(Path, "File path", "c:\\")
			
			GETN_COLOR(FitCurveColor, "Fit Curve color", 1)
			
			if(GetNBox(myTree, "Fit Exp Decay", "Fit Exponential Decay 1,2,3", NULL, fit_expdecay_event))
			{
				if(myTree.numExp.nVal > 1)
					out_str("Multiple exponential");
				if(myTree.DecayTime.decayT1.dVal <= 0)
					out_str("Invalid decay time specified");
			}
		}
*/ 
bool GetNBox(TreeNode& trNode, LPCSTR lpcszTitle=NULL, LPCSTR lpcszDescription=NULL, PAPPLY_FUNC pfnApply = NULL, PEVENT_FUNC pfnEvent = NULL, HWND hWndParent = NULL);

/**#
	Example:
		void test()
		{
			Tree     tr;
			tr.trNode.strVal = "Tree";
			tr.trNode.First.strVal = "first";
			tr.trNode.First.abc.nVal = 1;
			tr.trNode.First.def.nVal = 2;	
			out_params(tr);				
		}
*/
bool out_params(TreeNode& trNode);

//#define load_default_getnbox_gui(__TR, __CLASSNAME)	load_default_settings(__TR, __CLASSNAME,SETTINGS_GUI)


//------------------ CPY v7.5811 1/30/04 QA70-5910 PREVIEW_GETNBOX
typedef bool (* PVIEW_FUNC)(TreeNode& tr, int nViewState, Dialog& dlg, int nViewCntrlID);

//nViewState
enum {GETNVIEW_ON_INIT, GETNVIEW_ON_DESTROY, GETNVIEW_ON_OPEN, GETNVIEW_ON_CLOSE, GETNVIEW_ON_SIZE, GETNVIEW_ON_UPDATE};
/**#
		Example:
		#include <..\OriginLab\ImagePreview.h>
		int run_getnviewbox()
		{
			//Import a image and focus on it first
			string strSourceMatName;
			MatrixLayer ml = Project.ActiveLayer();
			if(!ml)
				return -1;
			ml.GetPage().GetName( strSourceMatName );
	
			// Use GETN_TREE macro to declare a tree for a Tree style GetN dialog
			GETN_TREE( tr )
			GETN_STR( tnMatrix, "Current Image:", strSourceMatName );
			if( GetNViewBox(tr, "Testing",NULL, preview) )
				out_tree( tr );
			return 1;
		}
		// handler when "preview" pressed
		bool preview(TreeNode& tr, int nViewState, Dialog& dlg, int nViewCntrlID)
		{	
			static CPreview* s_pPreview = NULL;
	
			switch(nViewState)
			{
			case GETNVIEW_ON_INIT:
				s_pPreview = new CPreview;
				if(!s_pPreview->Init(dlg, nViewCntrlID))
					return false;
			break;
			case GETNVIEW_ON_DESTROY:
				if(s_pPreview)
					delete s_pPreview;
				s_pPreview = NULL;
				break;
			case GETNVIEW_ON_UPDATE:
				s_pPreview->Update(tr);
				break;
			}
			return true;
		}
		//create class inheriting ImagePreview
		class CPreview : public ImagePreview
		{
		protected:
			virtual bool OnUpdatePreview(TreeNode tr)
			{
				MatrixPage mp(m_strSrcMatrix);
				if(!mp)
					return false;
				Matrix<ushort> mprev(m_mlCntrl);
				mprev.Rotate();
		
				return true;
			}
		};
*/
bool GetNViewBox(TreeNode& trNode, LPCSTR lpcszTitle=NULL, LPCSTR lpcszDescription=NULL, PVIEW_FUNC pfnView = NULL, PEVENT_FUNC pfnEvent = NULL, HWND hWndParent = NULL);
//------------------ end CPY v7.5811 1/30/04 QA70-5910 PREVIEW_GETNBOX


#pragma dll(OTreeEditor.dll)

#define AFTER_EDIT_USE_CUSTOM_EDITOR (-1)
#define AFTER_EDIT_USE_STR			(-2)

/**#
*/
class EditorManager
{
public:
	EditorManager();
	~EditorManager();
	
	
	DWORD	New(int nType, int nRow, DWORD nID=0, LPCSTR lpcszAuxString=NULL, DWORD dwParam1=0, DWORD dwParam2=0);
	bool	Delete(DWORD dwData);
	BOOL	DrawCell(DWORD dwData, DWORD hDC, const RECT * lpcRect, BOOL bSelected);
	double	GetCellHeightFactor(DWORD dwData);
	DWORD	CreateEditor(DWORD dwData, const RECT * lpcRect, HWND hwndOwner, UINT nControlID=100, LPCTSTR lpcszFontName=NULL, int nFontSize=0);
	bool	DestroyEditor(DWORD dwData);
	bool	StartEdit(DWORD dwData, int nRow);
	bool	AfterEdit(DWORD dwData, int nComboIndex = AFTER_EDIT_USE_CUSTOM_EDITOR, LPCSTR lpcszNewText = NULL);
	string	GetText(DWORD dwData, BOOL bTranslate = TRUE);
	bool	SetText(DWORD dwData, LPCSTR lpcsz, int nCvtText = OXVT_UINT);
	int		GetEditInfo(DWORD dwData, string& strCombo, string& strEditMask);
	string	GetStrData(DWORD dwData);
	bool	SetStrData(DWORD dwData, LPCSTR lpcsz);
	bool	ValidateEdit(DWORD dwData, LPCSTR lpcsz);
	bool	SetComboStr(DWORD dwData, LPCSTR lpcsz);
	#if _OC_VER >= 0x0800
	bool	SetEditorStr(DWORD dwData, LPCSTR lpcsz);
	BOOL	OnSelectionTrack(DWORD dwData);
	BOOL	OnSelectionChange(DWORD dwData);
	BOOL	SetTree(DWORD dwData, TreeNode& tr);
	BOOL	GetTree(DWORD dwData, TreeNode& tr);
	#endif //_OC_VER >= 0x0800
};

/// YuI 3/24/04 v7.5846 QA70-6118 NEW_DATA_SELECTOR_TOOL
// if modified also modify in okRange.cpp
#define	PREFIX_FOR_DATA_RANGE_DATA	"Data"
/// end NEW_DATA_SELECTOR_TOOL

#endif //_GET_N_BOX
