#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	sign_unsigned,
	sign_signed,
	sign_float,
};
///////////////////////////////////////////////////////////////////////
//////// modification log
///////////////////////////////////////////////////////////////////////
//CPY 09-18-2008 QA80-12203 2DARRAY_IMPORT_TO_MATRIXOBJ created this XF
//CPY 11/29/08 QA70-12203 NEED_SUPPORT_FOR_IMPORT_TO_WKS
/// Hong 01/22/09 FIX_OFFSET_OPTION_NOT_WORK
/// Sim 02-19-2009 FIX_DUMP_ERROR_MSG
/// Sim 07-31-2009 FIX_SHOW_GOOD_ERROR_MSG_FOR_FLOAT_DATA
/// Hong 02/25/10 QA80-12203-P4 IMPORT_TO_WKS_SUPPORT_SPECIFIED_COL
/// CPY 4/20/10 QA81-15336 FLOAT_SHOULD_BE_SUPPORTED
/// Sim 04-27-2010 ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
/// Sim 04-30-2010 QA81-15336-P1 FIX_ERR_MSG_MISSING_WHEN_CLICK_OUT_RESULTS_LOG

//put your own support static functions here
#include <GetNbox.h> ///---Sim 11-20-2006 SUPPORT_DND_OPEN_DIALOG
#include <okocUtils.h>
///---Sim 04-27-2010 ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
#include <..\originlab\fu_utils.h>
///---END ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK

#define STR_OUT_RESULTS_LOG "OutResultsLog" ///---Sim 04-30-2010 QA81-15336-P1 FIX_ERR_MSG_MISSING_WHEN_CLICK_OUT_RESULTS_LOG		

// this function will be moved to shared system oc file later when needed in some other places
int get_range_layer_type(const Range& dr, bool bChkSingleRange = true)
{
	if(bChkSingleRange && dr.GetNumRanges() != 1)
		return -1;
	
	string strBook, strSheet;
	if(!dr.GetBookSheet(strBook, strSheet))
		return -2;
		
	WorksheetPage wp(strBook);
	if(wp)
		return EXIST_WKS;
	MatrixPage	mp(strBook);
	if(mp)
		return EXIST_MATRIX;
	
	GraphPage gp(strBook);
	if(gp)
		return EXIST_PLOT;
	
	return -3;
}
	
///---Sim 04-27-2010 ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
static void generate_using_filter_tree(TreeNode& trUsingFilter, const TreeNode& trGetNOptions,
	const int& ncols, const int& bytes, const int& sign, const int& bigend, const int& offset)
{
	Tree trGetN;
	TreeNode tr = trGetN.AddNode("options");
	if ( tr )
		tr.Replace(trGetNOptions, true, true);
	trGetN.ncols.nVal = ncols;
	trGetN.bytes.nVal = bytes;
	trGetN.sign.nVal = sign;
	trGetN.bigend.nVal = bigend;
	trGetN.offset.nVal = offset;
	
	update_getn_LT_variables(trGetN, STR_XF_NAME_IMP2DBIN, true);
	
	/*
	if ( trGetN.options )
	{
		TreeNode trGetNLT = trGetN.options.GetNode(STR_NODE_NAME_GETN_LT);
		if ( trGetNLT )
			trGetNLT.Show = true;
	
		trUsingFilter.Replace(trGetN.options, true, true, true);
	}
	else
	{
		fuPrepareDefault(trUsingFilter, FILTER_TYPE_XFUNC);
	}
	*/
	generate_using_filter_tree_by_getn_tree(trUsingFilter, trGetN.options);
}
///---END ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK	



void impBin2d(const string& fname, const int& ncols, const int& bytes, const int& sign, const int& bigend, const int& offset, Range& orng, const TreeNode& options, const int& reimp)
{
	
	DWORD dw = GETLC_PAGE_SHORT_NAME | GETLC_COL_SHORT_NAME | GETLC_NO_ROWS;
	string strRange = orng.GetDescription(dw);
	//---- CPY 11/29/08 QA70-12203 NEED_SUPPORT_FOR_IMPORT_TO_WKS
	//int nRet = okoc_binary_mat_import(fname, strRange, ncols, bytes, sign, bigend);
	//if(nRet != 0)
	//	printf("okoc_binary_mat_import failed, err = %d\n", nRet);
	int nType = get_range_layer_type(orng);
	///---Sim 04-27-2010 ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
	int c1,c2;
	Page pg;
	Datasheet ds;
	if ( !GetRangeInfo(orng, ds, pg, c1, c2) )
		XF_THROW(XFERR_INVALID_RANGE);
		
	Tree trUsingFilter;
	generate_using_filter_tree(trUsingFilter, options,
		ncols, bytes, sign, bigend, offset);
	Tree trInfo;
	///---END ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
	int nRet;	
	/// Hong 01/22/09 FIX_OFFSET_OPTION_NOT_WORK
	int	nOffset = offset;
	if ( nOffset < 0 )
		nOffset = 0;
	/// end FIX_OFFSET_OPTION_NOT_WORK
	if(EXIST_MATRIX == nType)
		/// Hong 01/22/09 FIX_OFFSET_OPTION_NOT_WORK
		//nRet = okoc_binary_mat_import(fname, strRange, ncols, bytes, sign, bigend);
		nRet = okoc_binary_mat_import(fname, strRange, ncols, bytes, sign, bigend, nOffset);
		/// end FIX_OFFSET_OPTION_NOT_WORK
	else if(EXIST_WKS == nType)
	{
		MatrixPage mp;
		mp.Create("Origin", CREATE_HIDDEN | CREATE_SET_MISSING_IN_MANAGER);
		strRange.Format("[%s]1!1",mp.GetName());
		/// Hong 01/22/09 FIX_OFFSET_OPTION_NOT_WORK
		//nRet = okoc_binary_mat_import(fname, strRange, ncols, bytes, sign, bigend);
		nRet = okoc_binary_mat_import(fname, strRange, ncols, bytes, sign, bigend, nOffset);
		/// end FIX_OFFSET_OPTION_NOT_WORK
		if(0 == nRet)
		{
			///---Sim 04-27-2010 ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
			//int c1,c2,r1,r2;
			//Worksheet wks;
			//if(orng.GetRange(0, r1, c1, r2, c2, wks))
			Worksheet wks = ds;
			if ( wks )
			///---END ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
			{
				MatrixLayer ml = mp.Layers(0);
				MatrixObject mobj = ml.MatrixObjects(0);
				matrixbase& mb = mobj.GetDataObject();
				/// Hong 02/25/10 QA80-12203-P4 IMPORT_TO_WKS_SUPPORT_SPECIFIED_COL
				//mb.CopyTo(wks, 0, 0, -1, -1, 0, 0, false, false);
				mb.CopyTo(wks, 0, 0, -1, -1, 0, c1, false, false);
				/// end IMPORT_TO_WKS_SUPPORT_SPECIFIED_COL
			}
			else
				nRet = -3001;
		}
		mp.Destroy();
	}
	else
		XF_THROW(CER_NO_WORKSHEET);
	//---- end NEED_SUPPORT_FOR_IMPORT_TO_WKS
	///---Sim 04-27-2010 ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
	if ( 0 == nRet )
	{
		// get header block
		TreeNode trHeader = trInfo.AddNode("Header");
		if ( trHeader )
		{
			TreeNode trBlock = trHeader.AddNode("Block");
			if ( trBlock && nOffset > 0 )
			{
			    file ff;
			    bool bOK = ff.Open(fname, file::modeRead);
			    if( bOK )
			    {
				    vector<byte> vbytes;
				    vbytes.SetSize(nOffset);
				    byte* pBuf = vbytes;
				    ff.Read(pBuf, nOffset);
				    
				    vector<int> vints;
				    vints = vbytes;				    
				    trBlock.nVals = vints;
				    
				    ff.Close();
			    }
			}
		}
		
		DataRange dr;
		dr = orng;
		
		if ( !reimp )
			impinfo_UpdateExistingData(pg, dr);
		
		Tree trRange;			
		if (dr && dr.GetNumData() > 0)
			getRangeInfo(trRange, dr);
		
		impinfo_AddFile(ds, fname, trInfo, ASCIMP_MODE_NEW_SHEETS, FILTER_TYPE_XFUNC, trUsingFilter, 1, trRange, reimp);
	}
	///---END ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
	
	if(nRet != 0)
	///---Sim 02-19-2009 FIX_DUMP_ERROR_MSG
	{
		//printf("okoc_binary_mat_import failed, err = %d\n", nRet);
		string str;
		str.Format("okoc_binary_mat_import failed, err = %d\n", nRet);
		warning_msg_box(str, false);
	}
	///---END FIX_DUMP_ERROR_MSG
	
}

//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 impBin2d_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return impBin2d_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	///---Sim 07-31-2009 FIX_SHOW_GOOD_ERROR_MSG_FOR_FLOAT_DATA
	string strNodeName(lpcszNodeName);
	if ( GETNE_ON_INIT == nEventID || GETNE_ON_THEME == nEventID
		|| 0 == strNodeName.CompareNoCase(STR_OUT_RESULTS_LOG) ///---Sim 04-30-2010 QA81-15336-P1 FIX_ERR_MSG_MISSING_WHEN_CLICK_OUT_RESULTS_LOG
		|| 0 == strNodeName.CompareNoCase("bytes") || 0 == strNodeName.CompareNoCase("sign") )
	{
		if ( trGetN.sign.nVal > 1 )
		{
			//---- CPY 4/20/10 QA81-15336 FLOAT_SHOULD_BE_SUPPORTED
			//if ( trGetN.bytes.nVal < 8 )
			if ( trGetN.bytes.nVal < 4)
			//----
			{
				strErrMsg = XFERR_FLOAT_DATA_INVALID_ELEM_SIZE;
				bOKEnable = false;
			}
		}		
		return true;
	}
	///---END FIX_SHOW_GOOD_ERROR_MSG_FOR_FLOAT_DATA	
	
	return false;
	

}

int impBin2d_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	///---Sim 04-27-2010 ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
	if ( 0 == strcmp(lpcszVarName, "options") )
	{
		constructOptionsForXF(tr, (DWORD)0);
		
		TreeNode trGetNLT = check_add_getn_LT_to_filter_options(tr);
		TreeNode trNode;
		
		trNode = trGetNLT.AddNode("ncols");
		trNode.ID = TRGP_DOUBLE;
		trNode.DataID = GET_FILTER_USER_DATAID(1);
		
		trNode = trGetNLT.AddNode("bytes");
		trNode.ID = TRGP_DOUBLE;
		trNode.DataID = GET_FILTER_USER_DATAID(2);
		
		trNode = trGetNLT.AddNode("sign");
		trNode.ID = TRGP_DOUBLE;
		trNode.DataID = GET_FILTER_USER_DATAID(3);
		
		trNode = trGetNLT.AddNode("bigend");
		trNode.ID = TRGP_DOUBLE;
		trNode.DataID = GET_FILTER_USER_DATAID(4);
		
		trNode = trGetNLT.AddNode("offset");
		trNode.ID = TRGP_DOUBLE;
		trNode.DataID = GET_FILTER_USER_DATAID(5);
		
		fuSetXFunctionName(tr, "impBin2d");
	
		return 0;
	}	
	///---END ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
	
	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 impBin2d_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	///---Sim 04-27-2010 ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
	if(nGetNDialog > 0)
	{
		trGetN.options.Show = false;
	}	
	///---END ORG-29-P2 IMP_2D_BIN_SUPPORT_FILTER_SETTINGS_AND_SAVE_FILE_INFO_INTO_BOOK
	
}
//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 impBin2d_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
