// LightWnd.cpp : implementation file
//

#include "stdafx.h"
#include "mw4gameed.h"
#include "LightWnd.h"
#include "EditorWayPoint.h"



float REDUCEANGLE(float x)
{
	float whole, dec, div, tmp = x;

	whole = float(int(tmp));
	dec = tmp - whole;

	div = float(int(whole / 360));
	x = whole - (div * 360) + dec;

	return (x);
}

/////////////////////////////////////////////////////////////////////////////
// CLightWnd dialog


CLightWnd::CLightWnd(CWnd* pParent /*=NULL*/)
	: CDialog(CLightWnd::IDD, pParent)
{
	//{{AFX_DATA_INIT(CLightWnd)
	//}}AFX_DATA_INIT

	light = NULL;
}


void CLightWnd::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CLightWnd)
	DDX_Control(pDX, IDC_SPINANGLE, m_AngleSpin);
	DDX_Control(pDX, IDC_EDITANGLE, m_AngleEdit);
	DDX_Control(pDX, IDC_SPINOUTERRADIUS, m_OuterRadiusSpin);
	DDX_Control(pDX, IDC_SPINLIGHTZ, m_ZSpin);
	DDX_Control(pDX, IDC_SPINLIGHTYAW, m_YawSpin);
	DDX_Control(pDX, IDC_SPINLIGHTY, m_YSpin);
	DDX_Control(pDX, IDC_SPINLIGHTX, m_XSpin);
	DDX_Control(pDX, IDC_SPINLIGHTROLL, m_RollSpin);
	DDX_Control(pDX, IDC_SPINLIGHTPITCH, m_PitchSpin);
	DDX_Control(pDX, IDC_SPININNERRADIUS, m_InnerRadiusSpin);
	DDX_Control(pDX, IDC_EDITOUTTERRADIUS, m_OuterRadius);
	DDX_Control(pDX, IDC_EDITLIGHTZ, m_ZEdit);
	DDX_Control(pDX, IDC_EDITLIGHTROLL, m_RollEdit);
	DDX_Control(pDX, IDC_EDITLIGHTYAW, m_YawEdit);
	DDX_Control(pDX, IDC_EDITLIGHTY, m_YEdit);
	DDX_Control(pDX, IDC_EDITLIGHTX, m_XEdit);
	DDX_Control(pDX, IDC_EDITLIGHTPITCH, m_PitchEdit);
	DDX_Control(pDX, IDC_EDITINNERRADIUS, m_InnerRadiusEdit);
	DDX_Control(pDX, IDC_REDSLIDER, m_RedSlider);
	DDX_Control(pDX, IDC_GREENSLIDER, m_GreenSlider);
	DDX_Control(pDX, IDC_BLUESLIDER, m_BlueSlider);
	DDX_Control(pDX, IDC_REDEDIT, m_RedEdit);
	DDX_Control(pDX, IDC_GREENEDIT, m_GreenEdit);
	DDX_Control(pDX, IDC_BLUEEDIT, m_BlueEdit);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CLightWnd, CDialog)
	//{{AFX_MSG_MAP(CLightWnd)
	ON_BN_CLICKED(IDMYOK, OnMyok)
	ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_REDSLIDER, OnReleasedcaptureRedslider)
	ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_GREENSLIDER, OnReleasedcaptureGreenslider)
	ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_BLUESLIDER, OnReleasedcaptureBlueslider)
	ON_BN_CLICKED(IDRESET, OnReset)
	ON_WM_HSCROLL()
	ON_EN_KILLFOCUS(IDC_EDITINNERRADIUS, OnKillfocusEditinnerradius)
	ON_EN_KILLFOCUS(IDC_EDITLIGHTPITCH, OnKillfocusEditlightpitch)
	ON_EN_KILLFOCUS(IDC_EDITLIGHTROLL, OnKillfocusEditlightroll)
	ON_EN_KILLFOCUS(IDC_EDITLIGHTX, OnKillfocusEditlightx)
	ON_EN_KILLFOCUS(IDC_EDITLIGHTY, OnKillfocusEditlighty)
	ON_EN_KILLFOCUS(IDC_EDITLIGHTYAW, OnKillfocusEditlightyaw)
	ON_EN_KILLFOCUS(IDC_EDITLIGHTZ, OnKillfocusEditlightz)
	ON_EN_KILLFOCUS(IDC_EDITOUTTERRADIUS, OnKillfocusEditoutterradius)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPININNERRADIUS, OnDeltaposSpininnerradius)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPINLIGHTPITCH, OnDeltaposSpinlightpitch)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPINLIGHTROLL, OnDeltaposSpinlightroll)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPINLIGHTX, OnDeltaposSpinlightx)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPINLIGHTY, OnDeltaposSpinlighty)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPINLIGHTYAW, OnDeltaposSpinlightyaw)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPINLIGHTZ, OnDeltaposSpinlightz)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPINOUTERRADIUS, OnDeltaposSpinouterradius)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPINANGLE, OnDeltaposSpinangle)
	ON_EN_KILLFOCUS(IDC_EDITANGLE, OnKillfocusEditangle)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLightWnd message handlers

void CLightWnd::OnMyok() 
{
	CDialog::OnOK();
}

void CLightWnd::OnCancel() 
{
	light->SetColor(oldRed,oldGreen,oldBlue);
	
	CDialog::OnCancel();
}

void CLightWnd::OnReleasedcaptureRedslider(NMHDR* pNMHDR, LRESULT* pResult) 
{
	curRed = Scalar(m_RedSlider.GetPos()) / 100.0f;
	light->SetColor(curRed,curGreen,curBlue);
	
	UpdateControls();

	*pResult = 0;
}

void CLightWnd::OnReleasedcaptureGreenslider(NMHDR* pNMHDR, LRESULT* pResult) 
{
	curGreen = Scalar(m_GreenSlider.GetPos()) / 100.0f;
	light->SetColor(curRed,curGreen,curBlue);
	
	UpdateControls();

	*pResult = 0;
}

void CLightWnd::OnReleasedcaptureBlueslider(NMHDR* pNMHDR, LRESULT* pResult) 
{
	curBlue = Scalar(m_BlueSlider.GetPos()) / 100.0f;
	light->SetColor(curRed,curGreen,curBlue);
	
	UpdateControls();

	*pResult = 0;
}

void CLightWnd::UpdateControls() 
{
	if (!light)
		return;

	m_RedSlider.SetPos(int(curRed * 100));
	m_GreenSlider.SetPos(int(curGreen * 100));
	m_BlueSlider.SetPos(int(curBlue * 100));

	char string[32];

	sprintf(string,"%4.2f",curRed);
	m_RedEdit.SetWindowText(string);

	sprintf(string,"%4.2f",curGreen);
	m_GreenEdit.SetWindowText(string);

	sprintf(string,"%4.2f",curBlue);
	m_BlueEdit.SetWindowText(string);

	Point3D	point;
	YawPitchRoll ypr;

	point = worldMatrix;
	ypr = worldMatrix;

	sprintf(string,"%7.2f",point.x);
	m_XEdit.SetWindowText(string);

	sprintf(string,"%7.2f",point.y);
	m_YEdit.SetWindowText(string);

	sprintf(string,"%7.2f",point.z);
	m_ZEdit.SetWindowText(string);

	Scalar scalar;

	scalar = REDUCEANGLE(Degrees_Per_Radian * ypr.yaw);
	if (scalar < 0) scalar += 360;
	sprintf(string,"%7.2f",scalar);
	m_YawEdit.SetWindowText(string);

	scalar = REDUCEANGLE(Degrees_Per_Radian * ypr.pitch);
	if (scalar < 0) scalar += 360;
	sprintf(string,"%7.2f",scalar);
	m_PitchEdit.SetWindowText(string);

	scalar = REDUCEANGLE(Degrees_Per_Radian * ypr.roll);
	if (scalar < 0) scalar += 360;
	sprintf(string,"%7.2f",scalar);
	m_RollEdit.SetWindowText(string);

	sprintf(string,"%7.2f",light->lightInfo.m_outer);
	m_OuterRadius.SetWindowText(string);

	sprintf(string,"%7.2f",light->lightInfo.m_inner);
	m_InnerRadiusEdit.SetWindowText(string);

	scalar = REDUCEANGLE(Degrees_Per_Radian * light->lightInfo.m_spread);
	if (scalar < 0) scalar += 360;
	sprintf(string,"%7.2f",scalar);
	m_AngleEdit.SetWindowText(string);
}

void CLightWnd::OnReset() 
{
	curRed = oldRed;
	curGreen = oldGreen;
	curBlue = oldBlue;

	light->SetColor(curRed,curGreen,curBlue);

	UpdateControls();
}

BOOL CLightWnd::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	m_RedSlider.SetRange(0,100);
	m_GreenSlider.SetRange(0,100);
	m_BlueSlider.SetRange(0,100);

	m_RedSlider.SetBuddy(&m_RedEdit,FALSE);
	m_GreenSlider.SetBuddy(&m_GreenEdit,FALSE);
	m_BlueSlider.SetBuddy(&m_BlueEdit,FALSE);

	oldRed = oldGreen = oldBlue = 0;
	curRed = curGreen = curBlue = 0;

	worldMatrix = LinearMatrix4D::Identity;

	UpdateControls();
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CLightWnd::SetLight(EditorLight* Light)
{
	light = Light;

	light->light->GetInfo(&light->lightInfo);

	oldRed = light->lightInfo.m_color.red;
	oldGreen = light->lightInfo.m_color.green;
	oldBlue = light->lightInfo.m_color.blue;

	worldMatrix = light->lightInfo.m_origin;

	SetWindowText(light->instanceName);

	if (light->IsDerivedFrom(EditorAmbientLight::DefaultData))
	{
		m_InnerRadiusEdit.EnableWindow(FALSE);
		m_InnerRadiusSpin.EnableWindow(FALSE);
		m_OuterRadius.EnableWindow(FALSE);
		m_OuterRadiusSpin.EnableWindow(FALSE);
		m_XEdit.EnableWindow(FALSE);
		m_XSpin.EnableWindow(FALSE);
		m_YEdit.EnableWindow(FALSE);
		m_YSpin.EnableWindow(FALSE);
		m_ZEdit.EnableWindow(FALSE);
		m_ZSpin.EnableWindow(FALSE);
		m_YawEdit.EnableWindow(FALSE);
		m_YawSpin.EnableWindow(FALSE);
		m_PitchEdit.EnableWindow(FALSE);
		m_PitchSpin.EnableWindow(FALSE);
		m_RollEdit.EnableWindow(FALSE);
		m_RollSpin.EnableWindow(FALSE);
		m_AngleEdit.EnableWindow(FALSE);
		m_AngleSpin.EnableWindow(FALSE);
	}
	if (light->IsDerivedFrom(EditorInfiniteLight::DefaultData))
	{
		m_InnerRadiusEdit.EnableWindow(FALSE);
		m_InnerRadiusSpin.EnableWindow(FALSE);
		m_OuterRadius.EnableWindow(FALSE);
		m_OuterRadiusSpin.EnableWindow(FALSE);
		m_XEdit.EnableWindow(FALSE);
		m_XSpin.EnableWindow(FALSE);
		m_YEdit.EnableWindow(FALSE);
		m_YSpin.EnableWindow(FALSE);
		m_ZEdit.EnableWindow(FALSE);
		m_ZSpin.EnableWindow(FALSE);
		m_YawEdit.EnableWindow(TRUE);
		m_YawSpin.EnableWindow(TRUE);
		m_PitchEdit.EnableWindow(FALSE);
		m_PitchSpin.EnableWindow(FALSE);
		m_RollEdit.EnableWindow(FALSE);
		m_RollSpin.EnableWindow(FALSE);
		m_AngleEdit.EnableWindow(FALSE);
		m_AngleSpin.EnableWindow(FALSE);
	}
	if (light->IsDerivedFrom(EditorPointLight::DefaultData))
	{
		m_InnerRadiusEdit.EnableWindow(TRUE);
		m_InnerRadiusSpin.EnableWindow(TRUE);
		m_OuterRadius.EnableWindow(TRUE);
		m_OuterRadiusSpin.EnableWindow(TRUE);
		m_XEdit.EnableWindow(TRUE);
		m_XSpin.EnableWindow(TRUE);
		m_YEdit.EnableWindow(TRUE);
		m_YSpin.EnableWindow(TRUE);
		m_ZEdit.EnableWindow(TRUE);
		m_ZSpin.EnableWindow(TRUE);
		m_YawEdit.EnableWindow(FALSE);
		m_YawSpin.EnableWindow(FALSE);
		m_PitchEdit.EnableWindow(FALSE);
		m_PitchSpin.EnableWindow(FALSE);
		m_RollEdit.EnableWindow(FALSE);
		m_RollSpin.EnableWindow(FALSE);
		m_AngleEdit.EnableWindow(FALSE);
		m_AngleSpin.EnableWindow(FALSE);
	}
	if (light->IsDerivedFrom(EditorSpotLight::DefaultData))
	{
		m_InnerRadiusEdit.EnableWindow(TRUE);
		m_InnerRadiusSpin.EnableWindow(TRUE);
		m_OuterRadius.EnableWindow(TRUE);
		m_OuterRadiusSpin.EnableWindow(TRUE);
		m_XEdit.EnableWindow(TRUE);
		m_XSpin.EnableWindow(TRUE);
		m_YEdit.EnableWindow(TRUE);
		m_YSpin.EnableWindow(TRUE);
		m_ZEdit.EnableWindow(TRUE);
		m_ZSpin.EnableWindow(TRUE);
		m_YawEdit.EnableWindow(TRUE);
		m_YawSpin.EnableWindow(TRUE);
		m_PitchEdit.EnableWindow(TRUE);
		m_PitchSpin.EnableWindow(TRUE);
		m_RollEdit.EnableWindow(TRUE);
		m_RollSpin.EnableWindow(TRUE);
		m_AngleEdit.EnableWindow(TRUE);
		m_AngleSpin.EnableWindow(TRUE);
	}

	OnReset();
}

void CLightWnd::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	char string[8];

	if (pScrollBar->m_hWnd == m_RedSlider.m_hWnd)
	{
		curRed = Scalar(m_RedSlider.GetPos()) / 100.0f;
		sprintf(string,"%4.2f",curRed);
		m_RedEdit.SetWindowText(string);
	}
	else if (pScrollBar->m_hWnd == m_GreenSlider.m_hWnd)
	{
		curGreen = Scalar(m_GreenSlider.GetPos()) / 100.0f;
		sprintf(string,"%4.2f",curGreen);
		m_GreenEdit.SetWindowText(string);
	}
	else if (pScrollBar->m_hWnd == m_BlueSlider.m_hWnd)
	{
		curBlue = Scalar(m_BlueSlider.GetPos()) / 100.0f;
		sprintf(string,"%4.2f",curBlue);
		m_BlueEdit.SetWindowText(string);
	}
	light->SetColor(curRed,curGreen,curBlue);
	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CLightWnd::OnKillfocusEditlightx() 
{
	char string[8];
	Point3D loc;
	loc = worldMatrix;
	m_XEdit.GetWindowText(string,7);
	loc.x = (Scalar)atof(string);
	worldMatrix.BuildTranslation(loc);

	SetWorldMatrix();
}

void CLightWnd::OnKillfocusEditlighty() 
{
	char string[8];
	Point3D loc;
	loc = worldMatrix;
	m_YEdit.GetWindowText(string,7);
	loc.y = (Scalar)atof(string);
	worldMatrix.BuildTranslation(loc);

	SetWorldMatrix();
}

void CLightWnd::OnKillfocusEditlightz() 
{
	char string[8];
	Point3D loc;
	loc = worldMatrix;
	m_ZEdit.GetWindowText(string,7);
	loc.z = (Scalar)atof(string);
	worldMatrix.BuildTranslation(loc);

	SetWorldMatrix();
}

void CLightWnd::OnKillfocusEditlightyaw() 
{
	char string[8];
	YawPitchRoll ypr;
	ypr = worldMatrix;
	m_YawEdit.GetWindowText(string,7);
	ypr.yaw = Radians_Per_Degree * (Scalar)atof(string);
	worldMatrix.BuildRotation(ypr);

	SetWorldMatrix();
}

void CLightWnd::OnKillfocusEditlightpitch() 
{
	char string[8];
	YawPitchRoll ypr;
	ypr = worldMatrix;
	m_PitchEdit.GetWindowText(string,7);
	ypr.pitch = Radians_Per_Degree * (Scalar)atof(string);
	worldMatrix.BuildRotation(ypr);

	SetWorldMatrix();
}

void CLightWnd::OnKillfocusEditlightroll() 
{
	char string[8];
	YawPitchRoll ypr;
	ypr = worldMatrix;
	m_RollEdit.GetWindowText(string,7);
	ypr.roll = Radians_Per_Degree * (Scalar)atof(string);
	worldMatrix.BuildRotation(ypr);

	SetWorldMatrix();
}

void CLightWnd::OnKillfocusEditinnerradius() 
{
	char string[8];
	m_InnerRadiusEdit.GetWindowText(string,7);
	light->lightInfo.m_inner = (Scalar)atof(string);
	light->UpdateLight();
}

void CLightWnd::OnKillfocusEditoutterradius() 
{
	char string[8];
	m_OuterRadius.GetWindowText(string,7);
	light->lightInfo.m_outer = (Scalar)atof(string);
	light->UpdateLight();
}


void CLightWnd::OnKillfocusEditangle() 
{
	char string[8];
	m_AngleEdit.GetWindowText(string,7);
	light->lightInfo.m_spread = Radians_Per_Degree * (Scalar)atof(string);
	light->UpdateLight();
}

void CLightWnd::OnDeltaposSpinlightx(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

	Point3D loc;
	loc = worldMatrix;
	loc.x -= (float)pNMUpDown->iDelta;
	worldMatrix.BuildTranslation(loc);

	SetWorldMatrix();

	*pResult = 0;
}

void CLightWnd::OnDeltaposSpinlighty(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

	Point3D loc;
	loc = worldMatrix;
	loc.y -= (float)pNMUpDown->iDelta;
	worldMatrix.BuildTranslation(loc);

	SetWorldMatrix();

	*pResult = 0;
}

void CLightWnd::OnDeltaposSpinlightz(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

	Point3D loc;
	loc = worldMatrix;
	loc.z -= (float)pNMUpDown->iDelta;
	worldMatrix.BuildTranslation(loc);

	SetWorldMatrix();

	*pResult = 0;
}

void CLightWnd::OnDeltaposSpinlightyaw(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

	YawPitchRoll ypr;
	ypr = worldMatrix;
	ypr.yaw -= Radians_Per_Degree * (float)pNMUpDown->iDelta;
	worldMatrix.BuildRotation(ypr);

	SetWorldMatrix();

	*pResult = 0;
}

void CLightWnd::OnDeltaposSpinlightpitch(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

	YawPitchRoll ypr;
	ypr = worldMatrix;
	ypr.pitch -= Radians_Per_Degree * (float)pNMUpDown->iDelta;
	worldMatrix.BuildRotation(ypr);

	SetWorldMatrix();

	*pResult = 0;
}

void CLightWnd::OnDeltaposSpinlightroll(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

	YawPitchRoll ypr;
	ypr = worldMatrix;
	ypr.roll -= Radians_Per_Degree * (float)pNMUpDown->iDelta;
	worldMatrix.BuildRotation(ypr);

	SetWorldMatrix();
	
	*pResult = 0;
}

void CLightWnd::OnDeltaposSpininnerradius(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

	light->lightInfo.m_inner -= (float)pNMUpDown->iDelta;
	light->UpdateLight();
	UpdateControls();

	*pResult = 0;
}

void CLightWnd::OnDeltaposSpinouterradius(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

	light->lightInfo.m_outer -= (float)pNMUpDown->iDelta;
	light->UpdateLight();
	UpdateControls();

	*pResult = 0;
}

void CLightWnd::OnDeltaposSpinangle(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

	light->lightInfo.m_spread -= Radians_Per_Degree * (float)pNMUpDown->iDelta;
	light->UpdateLight();
	UpdateControls();

	*pResult = 0;
}

void CLightWnd::SetWorldMatrix()
{
	light->SetLightToWorldMatrix(worldMatrix);

	light->SetNewLocalToParent(worldMatrix);
	light->SyncMatrices(true);
	
	UpdateControls();
}
