#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	fld_active,
	fld_folder,
	fld_recursive,
	fld_open,
	fld_project,
};
enum{
	mode_duplicate,
	mode_drag,
};
enum{
	match_none,
	match_wkblong,
	match_wkbshort,
	match_comments,
};
//put additional include files here

//put your own support static functions here

///**************************modification log************************
//------ Folger 04/14/08 QA80-11387 KEEP_RECALCULATE_LINK_WHEN_DRAG_SHEET_IN_SPLIT_BOOK
/// Hong 04/16/08 QA80-11387 DEFAULT_SHOW_LONG_NAME_IN_BOOK_TITLE
/// Hong 04/22/08 QA80-11387 CHANGE_DEFAULT_BOOK_LONGNAME
/// Hong 05/18/09 QA80-11387 FIX_DEFAULT_BK_LNAME_NOT_WORK_EXCEPT_FIRST_ONE
///******************************************************************

static void _update_key_status(TreeNode& trGetN)
{
	trGetN.key.Enable = (match_none == trGetN.match.nVal) ? DISABLE : ENABLE;
}

static void _update_keep_status(TreeNode& trGetN)
{
	trGetN.keep.Enable = (mode_duplicate == trGetN.mode.nVal) ? ENABLE : DISABLE;
}

static int _get_page_names_in_folder(vector<string>& vsPageNames, int nFoldOption)
{
	int nOption;
	switch ( nFoldOption )
	{
	case fld_active:
		nOption = OPTION_ACTIVE_PAGE;
		break;
	case fld_folder:
		nOption = OPTION_ALL_IN_ACTIVE_FOLDER;
		break;	
	case fld_recursive:
		nOption = OPTION_ALL_RECURSIVE_IN_ACTIVE_FOLDER;		
		break;
	
	case fld_open:	
		nOption = OPTION_ALL_OPEN_IN_ACTIVE_FOLDER;
		break;
	case fld_project:
		nOption = OPTION_ALL_IN_OPJ;
		break;
	default:
		ASSERT(FALSE);
		return 0;
	}	
	get_folder_pages_name(vsPageNames, nOption, 0, NULL, NULL, EXIST_WKS); 	
	return vsPageNames.GetSize();
}

/**
	Parameter:
		nKeepIndex = [input] index of sheet to ignore splitting process, -1 mean no sheet ignored
*/
static int _plit_matched_book(const Page& pgSrc, bool bRename, int nMode, int nKeepIndex = -1)
{	
	ASSERT(pgSrc.Layers.Count() > 1);
	
	string	strPrefix;
	if ( mode_duplicate == nMode )
		strPrefix = _L("Copy of") + " ";
	/// Hong 04/22/08 QA80-11387 CHANGE_DEFAULT_BOOK_LONGNAME
	strPrefix += "%s " + _L("from") + " " + pgSrc.GetName();
	/// end CHANGE_DEFAULT_BOOK_LONGNAME
	
	bool	bKeepSrc = mode_duplicate == nMode;	//------ Folger 04/14/08 QA80-11387 KEEP_RECALCULATE_LINK_WHEN_DRAG_SHEET_IN_SPLIT_BOOK
	int		nCurrIndex, nNumSheet = 0;
	//------ Folger 04/14/08 QA80-11387 KEEP_RECALCULATE_LINK_WHEN_DRAG_SHEET_IN_SPLIT_BOOK
	//foreach(Layer ly in pgSrc.Layers)
	for ( nCurrIndex=pgSrc.Layers.Count()-1; nCurrIndex>=0; --nCurrIndex )
	//------
	{
		//nCurrIndex = ly.GetIndex();	//------ Folger 04/14/08 QA80-11387 KEEP_RECALCULATE_LINK_WHEN_DRAG_SHEET_IN_SPLIT_BOOK
		if ( nKeepIndex == nCurrIndex )
			continue;
		Layer ly = pgSrc.Layers(nCurrIndex);	//------ Folger 04/14/08 QA80-11387 KEEP_RECALCULATE_LINK_WHEN_DRAG_SHEET_IN_SPLIT_BOOK
		WorksheetPage wp;
		wp.Create(NULL, CREATE_VISIBLE | CREATE_EMPTY);
		wp.TitleShow = WIN_TITLE_SHOW_BOTH; /// Hong 04/16/08 QA80-11387 DEFAULT_SHOW_LONG_NAME_IN_BOOK_TITLE
		//------ Folger 04/14/08 QA80-11387 KEEP_RECALCULATE_LINK_WHEN_DRAG_SHEET_IN_SPLIT_BOOK
		//wp.AddLayer(ly);
		wp.AddLayer(ly, DCTRL_COPY_DEFAULT, bKeepSrc);
		//------
		if ( bRename )
		{
			/// Hong 05/18/09 QA80-11387 FIX_DEFAULT_BK_LNAME_NOT_WORK_EXCEPT_FIRST_ONE
			//strPrefix.Format(strPrefix, ly.GetName()); /// Hong 04/22/08 QA80-11387 CHANGE_DEFAULT_BOOK_LONGNAME
			string		strLName;
			strLName.Format(strPrefix, ly.GetName());
			/// end FIX_DEFAULT_BK_LNAME_NOT_WORK_EXCEPT_FIRST_ONE
			wp.SetName(ly.GetName(), OCD_ENUM_NEXT);
			/// Hong 04/22/08 QA80-11387 CHANGE_DEFAULT_BOOK_LONGNAME
			//wp.SetLongName(strPrefix + ly.GetName(), false);
			/// Hong 05/18/09 QA80-11387 FIX_DEFAULT_BK_LNAME_NOT_WORK_EXCEPT_FIRST_ONE
			//wp.SetLongName(strPrefix, false);
			wp.SetLongName(strLName, false);
			/// end FIX_DEFAULT_BK_LNAME_NOT_WORK_EXCEPT_FIRST_ONE
			/// end CHANGE_DEFAULT_BOOK_LONGNAME
		}
		
		nNumSheet++;		
	}
	return nNumSheet;
}

static int _split_books_with_options(const vector<string>& vsPageNames, int nMode, bool bKeepSrcPage, bool bRename, int nMatch, LPCSTR lpszKey)
{
	int nNumSplitSheet = 0;
	for ( int ii=0; ii < vsPageNames.GetSize(); ii++ )
	{
		Page pg(vsPageNames[ii]);
		if ( pg.Layers.Count() <= 1 ) // no need split if none or single sheet
			continue;
		
		// march string check
		bool bNeedMarch = true;
		string strVal;
		switch (nMatch)
		{
		case match_wkblong:
			strVal = pg.GetLongName();
			break;
		case match_wkbshort:
			strVal = pg.GetName();
			break;
		case match_comments:
			strVal = pg.GetComments();			
			break;
		case match_none:					
		default:
			bNeedMarch = false;
			break;
		}		
		if ( bNeedMarch && !strVal.Match(lpszKey) )		
			continue;		
		
		int		nKeepIndex = -1;
		if ( mode_drag == nMode )
		{
			Layer 	lyActive = pg.Layers();
			nKeepIndex = lyActive.GetIndex(); // default keep active sheet when drag
		}		
		nNumSplitSheet += _plit_matched_book(pg, bRename, nMode, nKeepIndex);
		
		switch ( nMode )
		{
		case mode_duplicate:
			if ( !bKeepSrcPage )
				pg.Destroy();
			
			break;
		case mode_drag:
			//------ Folger 04/14/08 QA80-11387 KEEP_RECALCULATE_LINK_WHEN_DRAG_SHEET_IN_SPLIT_BOOK
			//for ( int ii = pg.Layers.Count() - 1; ii >= 0; ii-- )
			//{				
				//if ( nKeepIndex == ii )
					//continue;
				//
				//Layer	ly = pg.Layers(ii);
				//ly.Destroy()
			//}			
			//------ End KEEP_RECALCULATE_LINK_WHEN_DRAG_SHEET_IN_SPLIT_BOOK
			break;
		default:
			ASSERT(FALSE); // invalid case
			break;
		}
	}
	return nNumSplitSheet;
}


void wsplit_book(const int& fld, const int& mode, const int& keep, const int& rename, const int& match, const string& key)
{
	vector<string> vsPageNames;
	if ( 0 == _get_page_names_in_folder(vsPageNames, fld) )
		XF_THROW(1);
	
	int nCopySheetNum = _split_books_with_options(vsPageNames, mode, keep, rename, match, key);
}

//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 wsplit_book_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return wsplit_book_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	if ( GETNE_ON_INIT == nEventID || GETNE_ON_THEME == nEventID )
	{
		_update_key_status(trGetN);
		_update_keep_status(trGetN);
		return true;
	}
	
	if ( 0 == lstrcmp(lpcszNodeName, "match") )
	{
		_update_key_status(trGetN);
	}
	
	if ( 0 == lstrcmp(lpcszNodeName, "mode") )
	{
		_update_keep_status(trGetN);
	}
	
	return false;

}

int wsplit_book_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 wsplit_book_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{

}
//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 wsplit_book_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
