// GUILight.cpp: implementation of the GUILight class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "mw4gameed2.h"
#include "GUILight.h"
#include "DrawInfo.h"
#include "ObjPanelDlg.h"
#include "LightPanel.h"
#include "PointLightPanel.h"
#include "SpotLightPanel.h"
#include <gosFX\gosFX.hpp>
#include <Adept\LightManager.hpp>
#include "GameInterface.h"

using namespace Adept;
using namespace gosFX;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

GUILight::GUILight(CString name):EdGUIObject(name)
{
	Visual=false;
	ScreenDiv=50;
	DrawPen=DrawInfo::HelperPen;
	MyLight=NULL;
	
}

void GUILight::UpdateMat()
{
	if(MyLight)
	{
		RemoveFromMap();
		LightManager::Info info;
		MyLight->GetInfo(&info);
		info.m_origin=GetMat();
		MyLight->ChangeLight(&info);
		AddToMap();
	}
}

void GUILight::AddToMap()
{
	if(!InMap)
	{
	AddLightToMap(MyLight);
	}
	
	EdGUIObject::AddToMap();
}

void GUILight::RemoveFromMap()
{
	if(InMap)
	{
	RemoveLightFromMap(MyLight);
	}

	EdGUIObject::RemoveFromMap();
}

void GUILight::Copy(GUILight &obj)
{
	LightManager::Info info;
	obj.MyLight->GetInfo(&info);
	Build();
	MyLight->ChangeLight(&info);
	EdGUIObject::Copy(obj);
	
}

RGBColor GUILight::GetColor()
{
		LightManager::Info info;
		MyLight->GetInfo(&info);
		return info.m_color;
}

void GUILight::SetColor(RGBColor &col)
{
		LightManager::Info info;
		MyLight->GetInfo(&info);
		info.m_color=col;
		MyLight->ChangeLight(&info);
}

Scalar GUILight::GetIntensity()
{
		LightManager::Info info;
		MyLight->GetInfo(&info);
		return info.m_intensity;
}

void GUILight::SetIntensity(Scalar i)
{
		LightManager::Info info;
		MyLight->GetInfo(&info);
		info.m_intensity=i;
		MyLight->ChangeLight(&info);
}

void GUILight::AssociateTo(gosFX::Light *light)
{
	
	InMap=false;
	SnapToGround=false;
	LightManager::Info info;
	light->GetInfo(&info);
	
	EdGUIObject::SetMat(info.m_origin);
	
	InMap=true;
	
	MyLight=light;
//	SetName(CString("Mission Light"));
	Check_Object(MyLight);	
}	


void GUILight::Clear()
{
	if(MyLight!=NULL)
	{
		Check_Object(MyLight);
		if(InMap)
		{
			RemoveFromMap();
		}
		Adept::TiledLightManager::Instance->DeleteLight(MyLight);
	}
}

void GUILight::SetToDefault()
{
		LightManager::Info info;
	info.m_color=RGBColor(1.0,1.0,1.0);
	info.m_inner=10.0f;
	info.m_outer=100.0f;
	info.m_intensity=1.0f;
	info.m_spread=45.0f*Radians_Per_Degree;
	info.m_origin=GetMat();
	if(MyLight)
	{
	MyLight->ChangeLight(&info);
	}
}

void GUILight::AddPanel(CObjPanelDlg *pnl,UndoCommand **cmd)
{
	pnl->AddPanel(new CLightPanel(this,cmd));
}

GUILight::~GUILight()
{
	Clear();
}


// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Ambient Light

GUIAmbientLight::GUIAmbientLight(CString name):GUILight(name)
{
	
}

void GUIAmbientLight::Build()
{
	MyLight= Adept::TiledLightManager::Instance->MakeAmbientLight();
	SetToDefault();
}


void GUIAmbientLight::AddPanel(CObjPanelDlg *pnl,UndoCommand **cmd)
{
	GUILight::AddPanel(pnl,cmd);
}

void GUIAmbientLight::Copy(GUIAmbientLight &obj)
{
	GUILight::Copy(obj);
}

EdGUIObject *GUIAmbientLight::Clone()
{
	GUIAmbientLight *obj=new GUIAmbientLight;
	obj->Copy(*this);
	return obj;
}

GUIAmbientLight::~GUIAmbientLight()
{
	
}

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Infinite Light

GUIInfiniteLight::GUIInfiniteLight(CString name):GUILight(name)
{
}


void GUIInfiniteLight::Build()
{
	MyLight = Adept::TiledLightManager::Instance->MakeInfiniteLight();
	SetToDefault();
}

void GUIInfiniteLight::Copy(GUIInfiniteLight &obj)
{
	GUILight::Copy(obj);
}

void GUIInfiniteLight::AddPanel(CObjPanelDlg *pnl,UndoCommand **cmd)
{
	EdGUIObject::AddPanel(pnl,cmd);
	GUILight::AddPanel(pnl,cmd);
}

EdGUIObject *GUIInfiniteLight::Clone()
{
	GUIInfiniteLight *obj=new GUIInfiniteLight;
	obj->Copy(*this);
	return obj;
}

GUIInfiniteLight::~GUIInfiniteLight()
{
	
}


// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Lookup Light

GUILookUpLight::GUILookUpLight(CString name):GUIInfiniteLight(name)
{
}


void GUILookUpLight::AddPanel(CObjPanelDlg *pnl,UndoCommand **cmd)
{
	GUIInfiniteLight::AddPanel(pnl,cmd);
}

void GUILookUpLight::Draw(DrawInfo &dinf)
{
	
	if(IsHidden()) return;
	SetPen(dinf);
	int rad=GetScreenRadius(dinf.vinf);
	
	CPoint pnt=dinf.vinf.DataToScreen(GetPos());
	CRect rct;
	
	rct.left=pnt.x-rad;
	rct.right=pnt.x+rad;
	rct.top=pnt.y-rad;
	rct.bottom=pnt.y+rad;
	
	dinf.GetDC()->MoveTo(pnt.x,rct.top);
	dinf.GetDC()->LineTo(pnt.x,rct.top+rad/2);
	
	dinf.GetDC()->MoveTo(pnt.x,rct.bottom);
	dinf.GetDC()->LineTo(pnt.x,rct.bottom-rad/2);
	
	dinf.GetDC()->MoveTo(rct.left,pnt.y);
	dinf.GetDC()->LineTo(rct.left+rad/2,pnt.y);
	
	dinf.GetDC()->MoveTo(rct.right,pnt.y);
	dinf.GetDC()->LineTo(rct.right-rad/2,pnt.y);
	
	float d;
	CPoint sp;
	d=(float)(1.0f-(rad/sqrt((pnt.x-rct.left)*(pnt.x-rct.left)+(pnt.y-rct.top)*(pnt.y-rct.top))));
	
	sp.x=(int)(rct.left+(pnt.x-rct.left)*d);
	sp.y=(int)(rct.top+(pnt.y-rct.top)*d);
	
	dinf.GetDC()->MoveTo(rct.TopLeft());
	dinf.GetDC()->LineTo(sp);
	
	sp.x=(int)(rct.right+(pnt.x-rct.right)*d);
	sp.y=(int)(rct.top+(pnt.y-rct.top)*d);
	
	dinf.GetDC()->MoveTo(rct.right,rct.top);
	dinf.GetDC()->LineTo(sp);
	
	sp.x=(int)(rct.right+(pnt.x-rct.right)*d);
	sp.y=(int)(rct.bottom+(pnt.y-rct.bottom)*d);
	
	dinf.GetDC()->MoveTo(rct.BottomRight());
	dinf.GetDC()->LineTo(sp);
	
	sp.x=(int)(rct.left+(pnt.x-rct.left)*d);
	sp.y=(int)(rct.bottom+(pnt.y-rct.bottom)*d);
	
	dinf.GetDC()->MoveTo(rct.left,rct.bottom);
	dinf.GetDC()->LineTo(sp);
	
	rct.left=pnt.x-rad/2;
	rct.right=pnt.x+rad/2;
	rct.top=pnt.y-rad/2;
	rct.bottom=pnt.y+rad/2;
	
	dinf.GetDC()->Ellipse(&rct);
	
}


GUILookUpLight::~GUILookUpLight()
{
	
}
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SpotLight
GUISpotLight::GUISpotLight(CString name,Point3D pnt):GUIPointLight(name,pnt)
{
	SetPos(pnt);
}

void GUISpotLight::Build()
{
	MyLight = Adept::TiledLightManager::Instance->MakeSpotLight();
	SetToDefault();
	UpdateMat();
}


void GUISpotLight::AddPanel(CObjPanelDlg *pnl,UndoCommand **cmd)
{
	EdGUIObject::AddPanel(pnl,cmd);
	GUILight::AddPanel(pnl,cmd);
	pnl->AddPanel(new CPointLightPanel(this,cmd));
	pnl->AddPanel(new CSpotLightPanel(this,cmd));
	
}

void GUISpotLight::Draw(DrawInfo &dinf)
{
	
	if(IsHidden()) return;
	SetPen(dinf);
	int rad=GetScreenRadius(dinf.vinf);
	
	CPoint pnt=dinf.vinf.DataToScreen(GetPos());
	CRect rct;
	
	rct.left=pnt.x-rad/2;
	rct.right=pnt.x+rad/2;
	rct.top=pnt.y-rad/2;
	rct.bottom=pnt.y+rad/2;
	
	dinf.GetDC()->Ellipse(&rct);
	
	
}

void GUISpotLight::Copy(GUISpotLight &obj)
{
	GUIPointLight::Copy(obj);
}

EdGUIObject *GUISpotLight::Clone()
{
	GUISpotLight *obj=new GUISpotLight;
	obj->Copy(*this);
	return obj;
}

Scalar GUISpotLight::GetSpreadAngle()
{
		LightManager::Info info;
		MyLight->GetInfo(&info);
		return info.m_spread;
}

void GUISpotLight::SetSpreadAngle(Scalar s)
{
		LightManager::Info info;
		MyLight->GetInfo(&info);
		info.m_spread=s;
		MyLight->ChangeLight(&info);	
}

GUISpotLight::~GUISpotLight()
{
	
}

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Point Light
GUIPointLight::GUIPointLight(CString name,Point3D pnt):GUILight(name)
{
	SetPos(pnt);
}

void GUIPointLight::Build()
{
	MyLight = Adept::TiledLightManager::Instance->MakePointLight();
	SetToDefault();
	UpdateMat();
}

void GUIPointLight::Copy(GUIPointLight &obj)
{
	GUILight::Copy(obj);
}

void GUIPointLight::AddPanel(CObjPanelDlg *pnl,UndoCommand **cmd)
{
	EdGUIObject::AddPanel(pnl,cmd);
	GUILight::AddPanel(pnl,cmd);
	pnl->AddPanel(new CPointLightPanel(this,cmd));
	
}

Scalar GUIPointLight::GetInnerRad()
{
		LightManager::Info info;
		MyLight->GetInfo(&info);
		return info.m_inner;

}

void GUIPointLight::SetInnerRad(Scalar rad)
{
		LightManager::Info info;
		MyLight->GetInfo(&info);
		info.m_inner=rad;
		MyLight->ChangeLight(&info);		
}

Scalar GUIPointLight::GetOuterRad()
{
		LightManager::Info info;
		MyLight->GetInfo(&info);
		return info.m_outer;
}

void GUIPointLight::SetOuterRad(Scalar rad)
{
		LightManager::Info info;
		MyLight->GetInfo(&info);
		info.m_outer=rad;
		MyLight->ChangeLight(&info);		
}

EdGUIObject *GUIPointLight::Clone()
{
	GUIPointLight *obj=new GUIPointLight;
	obj->Copy(*this);
	return obj;
}

void GUIPointLight::Draw(DrawInfo &dinf)
{
	
	if(IsHidden()) return;
	SetPen(dinf);
	int rad=GetScreenRadius(dinf.vinf);
	
	CPoint pnt=dinf.vinf.DataToScreen(GetPos());
	CRect rct;
	
	rct.left=pnt.x-rad;
	rct.right=pnt.x+rad;
	rct.top=pnt.y-rad;
	rct.bottom=pnt.y+rad;
	
	dinf.GetDC()->MoveTo(pnt.x,rct.top);
	dinf.GetDC()->LineTo(pnt.x,rct.top+rad/2);
	
	dinf.GetDC()->MoveTo(pnt.x,rct.bottom);
	dinf.GetDC()->LineTo(pnt.x,rct.bottom-rad/2);
	
	dinf.GetDC()->MoveTo(rct.left,pnt.y);
	dinf.GetDC()->LineTo(rct.left+rad/2,pnt.y);
	
	dinf.GetDC()->MoveTo(rct.right,pnt.y);
	dinf.GetDC()->LineTo(rct.right-rad/2,pnt.y);
	
	float d;
	CPoint sp;
	d=(float)(1.0f-(rad/sqrt((pnt.x-rct.left)*(pnt.x-rct.left)+(pnt.y-rct.top)*(pnt.y-rct.top))));
	
	sp.x=(int)(rct.left+(pnt.x-rct.left)*d);
	sp.y=(int)(rct.top+(pnt.y-rct.top)*d);
	
	dinf.GetDC()->MoveTo(rct.TopLeft());
	dinf.GetDC()->LineTo(sp);
	
	sp.x=(int)(rct.right+(pnt.x-rct.right)*d);
	sp.y=(int)(rct.top+(pnt.y-rct.top)*d);
	
	dinf.GetDC()->MoveTo(rct.right,rct.top);
	dinf.GetDC()->LineTo(sp);
	
	sp.x=(int)(rct.right+(pnt.x-rct.right)*d);
	sp.y=(int)(rct.bottom+(pnt.y-rct.bottom)*d);
	
	dinf.GetDC()->MoveTo(rct.BottomRight());
	dinf.GetDC()->LineTo(sp);
	
	sp.x=(int)(rct.left+(pnt.x-rct.left)*d);
	sp.y=(int)(rct.bottom+(pnt.y-rct.bottom)*d);
	
	dinf.GetDC()->MoveTo(rct.left,rct.bottom);
	dinf.GetDC()->LineTo(sp);
	
	rct.left=pnt.x-rad/2;
	rct.right=pnt.x+rad/2;
	rct.top=pnt.y-rad/2;
	rct.bottom=pnt.y+rad/2;
	
	dinf.GetDC()->Ellipse(&rct);
	
}

GUIPointLight::~GUIPointLight()
{
	
}
