#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
//put additional include files here
#include <sys_utils.h>
#include <..\originlab\fu_utils.h>
#include <..\originlab\XFunctionEx.h>
#include <..\System\oExtFile.h>
#include <okocutils.h>



#ifdef _FOR_SMART_LOADING_ONLY
	#include <..\Originlab\file_utils.h>
#endif

#include <..\Originlab\IgorProFile.h>
//put your own support static functions here

///modify log:
//////Sophy 1/8/2010 IMPORT_IGORPRO_FROM_SCRIPT_FAIL_TO_OPEN_FILE

static bool s_bFileValid = true;
#define OK_SURE(_OK_ENABLE) _OK_ENABLE = s_bFileValid; //also can be _OK_ENABLE = s_bFileValid && s_bSetting


void igp_clean_project()
{
	Project.ActivateFolder("/");
	Folder fld = Project.ActiveFolder();
	
	foreach(Folder subpag in fld.Subfolders){
		fld.RemoveSubFolder(subpag.GetName());
	}
	
	foreach(PageBase pg in fld.Pages){
		pg.Destroy();
	}

}

// Construct selection tree for pxp project
void con_tr_pxp_to_selection(TreeNode &tr1, TreeNode &tr2)
{
	string str;
	int val;
	foreach(TreeNode cNode in tr1.Children){
		if (cNode.GetNodeCount() > 0){
			TreeNode cNode2 = tr2.AddNode();
			cNode.GetAttribute(STR_LABEL_ATTRIB, str);
			cNode2.SetAttribute(STR_LABEL_ATTRIB, str);
			cNode.GetAttribute(STR_DATAID_ATTRIB, val);
			cNode2.SetAttribute(STR_DATAID_ATTRIB, val);			
			cNode.GetAttribute(STR_DATA_ATTRIB, val);
			cNode2.SetAttribute(STR_DATA_ATTRIB, val);
			cNode2.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_CHECK_CONTROL | GETNBRANCH_OPEN|GETNBRANCH_CHECK_CONTROL_ONE_EVENT);
			con_tr_pxp_to_selection(cNode, cNode2);
		}
		else{
			TreeNode cNode2 = tr2.AddNumericNode(1, "", TRGP_CHECK);
			cNode.GetAttribute(STR_LABEL_ATTRIB, str);		
			cNode2.SetAttribute(STR_LABEL_ATTRIB, str);
			cNode.GetAttribute(STR_DATAID_ATTRIB, val);
			cNode2.SetAttribute(STR_DATAID_ATTRIB, val);
			cNode.GetAttribute(STR_DATA_ATTRIB, str);
			cNode2.SetAttribute(STR_DATA_ATTRIB, str);
		}
	}
}

// Support whole folder selection
int update_selection_tree(TreeNode &trSelection)
{
	int nStop = 0;
	foreach(TreeNode cNode in trSelection.Children){
		if (cNode.GetNodeCount() > 0){
			int val = update_selection_tree(cNode);
			cNode.SetAttribute(STR_STOP_ATTRIB, val);
			if (1 == val)
				nStop = 1;
		}
		else{
			if (1 == cNode.nVal)
				nStop = 1;
		}
	}
	return nStop;
}

static BOOL construct_tree_FileInfo(string strFileName, TreeNode& trInfo)
{
	if ( !strFileName.IsFile() )
		return false;
	string strInfo;
	strInfo.Format("File Size: %s ", GetFileSize(strFileName));
	trInfo.strVal = strInfo;
	trInfo.Enable = 0;
	return true;
}

static bool _construct_branch(TreeNode& trFile, string strFileName)
{		
	Tree trStruct;
	IgorProFile fin(strFileName);
	if(fin.GetType() == TYPE_PXP){
		fin.Open();
		fin.ReadHeader(trStruct);
		fin.Close();
		
		con_tr_pxp_to_selection(trStruct, trFile);
	}
	else
	{
		// ibw file
	}
	
	return true;
}


static bool _construct_GUI_tree(TreeNode& trGUI, vector<string>& vsFileNames)
{
	int nCount = vsFileNames.GetSize();
	TreeNode trFile;

	trGUI.RemoveChildrenWithPrefix();

	string strTagName;
	for ( int nIndex = 0; nIndex < nCount; nIndex++ )
	{
		strTagName.Format("file%d", nIndex+1);
		trFile = trGUI.AddNode(strTagName);
		trFile.SetAttribute(STR_LABEL_ATTRIB, GetFileName(vsFileNames[nIndex], false));
		/// Hong 04/14/09 SHRINK_FILE_SELECTION_TO_SAVE_SPACE
		//trFile.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_CHECK_CONTROL | GETNBRANCH_OPEN|GETNBRANCH_CHECK_CONTROL_ONE_EVENT);
		trFile.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_CHECK_CONTROL | GETNBRANCH_CHECK_CONTROL_ONE_EVENT);
		/// end SHRINK_FILE_SELECTION_TO_SAVE_SPACE
			
		// Load File Info
		TreeNode trFileInfo;
		trFileInfo = trFile.AddNode("FileInfo");
		trFileInfo.SetAttribute(STR_LABEL_ATTRIB, STR_FILE_INFO);	///Sophy 9/21/2009 SET_LABEL_ON_GUI_FOR_TRANSLATION
		// Get file info
		if ( !construct_tree_FileInfo(vsFileNames[nIndex], trFileInfo) )
			return false;

		// Constract selection tree
		if ( !_construct_branch(trFile, vsFileNames[nIndex]) )
			return false;

	}
	trGUI.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
	
	return true;
}


static bool construct_tree_setting(const string& strMultiFileName, TreeNode& trSetting)
{
	StringArray vsFileNames;
	separate_multiline_files(strMultiFileName, vsFileNames); 

	return _construct_GUI_tree(trSetting, vsFileNames);
}


static bool file_name_event(TreeNode& trGetN, string& strErrMsg, bool bClearSetting = true)
{
	string strFileName = trGetN.fname.strVal;
	TreeNode trNode = trGetN.trfiles;

	if ( bClearSetting )
		trNode.RemoveChildrenWithPrefix();

	if ( !construct_tree_setting(strFileName, trNode) )
	{
		trNode.RemoveChildrenWithPrefix();
		strErrMsg = CER_INVALID_IMPORT_DATA_FILE;
		return false;
	}

	return true;
}


void impIgorPro(const string& fname, const TreeNode& trfiles, const TreeNode& options, Range& orng, TreeNode& trheader, const int& reimp)
{
	
	Tree tr, trTmp;
	string strRoot = Project.ActiveFolder().GetPath();
	Worksheet wks;
	
	IgorProFile igpFile(fname);
	if(igpFile.Open() != IMPERR_FILE_OPEN){
		// Support only one file
		if(trfiles.GetNodeCount() > 1)
			ASSERT(false);
		TreeNode trPXP = trfiles.FirstNode;		
		
		// Fisher: No need to clean up project
		//TreeNode trTemp = options.GetNode("CleanProject");
		//if(trTemp.nVal == true)
		//	igp_clean_project();		
		
		// Support from script access
		if(igpFile.GetType() == TYPE_PXP){
			if(!trPXP){
				igpFile.ReadHeader(trTmp);
				con_tr_pxp_to_selection(trTmp, tr);
				trPXP = tr;
			}
			update_selection_tree(trPXP);
			
			igpFile.ImportALL(trPXP, strRoot, wks);			
		}
		else
		{
			int r1,r2,c1,c2; 
			Datasheet ds;
			WorksheetPage wp;
			if ( !GetRangeInfo(orng, ds, wp, c1, c2) )
				XF_THROW(XFERR_INVALID_RANGE);
			wks = ds;
			//if(!wks)
			//	XF_THROW(CER_INVALID_WKS);
			igpFile.ImportIBW(wks, c1);
		}
	
	}
	
}

//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 impIgorPro_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return impIgorPro_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	OK_SURE(bOKEnable);
	
	if ( GETNE_ON_INIT == nEventID || GETNE_ON_THEME == nEventID )
	{
		s_bFileValid = file_name_event(trGetN, strErrMsg, false);
		OK_SURE(bOKEnable);
		return true;
	}
	
	string strTagName = lpcszNodeName;
	if(strTagName == "fname")
	{
		s_bFileValid = file_name_event(trGetN, strErrMsg);
		OK_SURE(bOKEnable);
		return true;
	}
	
	return false;
	

}

int impIgorPro_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	
	string strTagName = lpcszVarName;
	
	if ( 0 == strcmp(lpcszVarName, "options") )
	{
		//constructOptionsForXF(tr, false, false, false, false, false);
		
		fuSetShowTime(tr, 0);
		fuSetXFunctionName(tr, "impIgorPro");
		
		// Add user clean project checkbox
		//TreeNode trTemp = tr.AddNode("CleanProject");
		//trTemp.SetAttribute(STR_LABEL_ATTRIB, _L("Clean up the existing project"));
		//trTemp.ID = TRGP_CHECK;
		//trTemp.DataID = GET_USER_DATAID(1);
		//trTemp.nVal = 1;
	
		return 0;
	}
	
	if ( strTagName == "trfiles" )
	{
		return 0;
	}
	
	return -1;
	
}
//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 impIgorPro_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	
	if(nGetNDialog > 0)
	{
		string strFile = trGetN.fname.strVal;
		if(strFile == "fname$")
			trGetN.fname.strVal = "";
	
		trGetN.trheader.Show = 0;
		if(1 == trGetN.reimp.nVal)
		{
			trGetN.fname.Enable = 2;
			trGetN.orng.Enable = 2;
			trGetN.trfiles.Enable = 2;
		}
	
	}
	
	if(nGetNDialog >= 0)
	{
	
		if ( LTXF_FROM_GUI_MENU == dwCntrl )
			trGetN.fname.strVal = "";
	}
	
	if(nGetNDialog > -1)
	{
		bool bResetFileInfo = false; ///---Sim 03-24-2009 QA80-13342 SUPPORT_OC_ACCESS_IMP_FILE_DATA_SELECTION
		
		string strFileName = trGetN.fname.strVal;
	
		if ( LTXF_FROM_GUI_MENU & dwCntrl )
			strFileName = "";
	
		if(is_empty_or_unassigned(strFileName))
		{			
			int nFilesRet;
			if ( 0 != nGetNDialog )
			{
				int nShowOptionsDlg = 1;
				nFilesRet = get_open_box_by_file_group(strFileName, "IGOR","IGOR",
					0, NULL, NULL, STR_SHOW_OPT_DLG, &nShowOptionsDlg);
				nRet = (nShowOptionsDlg ? XFEVT_PROCEED : XFEVT_PROCEED_NO_DLG);
			}
			else
			{
				///Sophy 1/8/2010 IMPORT_IGORPRO_FROM_SCRIPT_FAIL_TO_OPEN_FILE
				//should not use true here, if so, there will be 0x0a at the end of the string
				//(strangely, String::GetLength() fail to detect the 0x0a character), this extra character will cause file::Open fail since the file path is not correct any longer.
				//nFilesRet = get_open_box_by_file_group(strFileName, "IGOR", "IGOR", true);
				nFilesRet = get_open_box_by_file_group(strFileName, "IGOR", "IGOR", false);
				///end IMPORT_IGORPRO_FROM_SCRIPT_FAIL_TO_OPEN_FILE
			}
	
			if ( 0 == nFilesRet )
			{
				nRet = XFEVT_ABORT;
				return;
			}
			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) )
		if( !file_name_event(trGetN, strErrMsg, bResetFileInfo) )
		///---END QA80-13342 SUPPORT_OC_ACCESS_IMP_FILE_DATA_SELECTION
		{
			int nErrMsg = atoi(strErrMsg);
			nRet = XFEVT_ABORT;
			warning_msg_box(nErrMsg, false, 'E');
			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 impIgorPro_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
