#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>


#include <GetNBox.h>
#include <image_utils.h>
//put additional include files here

//put your own support static functions here

enum {
	MASTER_CHANNEL = 0,
	RED_CHANNEL,
	GREED_CHANNEL,
	BLUE_CHANNEL,
	RGB_CHANNELS,
};

enum
{
	PKF_POSITIVE_DIRECTION = 1,
	PKF_NEGATIVE_DIRECTION,
  	PKF_BOTH_DIRECTION,
};

static void _check_set_rgb_valid(TreeNode trGetN)
{
	double r = trGetN.r.nVal;
	double g = trGetN.g.nVal;
	double b = trGetN.b.nVal;
	trGetN.r.nVal = (int)min(max(0., r),255.0);
	trGetN.g.nVal = (int)min(max(0., g),255.0);
	trGetN.b.nVal = (int)min(max(0., b),255.0);
}

static int _image_replace_color(pBITMAPHANDLE phBmp, int nR, int nG, int nB, int nFuzzi, int nAdjHue, int nAdjSaturation, int nAdjBightness)
{
	
	//HANDLE hData = GlobalAlloc(GHND,sizeof(COLORREPLACE) * (nHighThr - nLowThr + 1));
	//LPCOLORREPLACE pColorReplace = (LPCOLORREPLACE)GlobalLock(hData); 
	
	COLORREPLACE ColorReplace;
	ColorReplace.uStructSize = sizeof(COLORREPLACE);
	ColorReplace.crColor    = RGB(nR,nG,nB);
	ColorReplace.uFuzziness = nFuzzi; 
	
	//int n = 0;
	//for(int ii = nLowThr; ii <= nHighThr; ii++)
	//{
		//pColorReplace[n].uStructSize = sizeof(COLORREPLACE);
		//pColorReplace[n].crColor    = RGB(ii,ii,ii);
		//pColorReplace[n].uFuzziness = nFuzzi; 
		//n ++;
	//}

	int nBightness = nAdjBightness*10;
	int nHue = nAdjHue * 100;
	int nSaturation = nAdjSaturation*10;
	int	nRet = L_ColorReplaceBitmap(phBmp, &ColorReplace,  1, nHue, nSaturation, nBightness);//uColorCount, nHue, nSaturation, nBrightness))
//
	//GlobalUnlock(hData);
	//GlobalFree(hData);
		
	return nRet;
}


void imgColorReplace(const Image& img, Image& oimg, const int& fuzzi, const int& r, const int& g, const int& b, const int& adj_b, const int& adj_s, const int& adj_h)
{
	
	oimg.SetLBmp(img.GetLBmp(), TRUE);
	pBITMAPHANDLE phBmp = oimg.GetLBmp();
	
	int nRet = _image_replace_color(phBmp, r, g, b, fuzzi, adj_h, adj_s, adj_b);
	
}

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

}

int imgColorReplace_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 imgColorReplace_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 imgColorReplace_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 pPreviewBitmap;
	pPreviewBitmap=pimgCntrl->GetBitmapHandlePtr();
	
	_check_set_rgb_valid(trGetN);


	int nRet = _image_replace_color(pPreviewBitmap, trGetN.r.nVal, trGetN.g.nVal,trGetN.b.nVal,
								trGetN.fuzzi.nVal, trGetN.adj_h.nVal, trGetN.adj_s.nVal, trGetN.adj_b.nVal);

	if( SUCCESS != nRet)
	{
		bOKEnable = false;
		strErrMsg = nRet;
	}
	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)
{
	_check_set_rgb_valid(trGetN);
	int nRet = _image_replace_color(pPreviewBitmap, trGetN.r.nVal, trGetN.g.nVal,trGetN.b.nVal,
								trGetN.fuzzi.nVal, trGetN.adj_h.nVal, trGetN.adj_s.nVal, trGetN.adj_b.nVal);
	if( SUCCESS != nRet)
	{
		bOKEnable = false;
		strErrMsg = nRet;
	}
	
	bUpdatePreview = true;
}
	
int GetNImageBox_imgColorReplace(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);	
}
