#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	c_rgb,
	c_red,
	c_green,
	c_blue,
};


#include <GetNBox.h>
#include <image_utils.h>
#include <..\Originlab\matdata_utils.h>	

enum {
	AFF_CHANNELS = 0,
	AFF_GRAYSCALE ,
};
	

static int _image_binarize(BITMAPHANDLE* pLBmp,UINT uLowThreshold, UINT uHighThreshold, int nChannel)
{
    vector<uint> vChannels = {IDB_CHANNEL_MASTER, IDB_CHANNEL_RED, IDB_CHANNEL_GREEN, IDB_CHANNEL_BLUE};
    
	int nMaxVal=get_image_data_max_val(pLBmp);
	
	if(uLowThreshold<0 || uLowThreshold>nMaxVal || uHighThreshold<0 || uHighThreshold>nMaxVal)
	{
		return INTOPTN_OUT_OF_RANGE;
	}
	
	if(uLowThreshold > uHighThreshold)
		return XFERR_LOW_LARGER_THAN_HEIGH;
	
	//if(nAffect == AFF_GRAYSCALE)
	//{
		//if(GRAY_NO == L_IsGrayScaleBitmap(pLBmp))
		//{
			//L_GrayScaleBitmap(pLBmp, 8);
		//}
		//
		//return  L_IntensityDetectBitmap( pLBmp, uLowThreshold, uHighThreshold, 
								  //RGB(0, 0, 0), RGB(255, 255, 255), IDB_CHANNEL_MASTER);
	//}
	//else
	//{
	return  L_IntensityDetectBitmap( pLBmp, uLowThreshold, uHighThreshold,  
	                              RGB(0, 0, 0), RGB(255, 255, 255), vChannels[nChannel]);		
	//}	
	

}

static void _init_threshold_value(TreeNode& trGetN , BITMAPHANDLE* pBitmap)
{
	int t1 = trGetN.t1.nVal;
	int t2 = trGetN.t2.nVal;
	int nMaxVal;
	nMaxVal=get_image_data_max_val(pBitmap);
	
	string strT;
	strT.Format("%d|%d|%d",0,nMaxVal,255);	
	trGetN.t1.SetAttribute(STR_COMBO_ATTRIB,strT);
	trGetN.t2.SetAttribute(STR_COMBO_ATTRIB,strT);
	
	if((t1 == 0 && t2 == 0)||(t1 > nMaxVal) || (t2 > nMaxVal))
	{
		trGetN.t1.nVal = nMaxVal * 0.2;
		trGetN.t2.nVal = nMaxVal * 0.8;	
	}

}

void imgBinary(const Image& img, const int& t1, const int& t2, const int& c, Image& oimg)
{
	
	
	oimg.SetLBmp(img.GetLBmp(), TRUE);
	pBITMAPHANDLE phBmp = oimg.GetLBmp();
	
	//int nRet = _image_binarize(phBmp, t1, t2, aff, c);
	int nRet = _image_binarize(phBmp, t1, t2,  c);
		
	if(nRet < MAX_ERROR_CODE_FROM_LT)
		XF_THROW_EX(XFERR_LEADTOOLS_FUNCTION_UNKNOWN_ERR, nRet);
	
	if(nRet !=  SUCCESS)
		XF_THROW(nRet);
}

//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 imgBinary_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return imgBinary_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	return true;
	//return false;

}

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


// this is called when the GetNImageBox dialog is open
// bUpdateGrid = false when entering this function
// you need to set bUpdateGrid = true if you need to modify trGetN data and want to see the
// grid updated, for example
// trGetN.angle.nVal = 0; // force rotation to init to 0
// bUpdateGrid = true;
// bOKEnable is default = true, you may add code to check trGetN and decide that the OK button should be disabled, then set this to false
// example: 
// if(0==trGetN.angle.nVal) // no change, no point to click Ok to do nothing
//    bOKEnable = false; 
static void GetNImageBox_OnInit(TreeNode& trGetN, ImageControlBase* pimgCntrl, bool& bUpdateGrid, bool& bOKEnable, string& strErrMsg)
{
	pBITMAPHANDLE ph;
	ph=pimgCntrl->GetBitmapHandlePtr();
	
	//int nMaxVal;
	//nMaxVal=get_image_data_max_val(ph);
	//
	//string strT;
	//strT.Format("%d|%d|%d",0,nMaxVal,255);	
	//trGetN.t1.SetAttribute(STR_COMBO_ATTRIB,strT);
	//trGetN.t2.SetAttribute(STR_COMBO_ATTRIB,strT);
	//trGetN.t1.nVal = nMaxVal * 0.2;
	//trGetN.t2.nVal = nMaxVal * 0.8;
	_init_threshold_value(trGetN, ph);
	
	trGetN.c.Show = true;

	int nRet = _image_binarize(ph,trGetN.t1.nVal,trGetN.t2.nVal, trGetN.c.nVal);
	if( SUCCESS != nRet)
	{
		strErrMsg = nRet;
		bOKEnable = false;
	}
	
	bUpdateGrid = true;

}

// this is called whenever any controls in the grid is modified by the user
// upon entering function
// bUpdatePreview = true;// to update the preview image pPreviewBitmap
// bUpdateGrid = false; // event triggered by grid change, so default no need to update again
// if you want to modify other controls in the grid, then you need to set bUpdateGrid to true
// bOKEnable is default = true, you may add code to check trGetN and decide that the OK button should be disabled, then set this to false
static void GetNImageBox_OnChange(BITMAPHANDLE* pPreviewBitmap, TreeNode& trGetN, TreeNode& trNode, ImageControlBase* pimgCntrl, bool& bUpdatePreview, bool& bUpdateGrid, bool& bOKEnable, string& strErrMsg)
{
	//if(trGetN.aff.nVal == AFF_CHANNELS)
		//trGetN.c.Show = true;
	//else
		//trGetN.c.Show = false;
	if(!trNode.IsValid())//change theme only for temp, joseph should give more clearer mark later
	{
		_init_threshold_value(trGetN, pPreviewBitmap);
		bUpdateGrid = true;
	}		
	
//	if( SUCCESS != _image_binarize(pPreviewBitmap,trGetN.t1.nVal,trGetN.t2.nVal, trGetN.aff.nVal, trGetN.c.nVal))
	int nRet = _image_binarize(pPreviewBitmap,trGetN.t1.nVal,trGetN.t2.nVal,  trGetN.c.nVal);
	if( SUCCESS != nRet)
	{
		strErrMsg = nRet;
		bOKEnable = false;
	}
	
	bUpdatePreview = true;
}
	
int GetNImageBox_imgBinary(TreeNode& trGetN, int nRow, int nCol, TreeNode& trNode, DWORD dwCntrl, int nType, WndContainer& theDlg, ImageControlBase* pimgCntrl)
{
	return xf_GetNImageBox_event_handler(trGetN, nRow, nCol, trNode, dwCntrl, nType, pimgCntrl,
								GetNImageBox_OnInit, GetNImageBox_OnChange);	
}
