#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
///////////////////////////////////////////////////////////////////////
//////// modification log
/// Sim 06-25-2007 UPDATE_ORGANIZER
/// Hong 09/26/07 8.0709 CLEAN_OPEN_SAVE_DIALOG_TITLE_TO_DEFAULT
/// Sophy 9/21/2009 QA80-14336 MORE_WORK_ON_HANDLE_NOT_SUPPORTED_DATA
/// Hong 11/11/09 FIX_TDM_RUNTIME_ERROR
/// Sophy 12/17/2009 QA80-14325-P2 LABTALK_CTRL_TO_SKIP_EMPTY_BOOKSHEET
///////////////////////////////////////////////////////////////////////

//put additional include files here
#include <GetNbox.h>
#include <..\OriginLab\fu_utils.h>
#include <..\OriginLab\cmatfile.h>

static bool s_bFileValid = true;
static bool s_bRangeValid = true;
#define OK_SURE(_OK_ENABLE) _OK_ENABLE = (s_bFileValid && s_bRangeValid);

static bool construct_tree_setting(StringArray& vsFileNames, TreeNode& trSetting, string* pstrErr = NULL)
{
	int nCount = vsFileNames.GetSize();
	trSetting.RemoveChildrenWithPrefix(); 
	
	for ( int nIndex = 0; nIndex < vsFileNames.GetSize(); nIndex++ )
	{	
		TreeNode trFileSetting = trSetting.AddNumericNode(1, "FileSetting", TRGP_CHECK);
		trFileSetting.SetAttribute(STR_LABEL_ATTRIB, GetFileName(vsFileNames[nIndex]));

		TreeNode trFileInfo = trFileSetting.AddNode("FileInfo");
		trFileInfo.SetAttribute(STR_LABEL_ATTRIB, STR_FILE_INFO);	///Sophy 9/21/2009 SET_LABEL_ON_GUI_FOR_TRANSLATION
		GETN_USE(trFileInfo)
		string strTag, strInfo;
		strTag.Format("file%d", nIndex+1);
		strInfo.Format("File Size: %s ", GetFileSize(vsFileNames[nIndex]));
		GETN_STR(strTag, GetFileName(vsFileNames[nIndex], false), strInfo )
		GETN_READ_ONLY

		
		CMATFile matFile;
		
		matFile.ReadMATFile(vsFileNames[nIndex]);
		
		TreeNode trGroups = trFileSetting.AddNode("vars");
		trGroups.SetAttribute(STR_LABEL_ATTRIB, _L("Variables"));
		trGroups.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_CHECK_CONTROL);
		/// Hong 05/29/07 v8.0629 MORE_INFO
		string strLabel;
		/// end MORE_INFO
		foreach (TreeNode tn in matFile.m_trFileInfo.Children)
		{
			TreeNode trGroup = trGroups.AddNumericNode(1, "VarsName", TRGP_CHECK);
			/// Hong 05/29/07 v8.0629 MORE_INFO
			//trGroup.SetAttribute(STR_LABEL_ATTRIB, tn.tagName);
			strLabel.Format("%s: (%s - %s)", tn.tagName, tn.Type.strVal, tn.Size.strVal);
			trGroup.SetAttribute(STR_LABEL_ATTRIB, strLabel);
			/// end MORE_INFO			
		}
	}
	return true;
}

///Sophy 10/16/2009 QA80-14325 MAKE_OUTPUT_SELECTABLE_FOR_MATLAB_IMPORT
static bool _construct_options_branch(TreeNode& trGetN)
{
	if ( !trGetN )
		return false;
	//reuse dataid from ascii
	GETN_USE(trGetN) GETN_ID_BRANCH(IDST_DLG_ASCIMP_OPTIONS)
	GETN_LIST(ImpMode, _L("Import Mode"), IMPMODE_START_NEW_BOOKS, IMPMODE_OPTIONS_LIST) GETN_ID(IDE_IMP_IMPORTMODE)
	return true;
}
///end MAKE_OUTPUT_SELECTABLE_FOR_MATLAB_IMPORT
static bool file_name_event(TreeNode& trGetN, string& strErrMsg)
{
	string strFileName = trGetN.fname.strVal;
	TreeNode trNode = trGetN.trfiles;
	
	if ( !check_imported_file_name(strFileName, strErrMsg) )
		return false;
	
	// add code for construct trfiles
	StringArray vsFileNames;
	separate_multiline_files(strFileName, vsFileNames);
	if( !construct_tree_setting(vsFileNames, trNode, &strErrMsg) )
	{
		// clean the trFiles on GUI
		trNode.RemoveChildrenWithPrefix();
		strErrMsg = CER_INVALID_IMPORT_DATA_FILE;
		return false;
	}
	
	return true;
}



void impMatlab(const string& fname, const TreeNode& trfiles, const TreeNode& options, Range& orng, TreeNode& trheader, const TreeNode& trFilter)
{
	int c1,c2;
	Datasheet lyTarget;
	Page pgTarget;
	if ( !GetRangeInfo(orng, lyTarget, pgTarget, c1, c2) )
		XF_THROW(XFERR_INVALID_RANGE);
	
	Tree trBaseInfo; 
	
	Tree tnUsingFilter; /// Hong 06/13/07 v8.0640c TEMP_ADD_FILTER_INFO_FOR_MAKE_FILTER
	int nVer;
	if ( fuGetDouble(trFilter, IDE_DISP_IMP_ORIGINVER, nVer) )
		tnUsingFilter = trFilter;
	
	/// Hong 06/13/07 v8.0640c TEMP_ADD_FILTER_INFO_FOR_MAKE_FILTER
	if ( tnUsingFilter.GetNodeCount() <= 0 )
	{
		fuPrepareDefault(tnUsingFilter, FILTER_TYPE_XFUNC);		
		tree_set_attribute_to_all_nodes(tnUsingFilter, "Show", "0");		
	}
	
	fuSetXFunctionName(tnUsingFilter, "impMatlab");
	/// end TEMP_ADD_FILTER_INFO_FOR_MAKE_FILTER
	
	StringArray vsFileNames;
	separate_multiline_files(fname, vsFileNames); 
	int nFileCount = vsFileNames.GetSize();
	if ( nFileCount <= 0 )
		XF_THROW(CER_INVALID_IMPORT_DATA_FILE);
	
	if ( trfiles.IsEmpty())
	{
		if ( !construct_tree_setting(vsFileNames, trfiles) )
		{
			XF_THROW(CER_INVALID_IMPORT_DATA_FILE);
			return ;
		}
	}
	if( trfiles.IsEmpty())//trfiles was constructed by file
		XF_THROW(CER_INVALID_IMPORT_DATA_FILE);
	
	waitCursor wc;
	
	int nImportMode = options.ImpMode.nVal;
	if ( nImportMode != IMPMODE_START_NEW_BOOKS ) //not default
	{
		WorksheetPage wksPage(pgTarget);
		MatrixPage matPage(pgTarget);
		CMATFile matFile;
		matFile.ImportMatFiles(vsFileNames, wksPage, matPage, trfiles, nImportMode);
		return;
	}
	bool bEmptyPage = (pgTarget && 1 == pgTarget.Layers.Count() && is_sheet_empty(pgTarget.Layers(0)));
	
	int nImportFile = 0; //index for import file
	for ( int ii = 0; ii < nFileCount; ii++ )
	{
		TreeNode trFileSetting = trfiles.Children.Item(ii);
	
		///Sophy 12/17/2009 QA80-14325-P2 LABTALK_CTRL_TO_SKIP_EMPTY_BOOKSHEET
		//if(nImportFile != 0 || !bEmptyPage)
		//{
			//if ( EXIST_MATRIX == pgTarget.GetType() ) // if active matrixbook
			//{
				//MatrixPage matPg;
				//matPg.Create("origin");
				//pgTarget = matPg;
			//}
			//else
			//{
				//WorksheetPage wkpg;
				//wkpg.Create("origin");
				//pgTarget = wkpg;
			//}
		//}
		int nImportMode = pgTarget.GetType() == EXIST_WKS ? IMPMODE_ONE_TO_ONE_WKS : IMPMODE_ONE_TO_ONE_MAT;
		CMATFile matFile;
		if ( matFile.GetTargetPage(pgTarget, nImportMode, nImportFile) )
			lyTarget = pgTarget.Layers();
		///end LABTALK_CTRL_TO_SKIP_EMPTY_BOOKSHEET
		nImportFile++;
		
		string strFile;
		int nIndexLayer = lyTarget.GetIndex();
		strFile.Format("File%d", nIndexLayer + 1); // file index to be 1
		TreeNode trInfo = trBaseInfo.AddNode(strFile);
		
		int nRet = 0;
		///Sophy 12/17/2009 QA80-14325-P2 LABTALK_CTRL_TO_SKIP_EMPTY_BOOKSHEET
		//CMATFile matFile; //forward declare as to use its member function
		///end LABTALK_CTRL_TO_SKIP_EMPTY_BOOKSHEET
		if ( !matFile.ImportMatFile(vsFileNames[ii], pgTarget, trFileSetting.vars, trInfo) )
		{
			XF_THROW_EX(nRet, vsFileNames[ii]);
		}
		/// Hong 05/30/07 v8.0629b MORE_IMPORT_INFO_FOR_ORGANIZER
		//impinfo_AddFile(lyTarget, vsFileNames[ii], trInfo, ASCIMP_MODE_NEW_BOOKS, FILTER_TYPE_XFUNC, tnUsingFilter);
		Tree trDataRange;
		getRangeInfo(trDataRange, matFile.GetDataRange());
		
		impinfo_AddFile(lyTarget, vsFileNames[ii], trInfo, ASCIMP_MODE_NEW_BOOKS, FILTER_TYPE_XFUNC, tnUsingFilter, ii + 1, trDataRange);
		/// end MORE_IMPORT_INFO_FOR_ORGANIZER
	}
	//refresh_organizer_gui(pgTarget); ///---Sim 06-25-2007 UPDATE_ORGANIZER
	if( trheader )
		trheader.Replace(trBaseInfo.Clone(), true, true);/// Hong 01/10/06 FINFO_IS_ONLY_OUTPUT
}

//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 impMatlab_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return impMatlab_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	OK_SURE(bOKEnable);
	
	///support D&D show Dlg, if trFiles no child, should construct it
	/// Hong 11/11/09 FIX_TDM_RUNTIME_ERROR
	//if ( (GETNE_ON_INIT == nEventID && trGetN.info.Children.Count() == 0) || GETNE_ON_THEME == nEventID )
	if ( GETNE_ON_INIT == nEventID || GETNE_ON_THEME == nEventID )
	/// end FIX_TDM_RUNTIME_ERROR
	{
		///Sophy 9/21/2009 QA80-14336 MORE_WORK_ON_HANDLE_NOT_SUPPORTED_DATA this code was called in before_execute
		//s_bFileValid = file_name_event(trGetN, strErrMsg);
		///end MORE_WORK_ON_HANDLE_NOT_SUPPORTED_DATA
		s_bRangeValid = !trGetN.orng.strVal.IsEmpty();
		if(!s_bRangeValid)
			strErrMsg = CER_INVALID_PAGE;
		
		OK_SURE(bOKEnable);	
		return true;
	}
	
	if( 0 == lstrcmp(lpcszNodeName, "fname") )
	{
		s_bFileValid = file_name_event(trGetN, strErrMsg);
		OK_SURE(bOKEnable);
		return true;
	}
	///Cheney 2006-12-9 PREPARE_ERR_MESSAGE
	//check range if is invalid
	if( 0 == lstrcmp(lpcszNodeName, "orng") )
	{
		s_bRangeValid = !trGetN.orng.strVal.IsEmpty();
		OK_SURE(bOKEnable);
		if(!s_bRangeValid)
			strErrMsg = CER_INVALID_PAGE;
		
		return true;
	}
	///end PREPARE_ERR_MESSAGE
	return false;

}

int impMatlab_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	string strTagName(lpcszVarName);
	if ( strTagName.Compare("options") == 0 )
	{
		_construct_options_branch(tr);
		return 0;
	}
	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 impMatlab_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	if ( nGetNDialog > 0 )
	{
		trGetN.trheader.Show = 0;
		trGetN.trFilter.Show = 0;
	}
	if(nGetNDialog > -1)
	{
		bool bResetFileInfo = false; ///---Sim 03-24-2009 QA80-13342 SUPPORT_OC_ACCESS_IMP_FILE_DATA_SELECTION
		
		string strFileName = trGetN.fname.strVal;
		
		/// Hong 04/10/07 v8.0597b IGNORE_FNAME$_WHEN_FROM_MENU
		if ( LTXF_FROM_GUI_MENU & dwCntrl ) // if from menu, ignore default value fname$
			strFileName = "";
		/// end IGNORE_FNAME$_WHEN_FROM_MENU
		
		if(is_empty_or_unassigned(strFileName))
		{			
			/// Hong 05/31/07 v8.0630 MORE_ON_ACCESS_TO_FDLOG
			//int nFilesRet = get_open_box_by_file_group(strFileName, "MatlabFiles", "MatlabFiles", true);
			int nFilesRet;
			if ( 0 != nGetNDialog )
			{
				int nShowOptionsDlg = 1;
				/// Hong 09/26/07 8.0709 CLEAN_OPEN_SAVE_DIALOG_TITLE_TO_DEFAULT
				//nFilesRet = get_open_box_by_file_group(strFileName, "MatlabFiles", _L("MatlabFiles"),
				//	OPENBOX_FLAG_MULTIFILES, NULL, NULL, _L("Show Options Dialog"), &nShowOptionsDlg);
				nFilesRet = get_open_box_by_file_group(strFileName, "MatlabFiles", NULL,
					OPENBOX_FLAG_MULTIFILES, NULL, NULL, STR_SHOW_OPT_DLG, &nShowOptionsDlg);
				/// end CLEAN_OPEN_SAVE_DIALOG_TITLE_TO_DEFAULT
				nRet = (nShowOptionsDlg ? XFEVT_PROCEED : XFEVT_PROCEED_NO_DLG);
			}
			else
			{
				//nFilesRet = get_open_box_by_file_group(strFileName, "MatlabFiles", _L("MatlabFiles"), true);
				nFilesRet = get_open_box_by_file_group(strFileName, "MatlabFiles", NULL, true); /// Hong 09/26/07 8.0709 CLEAN_OPEN_SAVE_DIALOG_TITLE_TO_DEFAULT
			}
			/// end MORE_ON_ACCESS_TO_FDLOG
			/// end THEME_FILENAME_WORKBOOK_AND_WORKSHEET
			if ( 0 == nFilesRet )
			{
				nRet = XFEVT_ABORT;
				//warning_msg_box(XFERR_UI_USER_CANCEL, false);
				return;
			}
			///---END HANDLE_USER_CANCEL_OPEN_FILE_BOX
			trGetN.fname.strVal = strFileName;
			bResetFileInfo = true; ///---Sim 03-24-2009 QA80-13342 SUPPORT_OC_ACCESS_IMP_FILE_DATA_SELECTION
		} ///---Sim 03-24-2009 QA80-13342 SUPPORT_OC_ACCESS_IMP_FILE_DATA_SELECTION			
		
		string strErrMsg;
		///---Sim 03-24-2009 QA80-13342 SUPPORT_OC_ACCESS_IMP_FILE_DATA_SELECTION
		//if( !file_name_event(trGetN, strErrMsg) )
		///Sophy 9/21/2009 QA80-14336 MORE_WORK_ON_HANDLE_NOT_SUPPORTED_DATA
		//if( !file_name_event(trGetN, strErrMsg) ) // why not reset bit?
		//if( !file_name_event(trGetN, strErrMsg) ) // why not reset bit?
		s_bFileValid = file_name_event(trGetN, strErrMsg);//I think here should reset the bit
		if ( !s_bFileValid )
		///end MORE_WORK_ON_HANDLE_NOT_SUPPORTED_DATA
		///---END QA80-13342 SUPPORT_OC_ACCESS_IMP_FILE_DATA_SELECTION
		{
			/// Hong 03/21/07 v8.0586 FIX_FAIL_DUMP_CORRECT_ERROR_STRING
			//nRet = XFEVT_ABORT;
			//warning_msg_box(strErrMsg, false);
			int nErrMsg = atoi(strErrMsg);
			nRet = XFEVT_ABORT;
			warning_msg_box(nErrMsg, false, 'E'); // should pass an int ///---Sim 06-19-2007 IMPROVE_WARNING_MESSAGE_POST_FUNCTION
			/// end FIX_FAIL_DUMP_CORRECT_ERROR_STRING
			return;
		}
		///---Sim 03-24-2009 QA80-13342 SUPPORT_OC_ACCESS_IMP_FILE_DATA_SELECTION			
		//}
		///---END QA80-13342 SUPPORT_OC_ACCESS_IMP_FILE_DATA_SELECTION
	}
}
//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 impMatlab_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
