// OverviewWindow.cpp : implementation file
//

#include "stdafx.h"
#include <math.h>
#include "MW4GameEd2.h"
#include "OverviewWindow.h"
#include "EdGUIObject.h"
#include "ObjectManager.h"
#include "PenProps.h"
#include "MainFrm.h"
#include "Refresher.h"
#include "CameraController.h"
#include "OverviewProperties.h"
#include "GridProps.h"
#include "AlignDlg.h"
#include "DisperseDlg.h"
#include "CustomTagDlg.h"

#include "GameInterface.h"

#include <Windowsx.h>

static UINT indicators[] =
{
	ID_SEPARATOR           // status line indicator
};

const int key_scroll_rate = 50;

/////////////////////////////////////////////////////////////////////////////
// OverviewWindow

//IMPLEMENT_DYNCREATE(OverviewWindow, CWnd)

OverviewWindow::OverviewWindow(ObjectManager *objman,CWnd *parent)
: m_DistanceLineStartPos(-1,-1,-1)
, m_DistanceLineEndPos(-1,-1,-1)
, m_COverviewProperties(0)
{
	ShowTagsAlways=false;
	BackGroundReady=false;
	GroupSelecting=false;
	ZoomBoxing=false;
	TagFlag=TF_ONSELECT;
	
	BOOL result=false;
	
	result=GridPen.CreatePen(PS_SOLID,1,0xffff00);	 Verify(result);
	result=GreenPen.CreatePen(PS_SOLID,1,0x00ff00);  Verify(result);
	result=RedPen.CreatePen(PS_SOLID,1,0x0000ff);    Verify(result);
	result=YellowPen.CreatePen(PS_SOLID,1,0x00ffff); Verify(result);
	
	result=DarkGreenPen.CreatePen(PS_SOLID,1,0x007f00); Verify(result);
	result=DarkRedPen.CreatePen(PS_SOLID,1,0x00007f); Verify(result);
	result=DarkYellowPen.CreatePen(PS_SOLID,1,0x007f7f); Verify(result);
	UserGridSize.x=10.0f;
	UserGridSize.z=10.0f;
	
	ShowFlag=0xffffffff;
	
	CurrentVMode=VM_TEXTURE;
	
	LOGBRUSH lb;
	lb.lbColor=0xffffff;
	lb.lbStyle=BS_SOLID;
	result=BoxPen.CreatePen(PS_DOT,1,&lb); Verify(result);
	
	ObjMan=objman;
	DisplayUserGrid=false;
	DisplayZoneGrid=false;
	DisplayTileGrid=false;
	DidMoveCopy=false;
	HandCur=AfxGetApp()->LoadCursor(IDC_UHAND);
	
}

OverviewWindow::~OverviewWindow()
{
}


BEGIN_MESSAGE_MAP(OverviewWindow, CWnd)
//{{AFX_MSG_MAP(OverviewWindow)
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_WM_CLOSE()
ON_WM_SIZE()
ON_WM_MOUSEWHEEL()
ON_WM_LBUTTONDBLCLK()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
ON_WM_CHAR()
ON_COMMAND(ID_BACKGROUND_HEIGHTFIELD, OnBackgroundHeightfield)
ON_COMMAND(ID_BACKGROUND_SLOPEMAP, OnBackgroundSlopemap)
ON_COMMAND(ID_BACKGROUND_TEXTURE, OnBackgroundTexture)
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
ON_COMMAND(ID_EDIT_DELETE, OnEditDelete)
ON_COMMAND(ID_EDIT_GROUP, OnEditGroup)
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
ON_COMMAND(ID_EDIT_UNGOUP, OnEditUngoup)
ON_UPDATE_COMMAND_UI(ID_BACKGROUND_HEIGHTFIELD, OnUpdateBackgroundHeightfield)
ON_UPDATE_COMMAND_UI(ID_BACKGROUND_SLOPEMAP, OnUpdateBackgroundSlopemap)
ON_UPDATE_COMMAND_UI(ID_BACKGROUND_TEXTURE, OnUpdateBackgroundTexture)
ON_COMMAND(ID_VIEW_HELPERS_SHOWBOUNDS, OnViewHelpersShowbounds)
ON_COMMAND(ID_VIEW_HELPERS_SHOWLATTICE, OnViewHelpersShowlattice)
ON_COMMAND(ID_VIEW_HELPERS_SHOWPATHS, OnViewHelpersShowpaths)
ON_COMMAND(ID_VIEW_HELPERS_SHOWTILEBOUNDS, OnViewHelpersShowtilebounds)
ON_COMMAND(ID_VIEW_HELPERS_SHOWUSERGRID, OnViewHelpersShowusergrid)
ON_COMMAND(ID_VIEW_HELPERS_SHOWZONEBOUNDS, OnViewHelpersShowzonebounds)
ON_UPDATE_COMMAND_UI(ID_VIEW_HELPERS_SHOWBOUNDS, OnUpdateViewHelpersShowbounds)
ON_UPDATE_COMMAND_UI(ID_VIEW_HELPERS_SHOWLATTICE, OnUpdateViewHelpersShowlattice)
ON_UPDATE_COMMAND_UI(ID_VIEW_HELPERS_SHOWPATHS, OnUpdateViewHelpersShowpaths)
ON_UPDATE_COMMAND_UI(ID_VIEW_HELPERS_SHOWTILEBOUNDS, OnUpdateViewHelpersShowtilebounds)
ON_UPDATE_COMMAND_UI(ID_VIEW_HELPERS_SHOWUSERGRID, OnUpdateViewHelpersShowusergrid)
ON_UPDATE_COMMAND_UI(ID_VIEW_HELPERS_SHOWZONEBOUNDS, OnUpdateViewHelpersShowzonebounds)
ON_COMMAND(ID_VIEW_SETUSERGRIDPROPERTIES, OnViewSetusergridproperties)
ON_COMMAND(ID_VIEW_SETPENCOLORS, OnViewSetpencolors)
ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo)
ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
ON_COMMAND(ID_TOOLS_CREATELATTICE, OnToolsCreatelattice)
ON_COMMAND(ID_TOOLS_RECALCLATTICELINKS, OnToolsRecalclatticelinks)
ON_COMMAND(ID_TOOLS_RESETMISSIONBOUNDS, OnToolsResetmissionbounds)
ON_COMMAND(ID_OPTIONS_SETDEFAULTALIGNMENT, OnOptionsSetdefaultalignment)
ON_COMMAND(ID_VIEW_TAGS_SHOWCUSTOM, OnViewTagsShowcustom)
ON_WM_CREATE()
ON_WM_ERASEBKGND()
ON_COMMAND(ID_TOOLS_DISPERSEWITHBITMAP, OnToolsDispersewithbitmap)
ON_COMMAND(ID_TOOLS_SNAPOBJECTTOTERRAIN, OnToolsSnapobjecttoterrain)
ON_WM_RBUTTONDBLCLK()
	ON_WM_SYSKEYDOWN()
	ON_WM_SYSKEYUP()
	ON_COMMAND(ID_OPTIONS_FILLLATTICE, OnOptionsFilllattice)
	ON_UPDATE_COMMAND_UI(ID_OPTIONS_FILLLATTICE, OnUpdateOptionsFilllattice)
	ON_COMMAND(ID_TOOLS_DUMPOVERVEIWCONTENTSTOFILE, OnToolsDumpoverveiwcontentstofile)
	ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomin)
	ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomout)
	ON_COMMAND(ID_VIEW_TAGS_SHOWTAGS, OnViewTagsShowtags)
	ON_UPDATE_COMMAND_UI(ID_VIEW_TAGS_SHOWTAGS, OnUpdateViewTagsShowtags)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// OverviewWindow message handlers

void OverviewWindow::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	RefreshWindow(&dc);	
	// Do not call CWnd::OnPaint() for painting messages
}

void OverviewWindow::BuildBackGround()
{
	CDC *pDC=GetDC();
	CRect crect;
	GetClientRect(&crect);
	pDC->SetStretchBltMode(COLORONCOLOR);
	
	if(!ObjMan->IsLoaded()) return;
	
	
	Image *bimage;
	
	switch(CurrentVMode)
	{
	case VM_TEXTURE:
		bimage=ObjMan->GetTerrainTexture();
		break;
	case VM_HFIELD:
		bimage=ObjMan->GetHeightField();
		break;
	case VM_SLOPEMAP:
		bimage=ObjMan->GetSlopeMap();
		break;
	default: STOP(("Invalid View Mode"));
	}
	
	
	CSize bmsize(bimage->GetWidth(),bimage->GetHeight());
	BackGround.DeleteObject();
	BOOL result;
	result=BackGround.CreateCompatibleBitmap(pDC,bmsize.cx,bmsize.cy); Verify(result);
	
	CDC memDC;
	result=memDC.CreateCompatibleDC(pDC); Verify(result);
	memDC.SelectObject(BackGround);
	
	BITMAPINFO       binf;
	ZeroMemory(&binf,sizeof(binf));
	binf.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
	binf.bmiHeader.biPlanes=1;
	binf.bmiHeader.biCompression=BI_RGB;
	binf.bmiHeader.biWidth=bmsize.cx; 
	binf.bmiHeader.biHeight=-bmsize.cy;
	binf.bmiHeader.biBitCount=(unsigned short)bimage->GetBpp();
	
	BYTE *buf=bimage->Lock();
	
	int res;
	res=SetDIBitsToDevice(memDC,0,0,bmsize.cx,bmsize.cy,
		0,0,
		0,bmsize.cy,
		buf,&binf,DIB_RGB_COLORS);
	Verify(res!=0);
	
	bimage->UnLock();
	
	memDC.DeleteDC();
	ReleaseDC(pDC);
	BackGroundReady=true;
	drawInfo.vinf.SetBitmapArea(bmsize);
}

void OverviewWindow::InitWindow()
{
	BuildBackGround();
    InitBackBuffer();
	ObjMan->UpdateVisibility(ShowFlag);
}

void OverviewWindow::InitBackBuffer()
{
	BackBuffer.DeleteObject();
	CRect crect;
	GetClientRect(&crect);
	drawInfo.vinf.SetClientArea(crect.Size());
	CDC *pDC=GetDC();
	BOOL result;
	result=BackBuffer.CreateCompatibleBitmap(pDC,crect.Width(),crect.Height()); Verify(result);
	ReleaseDC(pDC);
}






void OverviewWindow::RefreshWindow(CDC *pDC)
{
	
	CRect destrect,crct;
	GetClientRect(&crct);
	
	bool needrelease=false;
	if(pDC==NULL) 
	{
		needrelease=true;
		pDC=GetDC();
	}
	CDC bbufDC;
	int res;
	res=bbufDC.CreateCompatibleDC(pDC);
	Verify(res!=0);
	bbufDC.SelectObject(BackBuffer);
	
	if(BackGroundReady)
	{
		CDC memDC;
		CRect srcrect;
		memDC.CreateCompatibleDC(pDC);
		memDC.SelectObject(BackGround);
		
		
		if(!drawInfo.vinf.GetBltRects(&destrect,&srcrect))
		{
		BOOL res=bbufDC.StretchBlt(
			destrect.left,destrect.top,destrect.Width(),destrect.Height(),
			&memDC,
			srcrect.left,srcrect.top,srcrect.Width(),srcrect.Height(),
			SRCCOPY);
//		Verify(res);
		}
		else
		{
			COLORREF col=memDC.GetPixel(srcrect.TopLeft());
			CRect clrct;
			GetClientRect(&clrct);
			bbufDC.FillSolidRect(&clrct,col);
		}
	}
	else
	{
		BOOL res;
		GetClientRect(&destrect);
		res=bbufDC.BitBlt(destrect.left,destrect.top,destrect.Width(),destrect.Height(),NULL,0,0,BLACKNESS); Verify(res);
	}
	
	DrawHelpers(&bbufDC);
	BOOL result;
	result=pDC->BitBlt(crct.left,crct.top,crct.Width(),crct.Height(),&bbufDC,0,0,SRCCOPY); Verify(result);
	
	if(needrelease)
		ReleaseDC(pDC);
	ValidateRect(NULL);
	
//	m_COverviewProperties->Refresh();
}

void OverviewWindow::DragCameraToPoint(const CPoint& point)
{
	if ((ObjMan->GetCameraController() != 0) &&
		(Refresher::Instance != 0))
	{
		CPoint p(point);
		Point3D point3D(drawInfo.vinf.ScreenToData(p));
		
		if (ObjMan->GetCameraController()->StaysInsideBounds(point3D,ObjMan->GetCameraController()->GetYawPitchRange()) == true)
		{
			ObjMan->GetCameraController()->SetLookAt(point3D,true);
			ObjMan->GetCameraController()->Update();
			Refresher::Instance->DrawRefresh();
		}
	}
}

void OverviewWindow::OnMouseMove(UINT nFlags, CPoint point) 
{
	m_LastMousePos = point;
	
	CRect crect;
	GetClientRect(&crect);
	short AltKey=GetAsyncKeyState(VK_MENU);
	short SpaceKey=GetAsyncKeyState(VK_SPACE);
	
	if(SpaceKey) GroupSelecting=false;
	
	if(ObjMan->IsMultiZone())
	{
		ObjMan->SelectMultiZone();
		Point3D vect;
		vect=drawInfo.vinf.ScreenToData(point);
		vect-=drawInfo.vinf.ScreenToData(OldPoint);
		ObjMan->OffsetSelection(vect);
		OldPoint=point;
		Refresher::Instance->DrawRefresh();
		
	}
	else
	{
		Point3D data_point=drawInfo.vinf.ScreenToData(point);
		if(nFlags&MK_MBUTTON || (SpaceKey && nFlags&MK_LBUTTON  && nFlags&MK_CONTROL) || ZoomBoxing)
		{	// Adjust Zoom
			
			if(ZoomBreakBuffer==false)
			{
				if(((point.x-ZoomBufferPoint.x)*(point.x-ZoomBufferPoint.x)+(point.y-ZoomBufferPoint.y)*(point.y-ZoomBufferPoint.y))>25) 
					ZoomBreakBuffer=true;
				
			}
			else
			{
				ZoomBoxing=true;	
				ZoomBox.left=point.x<ZoomBoxAnchor.x?point.x:ZoomBoxAnchor.x;
				ZoomBox.right=point.x>ZoomBoxAnchor.x?point.x:ZoomBoxAnchor.x;
				ZoomBox.top=point.y<ZoomBoxAnchor.y?point.y:ZoomBoxAnchor.y;
				ZoomBox.bottom=point.y>ZoomBoxAnchor.y?point.y:ZoomBoxAnchor.y;
				
				Refresher::Instance->OverviewRefresh();
			}
		}
		
		
		
		if(nFlags&MK_LBUTTON)
		{
			if(SpaceKey)
			{
				if(nFlags&MK_CONTROL)
				{
		
				
				}
				else
				{
				drawInfo.vinf.OffsetPan(OldPoint-point);
				ZoomBoxing=false;
				GroupSelecting=false;
				Refresher::Instance->OverviewRefresh();
				}

			}
			else
			{
				if(BreakBuffer)
				{
					
					if(InitalSelectCount==0 && InitalUnSelectCount==0)
					{
						GroupSelecting=true;
					}
					else
					{
						if(nFlags&MK_CONTROL && !DidMoveCopy)
						{
							ObjMan->Select(data_point);
							if(!ObjMan->CopySelection())
								MessageBox("Copy Operation Failed","Copy Fail",MB_OK);
							else
							{
							MoveCopyPoint.x=-MoveCopyPoint.x;
							MoveCopyPoint.y=-MoveCopyPoint.y;
							MoveCopyPoint.z=-MoveCopyPoint.z;
							MoveCopyQuat.w=-MoveCopyQuat.w;
							ObjMan->OffsetSelection(MoveCopyPoint);
							ObjMan->RotateSelection(MoveCopyQuat);
							ObjMan->ClearSelection();
							ObjMan->PasteClipBoard(Point3D(0.0f,0.0f,0.0f));
							}
							DidMoveCopy=true;
							Refresher::Instance->ObjManSelRefresh();
						
						}
						
						if(AltKey)
						{	//Rotate
							YawPitchRoll rot(0.0f,0.0f,0.0f);
							Scalar yd=(float)(OldPoint.y-point.y)/crect.Height();
							Scalar xd=(float)(OldPoint.x-point.x)/crect.Width();
							rot.yaw=Two_Pi*xd;
							UnitQuaternion quatrot;
							UnitQuaternion tquat;
							quatrot=rot;
							tquat.Multiply(quatrot,MoveCopyQuat);
							MoveCopyQuat=tquat;
							ObjMan->RotateSelection(quatrot);
							Refresher::Instance->DrawRefresh();
							
						}
						else
						{	//Offset
							Point3D vect;
							vect=data_point;
							vect-=drawInfo.vinf.ScreenToData(OldPoint);
							ObjMan->OffsetSelection(vect);
							Refresher::Instance->DrawRefresh();
							if(!DidMoveCopy) MoveCopyPoint+=vect;
						}
						
					}
					
					if(GroupSelecting)
					{
						GroupSelBox.left=point.x<GroupSelAnchor.x?point.x:GroupSelAnchor.x;
						GroupSelBox.right=point.x>GroupSelAnchor.x?point.x:GroupSelAnchor.x;
						GroupSelBox.top=point.y<GroupSelAnchor.y?point.y:GroupSelAnchor.y;
						GroupSelBox.bottom=point.y>GroupSelAnchor.y?point.y:GroupSelAnchor.y;
						Refresher::Instance->OverviewRefresh();
					}
					
					
				}
				else
				{
					if(((point.x-BufferPoint.x)*(point.x-BufferPoint.x)+(point.y-BufferPoint.y)*(point.y-BufferPoint.y))>25) 
					{
						BreakBuffer=true;
						ObjMan->SavePosForUndo();
						//					ObjMan->SaveRotForUndo();
					}
				}
			}		
		} //end of Left Button
		
		
		
		if(nFlags&MK_RBUTTON)
		{
		CSize delta;
		delta=OldPoint-point;

		if(CameraController::GetInstance()->RevMouse)
			delta.cy=-delta.cy;

			
			YawPitchRange ypr=CameraController::GetInstance()->GetYawPitchRange();
			CameraController::GetInstance()->RBMode=true;

			Scalar yd=(float)(delta.cy)*Two_Pi/crect.Height();
			Scalar xd=(float)(delta.cx)*Two_Pi/crect.Width();
			ypr.yaw+=xd;
			ypr.pitch+=yd;
			CameraController::GetInstance()->SetYawPitchRange(ypr);
			CameraController::GetInstance()->Update();
			Refresher::Instance->DrawRefresh();
			
		}
		else
		{
			CameraController::GetInstance()->RBMode=false;
		}
		
		
		if (m_DistanceLineStartPos != Stuff::Point3D(-1,-1,-1))
		{
			m_DistanceLineEndPos = drawInfo.vinf.ScreenToData(point);
			Refresher::Instance->OverviewRefresh();
		}
		
		if(nFlags&(MK_MBUTTON|MK_RBUTTON|MK_LBUTTON)) 	OldPoint=point;
	}	//End multizone
	
	CWnd::OnMouseMove(nFlags, point);
}

void OverviewWindow::OnLButtonDown(UINT nFlags, CPoint point) 
{
	short SpaceKey=GetAsyncKeyState(VK_SPACE);
if(nFlags&MK_CONTROL && SpaceKey)
{
			CPoint ZoomBufferPoint=point;
			ZoomBreakBuffer=false;
			
			OldPoint=point;
			ZoomBoxAnchor=point;
			ZoomBox=CRect(point,point);
			ZoomBoxing=false;	

}
else
{
	OldPoint=point;
	Point3D data_point=drawInfo.vinf.ScreenToData(point);
	GroupSelecting=false;
	GroupSelAnchor=point;
	GroupSelBox=CRect(point,point);
	BufferPoint=point;
	BreakBuffer=false;
	DidMoveCopy=false;
	AddedObject=false;
	InitalSelectCount=ObjMan->SelectionDepth(data_point);
	InitalUnSelectCount=ObjMan->ObjectDepth(data_point)-InitalSelectCount;
	MoveCopyPoint=Point3D(0.0f,0.0f,0.0f);
	MoveCopyQuat=UnitQuaternion::Identity;
	
	if(InitalUnSelectCount>0 && !(nFlags&MK_SHIFT) && !(nFlags&MK_CONTROL)) 
		ObjMan->ClearSelection(); 
	
	if(!(nFlags&MK_CONTROL)) 
		ObjMan->Select( drawInfo.vinf.ScreenToData(point));
	
	if((InitalSelectCount==0 && InitalUnSelectCount==0) && (nFlags&MK_SHIFT)) BreakBuffer=true;
	
	Refresher::Instance->OverviewRefresh();	
	Refresher::Instance->ObjManSelRefresh();
}	
	SetCapture();	
	CWnd::OnLButtonDown(nFlags, point);
}

void OverviewWindow::OnLButtonUp(UINT nFlags, CPoint point) 
{
	short SpaceKey=GetAsyncKeyState(VK_SPACE);
	short AltKey=GetAsyncKeyState(VK_MENU);
	
	if(ZoomBoxing)
	{
				ZoomBoxing=false;
				if(ZoomBox.Width()!=0 && ZoomBox.Height()!=0) 
				{
					Point3D min,max;
					min=drawInfo.vinf.ScreenToData(ZoomBox.TopLeft());
					max=drawInfo.vinf.ScreenToData(ZoomBox.BottomRight());
					drawInfo.vinf.SetViewLimits(min,max);
				}
				
	}
	else
	{
	
	if(InitalSelectCount==0 && InitalUnSelectCount==0 && !(nFlags&MK_SHIFT) && !AddedObject && !SpaceKey) 
		ObjMan->ClearSelection();
	
	Point3D data_point=drawInfo.vinf.ScreenToData(point);
	if(GroupSelecting)
	{
		if(!(nFlags&MK_SHIFT) && !(nFlags&MK_CONTROL) && !AddedObject) 
			ObjMan->ClearSelection();
		
		
		ObjMan->Select(drawInfo.vinf.ScreenToData(GroupSelBox.TopLeft()),
			drawInfo.vinf.ScreenToData(GroupSelBox.BottomRight()));
	}
	else
	{
		if(nFlags&MK_CONTROL && !DidMoveCopy)
		{
			ObjMan->ToggleSelect(data_point);
		}
	}
	
	if(DidMoveCopy)
	{
		Refresher::Instance->WorldRefresh();
	}
	
	GroupSelecting=false;
	}
	Refresher::Instance->OverviewRefresh();	
	Refresher::Instance->ObjManSelRefresh();
	ReleaseCapture();	
	CWnd::OnLButtonUp(nFlags, point);
}

void OverviewWindow::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	short SpaceKey=GetAsyncKeyState(VK_SPACE);
	short AltKey=GetAsyncKeyState(VK_MENU);
	Point3D data_point=drawInfo.vinf.ScreenToData(point);
	if(ObjMan->SelectionDepth(data_point)==0)
	{
		if(!ObjMan->AddAt(data_point,&ShowFlag,AltKey?true:false))
			MessageBox("Object Creation Failed","Creation Failure",MB_OK);
		
		ObjMan->UpdateVisibility(ShowFlag);
		ObjMan->Select(data_point);
		AddedObject=true;
	}
	else
	{
		ObjMan->SetProperties(data_point,this);
	}
	Refresher::Instance->WorldRefresh();
	CWnd::OnLButtonDblClk(nFlags, point);
}

void OverviewWindow::OnRButtonDown(UINT nFlags, CPoint point) 
{
	CameraController::GetInstance()->SetLookAt(drawInfo.vinf.ScreenToData(point),true);
	CameraController::GetInstance()->SetLookAtMode(false);
	CameraController::GetInstance()->Update();
	Refresher::Instance->DrawRefresh();
	
	CWnd::OnRButtonDown(nFlags, point);
}

void OverviewWindow::OnRButtonUp(UINT nFlags, CPoint point) 
{
	
	CWnd::OnRButtonUp(nFlags, point);
}


void OverviewWindow::OnRButtonDblClk(UINT nFlags, CPoint point) 
{
	EdGUIObject *obj;
	Point3D data_point=drawInfo.vinf.ScreenToData(point);
	obj=ObjMan->GetObjAtPoint(data_point);
	
	if(obj)
	{
	ObjMan->ClearSelection();
	ObjMan->Select(data_point);
	
	if (CameraController::GetInstance()->StaysInsideBounds(obj->GetPos(),
			CameraController::GetInstance()->GetYawPitchRange()) == true)
		{
			CameraController::GetInstance()->SetLookAt(obj->GetPos(),false);
			CameraController::GetInstance()->Update();
			CameraController::GetInstance()->SetLookAtMode(true);
		}
	}
	else
	{
		CameraController::GetInstance()->SetLookAt(data_point,false);
		CameraController::GetInstance()->Update();
	}
	Refresher::Instance->DrawRefresh();
	
	// TODO: Add your message handler code here and/or call default
	
	CWnd::OnRButtonDblClk(nFlags, point);
}




void OverviewWindow::DrawHelpers(CDC *pDC)
{
	pDC->SelectObject(GetStockObject(NULL_BRUSH));
	pDC->SetBkMode(TRANSPARENT);
	pDC->SetTextColor(0x0000ff);
	
	
		drawInfo.SetDC(pDC);
	
	//Draw Grid 
	if(DisplayUserGrid)
	{
		pDC->SelectObject(GridPen);
		DrawGrid(UserGridSize.x,UserGridSize.z,pDC);
	}
	
	//Draw Tile Grid
	if(DisplayTileGrid)
	{
		pDC->SelectObject(DarkGreenPen);
		DrawGrid(drawInfo.vinf.GetTileSize(),drawInfo.vinf.GetTileSize(),pDC);
		DrawTileEntityCounts(pDC);
		ObjMan->DrawTileViolation(drawInfo);
	}
	
	//Draw Zone Grid
	if(ObjMan->IsMultiZone())
	{
		pDC->SelectObject(RedPen);
		DrawGrid(drawInfo.vinf.GetZoneSize(),drawInfo.vinf.GetZoneSize(),pDC);
	}
	else
		if(DisplayZoneGrid)
		{
			pDC->SelectObject(GreenPen);
			DrawGrid(drawInfo.vinf.GetZoneSize(),drawInfo.vinf.GetZoneSize(),pDC);
		}
		

		
		// Draw Objects
		switch(TagFlag)
		{
		case TF_NEVER:
			ObjMan->DrawUnSelectedObjects(drawInfo,false);
			ObjMan->DrawSelectedObjects(drawInfo,false);
			break;
			
		case TF_ALWAYS:
			ObjMan->DrawUnSelectedObjects(drawInfo,true);
			ObjMan->DrawSelectedObjects(drawInfo,true);
			break;
			
		case TF_ONSELECT:
			ObjMan->DrawUnSelectedObjects(drawInfo,false);
			ObjMan->DrawSelectedObjects(drawInfo,true);
			break;
		}
	
		
		if (ObjMan->GetCameraController())
			ObjMan->GetCameraController()->Draw(drawInfo);
		
		//Draw Selection Box
		pDC->SelectObject(GetStockObject(NULL_BRUSH));

		if(GroupSelecting)
		{
			pDC->SelectObject(BoxPen);
			pDC->Rectangle(GroupSelBox);
		}
		
		if(ZoomBoxing)
		{
			pDC->SelectObject(BoxPen);
			pDC->Rectangle(ZoomBox);
		}
		
		if (m_DistanceLineStartPos != Stuff::Point3D(-1,-1,-1))
		{
			pDC->MoveTo(drawInfo.vinf.DataToScreen(m_DistanceLineStartPos));
			pDC->LineTo(drawInfo.vinf.DataToScreen(m_DistanceLineEndPos));
			
			Stuff::Point3D center(m_DistanceLineStartPos);
			center += m_DistanceLineEndPos;
			center *= 0.5f;
			CPoint center2D(drawInfo.vinf.DataToScreen(center));
			
			Stuff::Vector3D delta;
			delta.Subtract(m_DistanceLineStartPos,m_DistanceLineEndPos);
			
			CString s;
			s.Format("%.2f",delta.GetApproximateLength());
			
			pDC->TextOut(center2D.x + 5,center2D.y + 5,s.GetBuffer(0));
		}
}


void OverviewWindow::OnClose() 
{
	ShowWindow(SW_HIDE);
	//	CWnd::OnClose();
}

bool OverviewWindow::SetCorrectSize(int cx,int cy)
{
	if(drawInfo.vinf.GetMapRatio()!=(float)cx/cy)	
	{
		if(cx<cy)
		{
			// Fix X
			cy=(int)(cx*drawInfo.vinf.GetMapRatio());
		}
		else
		{	
			//Fix Y
			cx=(int)(cy/drawInfo.vinf.GetMapRatio());
		}
		
		SetWindowPos(NULL,0,0,cx,cy,SWP_NOMOVE|SWP_NOZORDER);
		return	false;
		
	}
	return true;
}

void OverviewWindow::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize(nType, cx, cy);
	InitBackBuffer();
}


void OverviewWindow::OnMouseHover(UINT nFlags, CPoint point)
{
	
	
}


LRESULT OverviewWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	// TODO: Add your specialized code here and/or call the base class
	MsgHan.Lock();

	switch(message)
	{
	case WM_RBUTTONDOWN:
		CameraController::GetInstance()->RBMode=true;
	case WM_LBUTTONDOWN:
		SetCapture();
		break;
	case WM_RBUTTONUP:
		CameraController::GetInstance()->RBMode=false;
	case WM_LBUTTONUP:
		ReleaseCapture();
		break;
	case WM_MOUSELEAVE:
				CameraController::GetInstance()->RBMode=false;

		break;

	case WM_MBUTTONDBLCLK:
		{
			drawInfo.vinf.SetZoom(1.0f);	// Zoom Extents
			Refresher::Instance->OverviewRefresh();	
		}
		break;
	case WM_MBUTTONDOWN:
		{
			CPoint point=CPoint(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam));
			CPoint ZoomBufferPoint=point;
			ZoomBreakBuffer=false;
			
			OldPoint=point;
			ZoomBoxAnchor=point;
			ZoomBox=CRect(point,point);
			ZoomBoxing=false;	
			SetCapture();	
		}
		break;
		
	case WM_MBUTTONUP:
		{
			CPoint point=CPoint(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam));
			if(ZoomBoxing)
			{
				ZoomBoxing=false;
				if(ZoomBox.Width()!=0 && ZoomBox.Height()!=0) 
				{
					Point3D min,max;
					min=drawInfo.vinf.ScreenToData(ZoomBox.TopLeft());
					max=drawInfo.vinf.ScreenToData(ZoomBox.BottomRight());
					drawInfo.vinf.SetViewLimits(min,max);
					Refresher::Instance->OverviewRefresh();	
				}
				
			}
			else
			{
				drawInfo.vinf.SetPan(point);
				Refresher::Instance->OverviewRefresh();	
			}
			ReleaseCapture();	
		}
		break;
		
	case WM_MOUSEHOVER:
		{
			OnMouseHover((UINT)wParam,CPoint(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)));
			
			TRACKMOUSEEVENT tme;
			tme.cbSize=sizeof(TRACKMOUSEEVENT);
			tme.dwFlags=TME_HOVER;
			tme.hwndTrack=m_hWnd;
			tme.dwHoverTime=HOVER_DEFAULT;
			_TrackMouseEvent(&tme);
		}
		break;
		
	}
	
	LRESULT res=CWnd::WindowProc(message, wParam, lParam);

	MsgHan.Unlock();
	return res;
}

void OverviewWindow::DrawTileEntityCounts( CDC *pDC)
{
float xspace=drawInfo.vinf.GetTileSize();
float yspace=drawInfo.vinf.GetTileSize();
	if(xspace<=0 || yspace<=0) return;
	
	Point3D goff,wpnt,min,max;
	drawInfo.vinf.GetViewLimits(&min,&max);
	
	goff=drawInfo.vinf.GetMapOrg();
	goff.x=xspace*((goff.x/xspace)-(float)floor(goff.x/xspace));
	goff.z=yspace*((goff.z/yspace)-(float)floor(goff.z/yspace));
	
	
	CPoint sp,ep;
	float xinc,yinc,xstop,ystop;
	wpnt.y=0.0f;
	
	yinc=yspace*(float)floor(min.z/yspace)-goff.z;
	ystop=max.z;
	while(yinc<=ystop)
	{
		xinc=xspace*(float)floor(min.x/xspace)-goff.x;
		xstop=max.x;
		while(xinc<=xstop)
		{
		int tx=(int)((xinc+drawInfo.vinf.GetMapSize().x*0.5f)/xspace),ty=(int)((yinc+drawInfo.vinf.GetMapSize().z*0.5f)/yspace);
		int etcount=EntitiesInTile(tx,ty);
		
		if(etcount>0)
		{
		if(etcount<=5)				pDC->SetTextColor(0x00ff00);
		else if(etcount>5 && etcount<10 ) pDC->SetTextColor(0x00ffff);
		else if(etcount>=10)				pDC->SetTextColor(0x0000ff);
		wpnt.x=xinc;
		wpnt.z=yinc;
		
		ep=drawInfo.vinf.DataToScreen(wpnt);

		wpnt.x=xinc+xspace;
		wpnt.z=yinc+yspace;
		sp=drawInfo.vinf.DataToScreen(wpnt);
		
		CRect rct(sp,ep);
		CString txt;
		txt.Format("%i",etcount);

		pDC->DrawText(txt,&rct,DT_VCENTER|DT_CENTER  );
		
		}
		
		xinc+=xspace;
		}
		yinc+=yspace;
	}
	

}

void OverviewWindow::DrawGrid(float xspace, float yspace, CDC *pDC)
{
	if(xspace<=0 || yspace<=0) return;
	
	Point3D goff,wpnt,min,max;
	drawInfo.vinf.GetViewLimits(&min,&max);
	float stop;
	
	goff=drawInfo.vinf.GetMapOrg();
	goff.x=xspace*((goff.x/xspace)-(float)floor(goff.x/xspace));
	goff.z=yspace*((goff.z/yspace)-(float)floor(goff.z/yspace));
	
	
	CPoint sp,ep;
	float inc;
	wpnt.y=0.0f;
	
	inc=yspace*(float)floor(min.z/yspace)-goff.z;
	stop=max.z;
	while(inc<=stop)
	{
		wpnt.z=inc;
		
		wpnt.x=min.x;
		sp=drawInfo.vinf.DataToScreen(wpnt);
		
		wpnt.x=max.x;
		ep=drawInfo.vinf.DataToScreen(wpnt);
		
		pDC->MoveTo(sp);
		pDC->LineTo(ep);
		inc+=yspace;
	}
	
	inc=xspace*(float)floor(min.x/xspace)-goff.x;
	stop=max.x;
	while(inc<=stop)
	{
		wpnt.x=inc;
		
		wpnt.z=min.z;
		sp=drawInfo.vinf.DataToScreen(wpnt);
		
		wpnt.z=max.z;
		ep=drawInfo.vinf.DataToScreen(wpnt);
		
		pDC->MoveTo(sp);
		pDC->LineTo(ep);
		
		inc+=xspace;
	}
	
	
}



BOOL OverviewWindow::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	
	CPoint point=pt;
	
	CRect crct;
	ScreenToClient(&point);
	GetWindowRect(&crct);
	Point3D newpan=drawInfo.vinf.ScreenToData(point);
	
	if(zDelta>0) 
		drawInfo.vinf.MultiplyZoom(1.5f);
	else
		drawInfo.vinf.MultiplyZoom(1/1.5f);
	
	if(crct.PtInRect(pt))
	{
		drawInfo.vinf.SetPan( newpan);
	}
	
		  Refresher::Instance->OverviewRefresh();
		  return CWnd::OnMouseWheel(nFlags, zDelta, pt);
}


void OverviewWindow::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	Point3D porg=drawInfo.vinf.ScreenToData(CPoint(0,0));
		Point3D mpoint;
		bool pmmz=ObjMan->IsMultiZone();

		switch(nChar)
		{
			
		case VK_UP:
			{
				mpoint=drawInfo.vinf.ScreenToData(CPoint(0,-1*nRepCnt));
				mpoint-=porg;
				ObjMan->OffsetSelection(mpoint);
				
				if(!pmmz && ObjMan->IsMultiZone() )
				{
				mpoint.x=-mpoint.x;
				mpoint.y=-mpoint.y;
				mpoint.z=-mpoint.z;
				ObjMan->OffsetSelection(mpoint);
				}
				
				Refresher::Instance->DrawRefresh();
				break;
			}
			
		case VK_DOWN:
			{
				mpoint=drawInfo.vinf.ScreenToData(CPoint(0,1*nRepCnt));
				mpoint-=porg;
				ObjMan->OffsetSelection(mpoint);

				if(!pmmz && ObjMan->IsMultiZone() )
				{
				mpoint.x=-mpoint.x;
				mpoint.y=-mpoint.y;
				mpoint.z=-mpoint.z;
				ObjMan->OffsetSelection(mpoint);
				}

				Refresher::Instance->DrawRefresh();
				break;
			}
			
		case VK_LEFT:
			{
				mpoint=drawInfo.vinf.ScreenToData(CPoint(-1*nRepCnt,0));
				mpoint-=porg;
				ObjMan->OffsetSelection(mpoint);

				if(!pmmz && ObjMan->IsMultiZone() )
				{
				mpoint.x=-mpoint.x;
				mpoint.y=-mpoint.y;
				mpoint.z=-mpoint.z;
				ObjMan->OffsetSelection(mpoint);
				}

				Refresher::Instance->DrawRefresh();
				break;
			}
			
		case VK_RIGHT:
			{
				mpoint=drawInfo.vinf.ScreenToData(CPoint(1*nRepCnt,0));
				mpoint-=porg;
				ObjMan->OffsetSelection(mpoint);

				if(!pmmz && ObjMan->IsMultiZone() )
				{
				mpoint.x=-mpoint.x;
				mpoint.y=-mpoint.y;
				mpoint.z=-mpoint.z;
				ObjMan->OffsetSelection(mpoint);
				}

				Refresher::Instance->DrawRefresh();
				break;
			}
		
		case VK_SPACE:
			{
			OldCur=SetCursor(HandCur);
			}
			break;
	case VK_RETURN: 
		{
			ObjMan->SetPropertiesOfSelected(this);
			Refresher::Instance->WorldRefresh();

//			Refresher::Instance->DrawRefresh();
//			Refresher::Instance->ObjManListRefresh();
			break;	
		}
		
	case VK_DELETE: 
		{
			ObjMan->DeleteSelection();
			Refresher::Instance->WorldRefresh();
			break;	
		}

	case 'M':
	{	
		if (m_DistanceLineStartPos == Stuff::Point3D(-1,-1,-1))
		{
			m_DistanceLineStartPos = drawInfo.vinf.ScreenToData(m_LastMousePos);
			m_DistanceLineEndPos = m_DistanceLineStartPos;
		}
		break;
	}
		
		}
		
	
	CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

void OverviewWindow::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	switch(nChar)
	{
	case VK_UP:
	case VK_DOWN:
	case VK_LEFT:
	case VK_RIGHT:
		ObjMan->SavePosForUndo();
		break;
	
	case VK_SPACE:
	{
	SetCursor(OldCur);
	}
	break;	

	case 'M':
	{	
		m_DistanceLineStartPos = Stuff::Point3D(-1,-1,-1);
		m_DistanceLineEndPos = m_DistanceLineStartPos;
		break;
	}

	}
}

void OverviewWindow::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	
	CWnd::OnChar(nChar, nRepCnt, nFlags);
}

void OverviewWindow::SetViewMode(ViewMode vm)
{
	CurrentVMode=vm;
	BuildBackGround();
	Refresher::Instance->OverviewRefresh();
}

void OverviewWindow::SaveToReg()
{
	m_COverviewProperties->SaveToReg();
	gos_SaveDataToRegistry("Show Flags",&ShowFlag,sizeof(ShowFlag));
	
	CRect rct;
	CString wintitle;
	GetWindowText(wintitle);
	
	
	gos_SaveDataToRegistry((char *)(LPCSTR)(wintitle+"DisplayUserGrid"),&DisplayUserGrid,sizeof(DisplayUserGrid));
	gos_SaveDataToRegistry((char *)(LPCSTR)(wintitle+"ZoneGrid"),&DisplayZoneGrid,sizeof(DisplayZoneGrid));
	gos_SaveDataToRegistry((char *)(LPCSTR)(wintitle+"TileGrid"),&DisplayTileGrid,sizeof(DisplayTileGrid));
	gos_SaveDataToRegistry((char *)(LPCSTR)(wintitle+"UserGridSize"),&UserGridSize,sizeof(UserGridSize));
	gos_SaveDataToRegistry((char *)(LPCSTR)(wintitle+"TagFlag"),&TagFlag,sizeof(TagFlag));
	gos_SaveDataToRegistry((char *)(LPCSTR)(wintitle+"ViewMode"),&CurrentVMode,sizeof(CurrentVMode));
	
	drawInfo.SaveToReg();
}

void OverviewWindow::LoadFromReg()
{
	unsigned long size;
	CRect rct;
	CString wintitle;
	GetWindowText(wintitle);
	
	drawInfo.LoadFromReg();
	m_COverviewProperties->LoadFromReg();
	
	gos_LoadDataFromRegistry("Show Flags",&ShowFlag,&size);
	m_COverviewProperties->Refresh();
	ObjMan->UpdateVisibility(ShowFlag);
	
	size=sizeof(DisplayUserGrid);
	gos_LoadDataFromRegistry((char *)(LPCSTR)(wintitle+"DisplayUserGrid"),&DisplayUserGrid,&size);
	size=sizeof(DisplayZoneGrid);
	gos_LoadDataFromRegistry((char *)(LPCSTR)(wintitle+"ZoneGrid"),&DisplayZoneGrid,&size);
	size=sizeof(DisplayTileGrid);
	gos_LoadDataFromRegistry((char *)(LPCSTR)(wintitle+"TileGrid"),&DisplayTileGrid,&size);
	size=sizeof(UserGridSize);
	gos_LoadDataFromRegistry((char *)(LPCSTR)(wintitle+"UserGridSize"),&UserGridSize,&size);
	
	
	
	
	size=sizeof(TagFlag);
	gos_LoadDataFromRegistry((char *)(LPCSTR)(wintitle+"TagFlag"),&TagFlag,&size);
	
	size=sizeof(CurrentVMode);
	gos_LoadDataFromRegistry((char *)(LPCSTR)(wintitle+"ViewMode"),&CurrentVMode,&size);
}

void OverviewWindow::OnBackgroundHeightfield() 
{
	SetViewMode(OverviewWindow::VM_HFIELD);
}

void OverviewWindow::OnBackgroundSlopemap() 
{
	SetViewMode(OverviewWindow::VM_SLOPEMAP);
}

void OverviewWindow::OnBackgroundTexture() 
{
	SetViewMode(OverviewWindow::VM_TEXTURE);
}

void OverviewWindow::OnEditCopy() 
{
	if(!ObjMan->CopySelection())
		MessageBox("Copy Operation Failed","Copy Fail",MB_OK);

	Refresher::Instance->WorldRefresh();
}

void OverviewWindow::OnEditCut() 
{
	if(!ObjMan->CutSelection())
		MessageBox("Cut Operation Failed","Cut Fail",MB_OK);

	Refresher::Instance->WorldRefresh();
}

void OverviewWindow::OnEditDelete() 
{
	ObjMan->DeleteSelection();
	Refresher::Instance->WorldRefresh();
}

void OverviewWindow::OnEditGroup() 
{
	ObjMan->GroupSelected();
	Refresher::Instance->WorldRefresh();
}

void OverviewWindow::OnEditPaste() 
{
	ObjMan->PasteClipBoard();
	Refresher::Instance->WorldRefresh();
}

void OverviewWindow::OnEditRedo() 
{
	ObjMan->Redo();
	Refresher::Instance->WorldRefresh();
}

void OverviewWindow::OnEditUndo() 
{
	ObjMan->Undo();
	Refresher::Instance->WorldRefresh();
}

void OverviewWindow::OnEditUngoup() 
{
	ObjMan->UnGroupSelected();
	Refresher::Instance->WorldRefresh();
}

void OverviewWindow::OnUpdateBackgroundHeightfield(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(GetViewMode()==OverviewWindow::VM_HFIELD?1:0);	
}

void OverviewWindow::OnUpdateBackgroundSlopemap(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(GetViewMode()==OverviewWindow::VM_SLOPEMAP?1:0);
}

void OverviewWindow::OnUpdateBackgroundTexture(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(GetViewMode()==OverviewWindow::VM_TEXTURE?1:0);
}

void OverviewWindow::OnViewHelpersShowbounds() 
{
	if(ShowFlag&SHOW_BOUNDS) 
		ShowFlag&=~SHOW_BOUNDS;
	else 
		ShowFlag|=SHOW_BOUNDS;
	
	ObjMan->UpdateVisibility(ShowFlag);
	Refresher::Instance->WorldRefresh();	
}

void OverviewWindow::OnViewHelpersShowlattice() 
{
	if(ShowFlag&SHOW_LATTICE) 
		ShowFlag&=~SHOW_LATTICE;
	else 
		ShowFlag|=SHOW_LATTICE;
	
	ObjMan->UpdateVisibility(ShowFlag);
	Refresher::Instance->WorldRefresh();	
}

void OverviewWindow::OnViewHelpersShowpaths() 
{
	if(ShowFlag&SHOW_PATHS) 
		ShowFlag&=~SHOW_PATHS;
	else 
		ShowFlag|=SHOW_PATHS;
	
	ObjMan->UpdateVisibility(ShowFlag);
	Refresher::Instance->WorldRefresh();	
	
}

void OverviewWindow::OnViewHelpersShowtilebounds() 
{
	DisplayTileGrid=!DisplayTileGrid;
	Refresher::Instance->OverviewRefresh();
	
}

void OverviewWindow::OnViewHelpersShowusergrid() 
{
	DisplayUserGrid=!DisplayUserGrid;
	Refresher::Instance->OverviewRefresh();
}

void OverviewWindow::OnViewHelpersShowzonebounds() 
{
	DisplayZoneGrid=!DisplayZoneGrid;
	Refresher::Instance->OverviewRefresh();
}

void OverviewWindow::OnUpdateViewHelpersShowbounds(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck((ShowFlag&SHOW_BOUNDS)?1:0);
}

void OverviewWindow::OnUpdateViewHelpersShowlattice(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck((ShowFlag&SHOW_LATTICE)?1:0);
}

void OverviewWindow::OnUpdateViewHelpersShowpaths(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck((ShowFlag&SHOW_PATHS)?1:0);
}

void OverviewWindow::OnUpdateViewHelpersShowtilebounds(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(DisplayTileGrid?1:0);
}

void OverviewWindow::OnUpdateViewHelpersShowusergrid(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(DisplayUserGrid?1:0);
}

void OverviewWindow::OnUpdateViewHelpersShowzonebounds(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(DisplayZoneGrid?1:0);
}

void OverviewWindow::OnViewSetusergridproperties() 
{
	CGridProps dlg;
	dlg.m_XDist=UserGridSize.x;
	dlg.m_YDist=UserGridSize.z;
	
	if(dlg.DoModal()==IDOK)
	{
		UserGridSize.x=dlg.m_XDist;
		UserGridSize.z=dlg.m_YDist;
		DisplayUserGrid=true;	
		Refresher::Instance->OverviewRefresh();	
	}
}

void OverviewWindow::OnViewSetpencolors() 
{
	CPenProps dlg(&drawInfo,this);
	dlg.DoModal();
	Refresher::Instance->OverviewRefresh();
}

void OverviewWindow::OnUpdateEditRedo(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(ObjMan->CanRedo());
}

void OverviewWindow::OnUpdateEditUndo(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(ObjMan->CanUndo());
}

void OverviewWindow::OnToolsCreatelattice() 
{
	CString lattice_warn,warn;
	lattice_warn.LoadString(IDS_LATTICEWARNING);
	warn.LoadString(IDS_WARNING);
	if (MessageBox(lattice_warn,warn,MB_ICONQUESTION | MB_YESNO) == IDNO)
		return;
	ObjMan->CreateLattice();
	ShowFlag|=SHOW_LATTICE;
	ObjMan->UpdateVisibility(ShowFlag);
	Refresher::Instance->WorldRefresh();
	
}

void OverviewWindow::OnToolsRecalclatticelinks() 
{
	ObjMan->RecalcLatticeLinks();
	ShowFlag|=SHOW_LATTICE;
	ObjMan->UpdateVisibility(ShowFlag);
	Refresher::Instance->WorldRefresh();
}

void OverviewWindow::OnToolsResetmissionbounds() 
{
	ObjMan->ResetBounds();
	ShowFlag|=SHOW_BOUNDS;
	ObjMan->UpdateVisibility(ShowFlag);
	Refresher::Instance->OverviewRefresh();
	
}

void OverviewWindow::OnOptionsSetdefaultalignment() 
{
	CAlignDlg dlg;
	
	dlg.m_alignment=ObjMan->GetDefaultAlignment();
	if(dlg.DoModal()==IDOK)
	{
		ObjMan->SetDefaultAlignment(dlg.m_alignment);
	}
	
}

void OverviewWindow::OnViewTagsShowcustom() 
{
	CCustomTagDlg dlg;

	
	Refresher::Instance->OverviewRefresh();

	dlg.m_ShowTags=ShowTagsAlways;
	dlg.TagFlag=ObjMan->GetTagFlags();
	
	if(dlg.DoModal()==IDOK)
	{
		ObjMan->SetTagFlags(dlg.TagFlag);
		Refresher::Instance->OverviewRefresh();
		Refresher::Instance->ObjManListRefresh();
		
		ShowTagsAlways=dlg.m_ShowTags?true:false;
		
		if(ShowTagsAlways)
			TagFlag=TF_ALWAYS;
		else
			TagFlag=TF_ONSELECT;


	}
	
}


int OverviewWindow::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	m_COverviewProperties = new COverviewProperties(ObjMan,&ShowFlag,GetParent()->GetParent());
	
	return 0;
}



BOOL OverviewWindow::OnEraseBkgnd(CDC* pDC) 
{
	
	return CWnd::OnEraseBkgnd(pDC);
}

void OverviewWindow::OnToolsDispersewithbitmap() 
{
CDisperseDlg dlg(ObjMan);

if(dlg.DoModal()==IDOK)
	{

	ObjMan->UpdateVisibility(ShowFlag);
	Refresher::Instance->WorldRefresh();
	}

}


void OverviewWindow::OnToolsSnapobjecttoterrain() 
{
	ObjMan->SnapObjectToGround(true);
	Refresher::Instance->DrawRefresh();
	
}


void OverviewWindow::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
YawPitchRoll rot(0,0,0);
UnitQuaternion quatrot;

	if(nFlags&0x2000)	//Alt Key is Down
	if(GetAsyncKeyState(VK_SHIFT))
	{
		switch(nChar)
		{
			
		case VK_UP:
			{
				rot.pitch=-5*Radians_Per_Degree*nRepCnt;
				quatrot=rot;
				ObjMan->RotateSelection(quatrot);
				Refresher::Instance->DrawRefresh();
				break;
			}
			
		case VK_DOWN:
			{
				rot.pitch=+5*Radians_Per_Degree*nRepCnt;
				quatrot=rot;
				ObjMan->RotateSelection(quatrot);
				Refresher::Instance->DrawRefresh();
				break;
			}
			
		case VK_LEFT:
			{
				rot.roll=-5*Radians_Per_Degree*nRepCnt;
				quatrot=rot;
				ObjMan->RotateSelection(quatrot);
				Refresher::Instance->DrawRefresh();
				break;
			}
			
		case VK_RIGHT:
			{
				rot.roll=5*Radians_Per_Degree*nRepCnt;
				quatrot=rot;
				ObjMan->RotateSelection(quatrot);
				Refresher::Instance->DrawRefresh();
				break;
			}
			
		}
		
	}
	else 
	{
		switch(nChar)
		{
			
		case VK_UP:
			{
				ObjMan->OffsetSelection(Point3D(0,1.0f,0));
				Refresher::Instance->DrawRefresh();
				break;
			}
			
		case VK_DOWN:
			{
				ObjMan->OffsetSelection(Point3D(0,-1.0f,0));
				Refresher::Instance->DrawRefresh();
				break;
			}
			
		case VK_LEFT:
			{
				rot.yaw=5*Radians_Per_Degree*nRepCnt;
				quatrot=rot;
				ObjMan->RotateSelection(quatrot);
				Refresher::Instance->DrawRefresh();
				break;
			}
			
		case VK_RIGHT:
			{
				rot.yaw=-5*Radians_Per_Degree*nRepCnt;
				quatrot=rot;
				ObjMan->RotateSelection(quatrot);
				Refresher::Instance->DrawRefresh();
				break;
			}
			
		}
		
	}

	CWnd::OnSysKeyDown(nChar, nRepCnt, nFlags);
}

void OverviewWindow::OnSysKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if(nFlags&0x2000)	//Alt Key is Down
	switch(nChar)
	{
	case VK_UP:
	case VK_DOWN:
	case VK_LEFT:
	case VK_RIGHT:
		ObjMan->SavePosForUndo();
		break;
	}
	
	CWnd::OnSysKeyUp(nChar, nRepCnt, nFlags);
}

void OverviewWindow::OnOptionsFilllattice() 
{
	drawInfo.UseBrushes=!drawInfo.UseBrushes;
	Refresher::Instance->OverviewRefresh();
}

void OverviewWindow::OnUpdateOptionsFilllattice(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(drawInfo.UseBrushes);
}

void OverviewWindow::OnToolsDumpoverveiwcontentstofile() 
{
	CFileDialog dlg1(FALSE,"Tiffs","Output.tif",OFN_NOCHANGEDIR,"Tiffs (*.tif)|*.tif||",this);
	
	if(dlg1.DoModal()==IDOK)
	{
	Image finalimage;
	
	finalimage.CreateBlank((int)(ObjMan->GetMapSize().x/5),(int)(ObjMan->GetMapSize().z/5),
							ITYPE_RGB,24,RGBMask(0xff0000,0x00ff00,0x0000ff));
	
	switch(CurrentVMode)
	{
	case VM_TEXTURE:
		ObjMan->LoadTerrainTexture(&finalimage);
		break;
	case VM_HFIELD:
		ObjMan->BuildHFFromMap(&finalimage);
		break;
	case VM_SLOPEMAP:
		{
		Point3D pnt=ObjMan->BuildHFFromMap(&finalimage);
		ObjMan->MakeSlopeMap(&finalimage,pnt);
		}
		break;
	default: STOP(("Invalid View Mode"));
	}

	CBitmap bmp;

	BOOL res;
	void *gres;

	CDC *pDC=GetDC(),memDC;
	res=bmp.CreateCompatibleBitmap(pDC,finalimage.GetWidth(),finalimage.GetHeight());
	Verify(res);
	res=memDC.CreateCompatibleDC(pDC);
	Verify(res);
	gres=memDC.SelectObject(bmp);
	Verify(gres);
	

	BITMAPINFO       binf;
	ZeroMemory(&binf,sizeof(binf));
	binf.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
	binf.bmiHeader.biWidth=finalimage.GetWidth(); 
	binf.bmiHeader.biHeight=-finalimage.GetHeight();
	binf.bmiHeader.biPlanes=1;
	binf.bmiHeader.biBitCount=finalimage.GetBpp();
	binf.bmiHeader.biCompression=BI_RGB;
	
	res=SetDIBitsToDevice(memDC,0,0,finalimage.GetWidth(),
		finalimage.GetHeight(),0,0,0,finalimage.GetHeight(),finalimage.Lock(),
		&binf,DIB_RGB_COLORS);  
	Verify(res);
	
	finalimage.UnLock();


	ViewWindowInfo oldinfo=drawInfo.vinf;
	drawInfo.vinf.SetClientArea(CSize(finalimage.GetWidth(),finalimage.GetHeight()));
	drawInfo.vinf.SetZoom(1.0f);	// Zoom Extents
	drawInfo.vinf.SetPan(Point3D(0.0f,0.0f,0.0f));
	
	DrawHelpers(&memDC);
	drawInfo.vinf=oldinfo;
	
	res=GetDIBits(memDC,bmp,0,finalimage.GetHeight(),finalimage.Lock(),&binf,DIB_RGB_COLORS);
	Verify(res);
	finalimage.UnLock();

	finalimage.SaveTiff((char *)(LPCSTR)dlg1.GetPathName());
	
	memDC.DeleteDC();
	bmp.DeleteObject();
	ReleaseDC(pDC);

	}

}

void OverviewWindow::OnViewZoomin() 
{
		drawInfo.vinf.MultiplyZoom(1.5f);
	  Refresher::Instance->OverviewRefresh();
}

void OverviewWindow::OnViewZoomout() 
{
		drawInfo.vinf.MultiplyZoom(1/1.5f);
	  Refresher::Instance->OverviewRefresh();
}

void OverviewWindow::OnViewTagsShowtags() 
{
	if(TagFlag==TF_NEVER)
	{
		TagFlag=ShowTagsAlways?TF_ALWAYS:TF_ONSELECT;
	}
	else
		TagFlag=TF_NEVER;


}

void OverviewWindow::OnUpdateViewTagsShowtags(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(TagFlag!=TF_NEVER?1:0);
}
