#include "StdAfx.h"
#include <windowsx.h>									// ComboBox_GetCurSel
#include <assert.h>										// assert()
#include "UIBumpmapPanel.h"						// CUIBumpmapPanel
#include "resource.h"
#include "ImageProperties.h"					// CBumpProperties
#include <Commdlg.h>									// OPENFILENAME
#include <commctrl.h>									// TBM_SETRANGEMAX, TBM_SETRANGEMIN

CUIBumpmapPanel::CUIBumpmapPanel() :m_hTab_Normalmapgen(0)
{
	// Reflect slider bump notifications back to the control.
	this->reflectIDs.insert(IDC_NM_SLIDERBUMPBLUR);
	this->reflectIDs.insert(IDC_EDIT_BLURSTRENGTH);
	this->reflectIDs.insert(IDC_NM_SLIDERBUMPSTRENGTH);
	this->reflectIDs.insert(IDC_EDIT_BUMPSTRENGTH);
}

void CUIBumpmapPanel::InitDialog( HWND hWndParent, const bool bShowBumpmapFileName )
{
	// Initialise the values.
	m_blurStrengthValue.SetValue(0.0f);
	m_blurStrengthValue.SetMin(0.0f);
	m_blurStrengthValue.SetMax(10.0f);
	m_bumpStrengthValue.SetValue(0.0f);
	m_bumpStrengthValue.SetMin(0.0f);
	m_bumpStrengthValue.SetMax(15.0f);

	HWND hwnd=GetDlgItem(hWndParent,IDC_PROPTAB);assert(hwnd);
	RECT wnp;

	GetWindowRect(hwnd,&wnp);

	m_hTab_Normalmapgen=CreateDialogParam(g_hInst,MAKEINTRESOURCE(IDD_TAB_NORMALMAPGEN),hWndParent,WndProc,reinterpret_cast<LPARAM>(this));assert(m_hTab_Normalmapgen);
	SetWindowPos(m_hTab_Normalmapgen, HWND_TOP, wnp.left, wnp.top, 0,0,SWP_NOSIZE); 

	{
		int nCmdShow = bShowBumpmapFileName ? SW_SHOW : SW_HIDE;

		HWND hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_SRFO_ADDBUMP_TEXT0);assert(hwnd);

		ShowWindow(hwnd,nCmdShow);

		hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_SRFO_ADDBUMP_NAME);assert(hwnd);

		ShowWindow(hwnd,nCmdShow);

		hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_SRFO_ADDBUMP_CHOOSE);assert(hwnd);

		ShowWindow(hwnd,nCmdShow);
	}

	{
		hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_NM_SLIDERBUMPSTRENGTH);assert(hwnd);
		m_bumpStrengthSlider.SetDocument(&m_bumpStrengthValue);
		m_bumpStrengthSlider.SubclassWindow(hwnd);
	}

	{
		hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_NM_SLIDERBUMPBLUR);assert(hwnd);
		m_blurStrengthSlider.SetDocument(&m_blurStrengthValue);
		m_blurStrengthSlider.SubclassWindow(hwnd);
	}

	{
		hwnd = GetDlgItem(m_hTab_Normalmapgen,IDC_EDIT_BLURSTRENGTH);assert(hwnd);
		m_blurStrengthEdit.SetDocument(&m_blurStrengthValue);
		m_blurStrengthEdit.SubclassWindow(hwnd);
	}

	{
		hwnd = GetDlgItem(m_hTab_Normalmapgen,IDC_EDIT_BUMPSTRENGTH);assert(hwnd);
		m_bumpStrengthEdit.SetDocument(&m_bumpStrengthValue);
		m_bumpStrengthEdit.SubclassWindow(hwnd);
	}

	// bump to normal map conversion
	{
		HWND hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_NM_FILTERTYPE);assert(hwnd);

		SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"<none>");										// 0
		SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"GaussFilter");								// 1
//		SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"GaussFilter (with Alpha)");	// 2
		//		SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"soft 3x3");
		//		SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"very soft 4x4 (half texel shift)");
		//		SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)"ultra soft 5x5");
	}

}

HWND CUIBumpmapPanel::GetHWND() const
{
	return m_hTab_Normalmapgen;
}


void CUIBumpmapPanel::UpdateBumpStrength( const CBumpProperties &rBumpProp )
{
	this->m_bumpStrengthValue.SetValue(rBumpProp.GetBumpStrength());
}


void CUIBumpmapPanel::UpdateBlurAmount( const CBumpProperties &rBumpProp )
{
	this->m_blurStrengthValue.SetValue(rBumpProp.GetBumpBlurAmount());
}


void CUIBumpmapPanel::GetDataFromDialog( CBumpProperties &rBumpProp )
{
	{
		HWND hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_NM_BUMPINVERT);assert(hwnd);

		bool bInverted = Button_GetCheck(hwnd)!=0;

		rBumpProp.SetBumpStrength( bInverted ? -abs(rBumpProp.GetBumpStrength()) : abs(rBumpProp.GetBumpStrength()) );
	}

	{
		float fSign = sgn(rBumpProp.GetBumpStrength());

		rBumpProp.SetBumpStrength(this->m_bumpStrengthValue.GetValue() * fSign);
	}

	rBumpProp.SetBumpBlurAmount(this->m_blurStrengthValue.GetValue());

	{
		HWND hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_NM_FILTERTYPE);assert(hwnd);

		rBumpProp.SetBumpToNormalFilter(ComboBox_GetCurSel(hwnd));
	}

	{
		char str[2048];

		HWND dlgitem=::GetDlgItem(m_hTab_Normalmapgen,IDC_SRFO_ADDBUMP_NAME);

		GetWindowText(dlgitem,str,2048);

		rBumpProp.SetBumpmapName(str);
	}
}


void CUIBumpmapPanel::ChooseAddBump( HWND hParentWnd )
{
	OPENFILENAME ofn;

	memset(&ofn,0,sizeof(OPENFILENAME));
	char bumpmapname[1024]="";

	ofn.lStructSize=sizeof(OPENFILENAME);
	ofn.hwndOwner=hParentWnd;
	ofn.hInstance=(HINSTANCE)GetModuleHandle(NULL);
	ofn.lpstrFilter="TIF Files (*.TIF)\0*.TIF\0";
	ofn.lpstrDefExt="tif";
	ofn.lpstrFile=bumpmapname;
	ofn.nMaxFile=1024;
	ofn.lpstrTitle="Open optional Bumpmap (.TIF)";
	ofn.Flags=OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;

	if(!GetOpenFileName(&ofn))		// filename: bumpmapname
		bumpmapname[0]=0;

	HWND dlgitem=::GetDlgItem(m_hTab_Normalmapgen,IDC_SRFO_ADDBUMP_NAME);

	SetWindowText(dlgitem,bumpmapname);
}

void CUIBumpmapPanel::SetDataToDialog( const CBumpProperties &rBumpProp, const bool bEnableCustoms, const bool bInitalUpdate )
{
	// sub window normalmapgen
	HWND hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_NM_FILTERTYPE);assert(hwnd);
	SendMessage(hwnd,CB_SETCURSEL,rBumpProp.GetBumpToNormalFilter(),0);
	rBumpProp.EnableWindowBumpToNormalFilter(hwnd);

	if(bInitalUpdate)
	{
		UpdateBumpStrength(rBumpProp);
		UpdateBlurAmount(rBumpProp);
	}

	hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_EDIT_BUMPSTRENGTH);assert(hwnd);
	rBumpProp.EnableWindowBumpStrength(hwnd);
	hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_NM_SLIDERBUMPSTRENGTH);assert(hwnd);
	rBumpProp.EnableWindowBumpStrength(hwnd);
	hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_NM_BUMPINVERT);assert(hwnd);
	rBumpProp.EnableWindowBumpStrength(hwnd);

	hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_NM_SLIDERBUMPBLUR);assert(hwnd);
	rBumpProp.EnableWindowBumpBlurAmount(hwnd);
	hwnd=GetDlgItem(m_hTab_Normalmapgen,IDC_EDIT_BLURSTRENGTH);assert(hwnd);
	rBumpProp.EnableWindowBumpBlurAmount(hwnd);


	{
		HWND dlgitem=::GetDlgItem(m_hTab_Normalmapgen,IDC_SRFO_ADDBUMP_NAME);

		SetWindowText(dlgitem,rBumpProp.GetBumpmapName());
	}
}

BOOL CALLBACK CUIBumpmapPanel::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	// Get the instance pointer.
	CUIBumpmapPanel* pThis;
	if (uMsg == WM_INITDIALOG)
	{
		SetWindowLongPtr(hWnd, GWL_USERDATA, lParam);
		pThis = reinterpret_cast<CUIBumpmapPanel*>(static_cast<LONG_PTR>(lParam));
	}
	else
	{
		pThis = reinterpret_cast<CUIBumpmapPanel*>(static_cast<LONG_PTR>(GetWindowLongPtr(hWnd, GWL_USERDATA)));
	}

	// Reflect notifications back to (some of) the controls.
	BOOL bHandled = TRUE;
	LRESULT lResult = pThis->ReflectNotifications(hWnd, uMsg, wParam, lParam, bHandled, pThis->reflectIDs);
	if (bHandled)
		return lResult;

	HWND hParent=GetParent(hWnd);

	if(hParent)
		return SendMessage(hParent,uMsg,wParam,lParam)!=0?TRUE:FALSE;

	//	return DefWindowProc( hWnd, uMsg, wParam, lParam );
	return FALSE;
}

// Based on code from AtlWin.h
LRESULT CUIBumpmapPanel::ReflectNotifications(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled, const std::set<int>& reflectIDs)
{
	HWND hWndChild = NULL;

	switch(uMsg)
	{
	case WM_COMMAND:
		if(lParam != NULL)	// not from a menu
			hWndChild = (HWND)lParam;
		break;
	case WM_NOTIFY:
		hWndChild = ((LPNMHDR)lParam)->hwndFrom;
		break;
	case WM_PARENTNOTIFY:
		switch(LOWORD(wParam))
		{
		case WM_CREATE:
		case WM_DESTROY:
			hWndChild = (HWND)lParam;
			break;
		default:
			hWndChild = GetDlgItem(hWnd, HIWORD(wParam));
			break;
		}
		break;
	case WM_DRAWITEM:
		if(wParam)	// not from a menu
			hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem;
		break;
	case WM_MEASUREITEM:
		if(wParam)	// not from a menu
			hWndChild = GetDlgItem(hWnd, ((LPMEASUREITEMSTRUCT)lParam)->CtlID);
		break;
	case WM_COMPAREITEM:
		if(wParam)	// not from a menu
			hWndChild = GetDlgItem(hWnd, ((LPCOMPAREITEMSTRUCT)lParam)->CtlID);
		break;
	case WM_DELETEITEM:
		if(wParam)	// not from a menu
			hWndChild = GetDlgItem(hWnd, ((LPDELETEITEMSTRUCT)lParam)->CtlID);
		break;
	case WM_VKEYTOITEM:
	case WM_CHARTOITEM:
	case WM_HSCROLL:
	case WM_VSCROLL:
		hWndChild = (HWND)lParam;
		break;
	case WM_CTLCOLORBTN:
	case WM_CTLCOLORDLG:
	case WM_CTLCOLOREDIT:
	case WM_CTLCOLORLISTBOX:
	case WM_CTLCOLORMSGBOX:
	case WM_CTLCOLORSCROLLBAR:
	case WM_CTLCOLORSTATIC:
		hWndChild = (HWND)lParam;
		break;
	default:
		break;
	}

	if(hWndChild == NULL || reflectIDs.find(GetDlgCtrlID(hWndChild)) == reflectIDs.end())
	{
		bHandled = FALSE;
		return 1;
	}

	ATLASSERT(::IsWindow(hWndChild));
	return ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam);
}
