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

#include "stdafx.h"
#include "MW4GameEd2.h"
#include "GUILattice.h"
#include "DrawInfo.h"
#include "ProgDlg.h"

#include <MW4\Rail_move.hpp>


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

// >>>>>>>>>>>>>>  GUILatticeNode

GUILatticeNode::GUILatticeNode(MW4AI::CRailNode *node)
{
	MyNode=NULL;
	SetName(CString("LatticeNode"));
	Visual=false;
	SetNode(node);
	RadiusPen=DrawInfo::ExtraHelperPen;
}

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

int GUILatticeNode::GetNodeID() {return MyNode->ID();}

void GUILatticeNode::RotateBy(UnitQuaternion &pnt)
{

}

void GUILatticeNode::SetNode(MW4AI::CRailNode *node)
{
	//	if(MyNode==node) return;
	
	MyNode=node;
	
	if(MyNode!=NULL)
	{
		RadiusSqu=MyNode->RadiusSquared();
		SetPos(MyNode->Location());
	}
	
}

MW4AI::CRailLink *GUILatticeNode::GetLinkTo(GUILatticeNode *node)
{
	int i;
	MW4AI::CRailLink *link;
	
	for(i=0;i<MyNode->NumLinks();i++)
	{
		link=MyNode->Link(i);
		if(link)
		{
			if(link->Location(0)==MyNode)
			{
				if(link->Location(1)==node->MyNode)
					return link;
			}
			else if(link->Location(1)==MyNode)
			{
				if(link->Location(0)==node->MyNode)
					return link;
			}
			else
			{
				STOP(("Lattice Error"));
			}
		}
	}
	
	return NULL;
}

void GUILatticeNode::UpdateMat()
{
	
	if(MyNode!=NULL)
	{
		MyNode->Location(GetPos());
	}

	EdGUIObject::UpdateMat();
}

void GUILatticeNode::Draw(DrawInfo &dinf)
{
	if(IsHidden()) return;

	SetPen(dinf);

	int drad=GetScreenRadius(dinf.vinf);
	
	CPoint pnt=dinf.vinf.DataToScreen(GetPos());
	dinf.GetDC()->Ellipse(pnt.x-drad,pnt.y-drad,pnt.x+drad,pnt.y+drad);
	

	if(!IsSelected()) dinf.SetPen(RadiusPen);
	
	CSize srad;
	Point3D rad;
	rad.y=0.0f;
	rad.z=rad.x=MyNode->Radius();
	srad=dinf.vinf.DataToScreen(rad)-dinf.vinf.DataToScreen(Point3D(0.0f,0.0f,0.0f));
	srad.cx=abs(srad.cx);
	srad.cy=abs(srad.cy);
	if(srad.cx>2000 || srad.cy>2000) return;
	
	CRect rct;
	rct.SetRect(pnt.x-srad.cx,pnt.y-srad.cy,pnt.x+srad.cx,pnt.y+srad.cy);
	dinf.GetDC()->Ellipse(&rct);

 }


GUILatticeNode::~GUILatticeNode()
{
}

// >>>>>>>>>>>>>>  GUILattice
GUILattice::GUILattice(MW4AI::CRailGraph *path):GUIObjectList()
{
	SetName(CString("MovementGraph"));
	SetGraph(path);
	ExistEmpty=true;
}

void GUILattice::SetGraph(MW4AI::CRailGraph *graph)
{
DeleteAllObjects();
	MyGraph=graph;
	if(MyGraph!=NULL)
	{
		Check_Object(MyGraph);
		for(int i=0;i<MyGraph->NumNodes();i++)
			if(MyGraph->Node(i)!=NULL)
			{
				AddObject(new GUILatticeNode(MyGraph->Node(i)));
			}
	}

}

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

EdGUIObject *GUILattice::AddNode(Point3D &pnt)
{
	MW4AI::CRailNode *rnode=new MW4AI::CRailNode(pnt,50);
	MyGraph->AddNode(rnode);
	GUILatticeNode *ret;
	AddObject(ret=new GUILatticeNode(rnode));
	return ret;
}

void GUILattice::Draw(DrawInfo &dinf)
{
	SetPen(dinf);
if(IsHidden()) return;
	Check_Object(MyGraph);
	
	for(int i=0;i<MyGraph->NumLinks();i++)
		if(MyGraph->Link(i)!=NULL)
		{
			Verify (MyGraph->Link(i)->Location(0));
			Verify (MyGraph->Link(i)->Location(1));
			dinf.GetDC()->MoveTo(dinf.vinf.DataToScreen(MyGraph->Link(i)->Location(0)->Location()));
			dinf.GetDC()->LineTo(dinf.vinf.DataToScreen(MyGraph->Link(i)->Location(1)->Location()));
#if 0
			if (MyGraph->Link(i)->Location(0) != 0)
			{
				dinf.GetDC()->MoveTo(dinf.vinf.DataToScreen(MyGraph->Link(i)->Location(0)->Location()));
			}

			if (MyGraph->Link(i)->Location(1) != 0)
			{
				dinf.GetDC()->LineTo(dinf.vinf.DataToScreen(MyGraph->Link(i)->Location(1)->Location()));
			}
#endif
		}
		
		GUIObjectList::Draw(dinf);
}

EdGUIObject *GUILattice::AddNodeIfSelected(Point3D &pnt,bool insert)	
{
	if(!IsSelected()) return false;
	return AddNode(pnt);
}

void GUILattice::RemoveObject(int idx)
{
	Verify(idx<GetObjectCount());
	Verify(ObjectCount==GetActualNodeCount());
	
	GUILatticeNode *gobj=(GUILatticeNode *)GetObject(idx);
	if(MyGraph)
	{
		Check_Object(MyGraph);
		MyGraph->DeleteNode(gobj->GetNodeID());
	}
	GUIObjectList::RemoveObject(idx);
	Verify(ObjectCount==GetActualNodeCount());
	
	SyncNodesToData();
}

void GUILattice::SyncNodesToData()
{
	GUILatticeNode *node;
	int objinc=0;
	
	while(GetObjectCount()>GetActualNodeCount()) GUIObjectList::RemoveObject(0);
	while(GetObjectCount()<GetActualNodeCount()) GUIObjectList::AddObject(new GUILatticeNode(NULL));


	
	Verify(GetObjectCount()==GetActualNodeCount());
	for(int i=0;i<MyGraph->NumNodes();i++)
		if(MyGraph->Node(i)!=NULL)
		{
			node=(GUILatticeNode *)GetObject(objinc++);
			node->SetNode(MyGraph->Node(i));
		}
		Verify(objinc==GetObjectCount());
}

bool GUILattice::UnGroupSelected(UndoCommand **cmd)
{
return false;
}

CProgressDlg *ProgressDlg=NULL;

void CalcLinkProgress(float pct)
{
	ProgressDlg->SetPos(int(pct));
}

void GUILattice::CalcLinksOnSelected()
{
	if(GetObjectCount()==0) return;
	int i,scount;
	scount=SelectionCount();
	if(scount==0)
	{
	Select();
	scount=SelectionCount();
	}
	if(IsSelected()) scount--;			//AHF remove the list itself from the count
	
	GUILatticeNode *node;
	int *node_list=new int[scount];
	
	int objinc=0;
	for(i=0;i<GetObjectCount();i++)
	{
		node=(GUILatticeNode *)GetObject(i);
		if(node->IsSelected())
			node_list[objinc++]=node->GetNodeID();
		else
		{
			int fred;
			fred = 1;
		}
	}
		
	Verify(objinc==scount);
	
	float weight[MW4AI::NUM_MOVE_TYPES][2];
		memset(&weight,0,sizeof(weight));

ProgressDlg=new CProgressDlg(IDS_CREATELINKS);
ProgressDlg->Create();
ProgressDlg->ShowWindow(SW_SHOW);

		MW4AI::g_MissionGraph->CalcLinks(node_list,scount,MW4AI::MINLINKCALC,MW4AI::MAXLINKCALC,MW4AI::LINKDIST,CalcLinkProgress);

delete ProgressDlg;
ProgressDlg=NULL;

	delete node_list;
}

int GUILattice::GroupSelected(UndoCommand **cmd)
{
return 0;
}


void CreateLatticeProgress(float pct)
{
	ProgressDlg->SetPos(int(pct));
}

void GUILattice::CreateLattice(int num)
{
ProgressDlg=new CProgressDlg(IDS_CREATELATTICE);
ProgressDlg->Create();
ProgressDlg->ShowWindow(SW_SHOW);

MW4AI::g_MissionGraph->CreateBasicNodes(num,CreateLatticeProgress);
SetGraph(MW4AI::g_MissionGraph);

delete ProgressDlg;
ProgressDlg=NULL;
}

void GUILattice::SaveTextInfo(NotationFile *not_file)
{
Page *page=not_file->SetPage((char *)(LPCSTR)GetName());
page->SetEntry("Type","Lattice");
}

GUILattice::~GUILattice()
{
}

void GUILattice::UpdateVisibility(DWORD visflag)
	{
	SetHide(visflag&SHOW_LATTICE?false:true);
	}

int GUILattice::GetActualNodeCount()
{
int count=0;
	for(int i=0;i<MyGraph->NumNodes();i++)
		if(MyGraph->Node(i)!=NULL) count++;
return count;
}


HTREEITEM GUILattice::AddToBranch(CTreeCtrl *tree,HTREEITEM itm)
{
	return EdGUIObject::AddToBranch(tree,itm);
}
