// FinalBitmapWnd.cpp : implementation file
//

#include "stdafx.h"
#include "TCTb.h"
#include "FinalBitmapWnd.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern CTCTbApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CFinalBitmapWnd

//IMPLEMENT_DYNCREATE(CFinalBitmapWnd, CMDIChildWnd)



CFinalBitmapWnd::CFinalBitmapWnd()
{
	Adjust=1;
	zfactor=(float)1.0;
	hfname="none";
	curpnt=-1;
}

CFinalBitmapWnd::~CFinalBitmapWnd()
{
}


BEGIN_MESSAGE_MAP(CFinalBitmapWnd, CMDIChildWnd)
//{{AFX_MSG_MAP(CFinalBitmapWnd)
ON_WM_DESTROY()
ON_WM_CLOSE()
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_DROPFILES()
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFinalBitmapWnd message handlers

void CFinalBitmapWnd::OnDestroy() 
{
	WhitePen.DeleteObject();
	BluePen.DeleteObject();
	RedPen.DeleteObject();
	RDPen.DeleteObject();
	RedBrush.DeleteObject();
	BlueBrush.DeleteObject();


	CMDIChildWnd::OnDestroy();
	
	// TODO: Add your message handler code here
	
}

void CFinalBitmapWnd::OnClose() 
{
	//ShowWindow(SW_MINIMIZE);
	ShowWindow(SW_HIDE);	
	//	CMDIChildWnd::OnClose();
}


void CFinalBitmapWnd::MakeDisplayedBmp(TCTTerrainData *tdat)
{
	Check_Pointer(tdat);	
	CDC *pDC=GetDC();
	
	switch(theApp.DMode)
	{
	case DM_HFIELD:
		{
			int imw,imh;
			Image timg;
			HeightFieldLayer *lay;
			lay=&tdat->HFLayer;
			timg=lay->Img;
			hfname=lay->Img.GetFileName();
			
			
			timg.MakeGrayscalePalette();
			timg.MakeRGB24();
			//Change this make it work with arbitary pitch possibly code a method in image class
			imw=timg.GetWidth();
			imh=timg.GetHeight();
			
			DispBmp.DeleteObject();
			DispBmp.CreateCompatibleBitmap(pDC,imw,imh);
			
			
			CRect trct;
			trct.top=trct.left=0;
			trct.bottom=imh; trct.right=imw;
			CalcWindowRect(&trct);
			SetWindowPos(&wndTop,trct.left,trct.top,trct.Width(),trct.Height(),SWP_NOMOVE|SWP_SHOWWINDOW);   
			
			BITMAPINFOHEADER bhd;
			BITMAPINFO       binf;
			bhd.biSize=sizeof(BITMAPINFOHEADER);
			bhd.biWidth=imw; bhd.biHeight=-imh;
			bhd.biPlanes=1;
			bhd.biBitCount=24;
			bhd.biCompression=BI_RGB;
			bhd.biSizeImage=0;
			bhd.biClrImportant=0;
			binf.bmiHeader=bhd;
			
			CDC memDC;
			
			memDC.CreateCompatibleDC(pDC);
			memDC.SelectObject(&DispBmp);
			
			SetDIBitsToDevice(memDC.m_hDC,0,0,imw,
				imh,0,0,0,imh,timg.Lock(),
				&binf,DIB_RGB_COLORS);  
			timg.UnLock();
			
			memDC.DeleteDC();
		}
		break;
		
	case DM_BASETEXTURE:
		{
			int imw,imh;
			Image timg;
			TextureLayer *lay;
			lay=&tdat->BaseTexture;
			timg=lay->Img;
			hfname=lay->Img.GetFileName();
			
			timg.MakeRGB24();
			
			//Change this make it work with arbitary pitch possibly code a method in image class
			imw=timg.GetWidth();
			imh=timg.GetHeight();
			
			DispBmp.DeleteObject();
			DispBmp.CreateCompatibleBitmap(pDC,imw,imh);
			
			
			CRect trct;
			trct.top=trct.left=0;
			trct.bottom=imh; trct.right=imw;
			CalcWindowRect(&trct);
			SetWindowPos(&wndTop,trct.left,trct.top,trct.Width(),trct.Height(),SWP_NOMOVE|SWP_SHOWWINDOW);   
			
			BITMAPINFOHEADER bhd;
			BITMAPINFO       binf;
			bhd.biSize=sizeof(BITMAPINFOHEADER);
			bhd.biWidth=imw; bhd.biHeight=-imh;
			bhd.biPlanes=1;
			bhd.biBitCount=24;
			bhd.biCompression=BI_RGB;
			bhd.biSizeImage=0;
			bhd.biClrImportant=0;
			binf.bmiHeader=bhd;
			
			CDC memDC;
			
			memDC.CreateCompatibleDC(pDC);
			memDC.SelectObject(&DispBmp);
			
			SetDIBitsToDevice(memDC.m_hDC,0,0,imw,
				imh,0,0,0,imh,timg.Lock(),
				&binf,DIB_RGB_COLORS);  
			timg.UnLock();
			
			memDC.DeleteDC();
		}
		break;
	}
	
	
	
	SetWindowPos(NULL,0,0,640,640,SWP_NOMOVE|SWP_SHOWWINDOW);   
	
	ReleaseDC(pDC);	
	ReDraw();
}

int CFinalBitmapWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	CDC *pDC=GetDC();
	DispBmp.CreateCompatibleBitmap(pDC,DEFAULTBMPSIZE,DEFAULTBMPSIZE);
	
	DispBBuffer.CreateCompatibleBitmap(pDC,DEFAULTBMPSIZE,DEFAULTBMPSIZE);
	
    
	
	//Make a BitMap and Black it out.
	CDC memDC;
	
    memDC.CreateCompatibleDC(pDC);
    memDC.SelectObject(&DispBmp);
	
	BITMAP bmp;
	DispBmp.GetBitmap(&bmp);
	CRect trct;
	trct.top=trct.left=0;
	trct.bottom=bmp.bmHeight; trct.right=bmp.bmWidth;
	LastWidth=bmp.bmWidth;
	LastHeight=trct.bottom;
	CalcWindowRect(&trct);
	SetWindowPos(&wndTop,trct.left,trct.top,trct.Width(),trct.Height(),SWP_NOMOVE|SWP_SHOWWINDOW);   
	
	memDC.BitBlt(0,0,bmp.bmWidth,bmp.bmHeight,NULL,0,0,BLACKNESS);
	memDC.DeleteDC();
	WhitePen.CreatePen(PS_SOLID,1,RGB(255,255,255)); 
	BluePen.CreatePen(PS_SOLID,1,RGB(0,0,255));
	RedPen.CreatePen(PS_SOLID,3,RGB(255,0,0));
	RDPen.CreatePen(PS_DASH,1,RGB(255,0,0));
	RedBrush.CreateSolidBrush(RGB(255,0,0));
	BlueBrush.CreateSolidBrush(RGB(0,255,0));

	memDC.DeleteDC();
	ReleaseDC(pDC);

	return 0;
}

void CFinalBitmapWnd::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	ReDraw();
	// Do not call CMDIChildWnd::OnPaint() for painting messages
}

void CFinalBitmapWnd::ReDraw()
{
	
    CDC *pDC,memDC,bbDC;
	BITMAP bmp,bmp2;
	DispBmp.GetBitmap(&bmp);
	
	pDC=GetDC();
	
    memDC.CreateCompatibleDC(pDC);
    memDC.SelectObject(&DispBmp);
    bbDC.CreateCompatibleDC(pDC);
    bbDC.SelectObject(&DispBBuffer);
	
	//Blt image to back buffer
	DispBBuffer.GetBitmap(&bmp);
	DispBmp.GetBitmap(&bmp2);
	bbDC.StretchBlt(0,0,bmp.bmWidth,bmp.bmHeight,&memDC,
		0,0,bmp2.bmWidth,bmp2.bmHeight,SRCCOPY);
	
	
	
	UpdateDims();
	SplineLoop *ViewLoop;
	ViewLoop=theApp.CamInfo.ViewLoop;
	
	//Display the ViewSpline
	if(ViewLoop && theApp.CamInfo.GetMode()==CameraInfo::CM_TRACK)
	{
		Stuff::Scalar t=0.0f,step=1.0f/VSRES;
		Stuff::Point3D np;
		Stuff::Vector3D nv;
		CPoint loc;
		int i;
		
		
		bbDC.SelectObject(WhitePen);
		bbDC.SelectObject(GetStockObject(NULL_BRUSH));
		
		
		ViewLoop->Evaluate(0.0f,&np,&nv);
		bbDC.MoveTo(GridToMap(np));	
		
		for(t=step;t<=1.0f;t+=step)
		{
			ViewLoop->Evaluate(t,&np,&nv);
			bbDC.LineTo(GridToMap(np));
		} 
		
		for(i=0;i<EDCPOINTS;i++)
		{
			ViewLoop->GetCPoint(i,&np,&nv);
			loc=GridToMap(np);
			bbDC.Rectangle(loc.x-5,loc.y-5,loc.x+5,loc.y+5);
		}
		
	}
	
	//Display the Camera
	if(theApp.RVWnd && theApp.RVWnd->ActiveHField) 
	{
		
		Stuff::Point3D np;
		Stuff::Vector3D nv;
		CPoint loc,tloc;
		
		bbDC.SelectObject(RedPen);
		bbDC.SelectObject(RedBrush);
		
		if(theApp.CamInfo.GetMode()==CameraInfo::CM_TRACK)
		{
			//theApp.ViewLoop->Evaluate(theApp.RVWnd->CTime,&np,&nv);
			np=theApp.CamInfo.Loc;
			nv=theApp.CamInfo.Dir;
			
			loc=GridToMap(np);
			bbDC.Rectangle(loc.x-5,loc.y-5,loc.x+5,loc.y+5);
		}
		else
		{
			np=theApp.CamInfo.Loc;
			nv=theApp.CamInfo.Dir;
			loc=GridToMap(np);
			bbDC.Rectangle(loc.x-5,loc.y-5,loc.x+5,loc.y+5);
		}
		
		if(theApp.CamInfo.UseTarget)
		{
			tloc=GridToMap(theApp.CamInfo.TargetLoc);
			
			bbDC.SelectObject(BluePen);
			bbDC.SelectObject(GetStockObject(NULL_BRUSH));
			bbDC.Rectangle(tloc.x-5,tloc.y-5,tloc.x+5,tloc.y+5);
			
			bbDC.SelectObject(RDPen);
			bbDC.MoveTo(loc);
			bbDC.LineTo(tloc);
		}
		else
		{
			Stuff::Scalar xs,zs;
			xs=theApp.RVWnd->ActiveHField->GetXScale();
			zs=theApp.RVWnd->ActiveHField->GetZScale();
			
			bbDC.SelectObject(RedPen);
			bbDC.MoveTo(loc);
			nv.Normalize(nv);
			np.x+=nv.x*20*xs;
			np.z+=nv.z*20*zs;
			bbDC.LineTo(GridToMap(np));
		}
		
	} //end of draw camera
	
	//Display the backbuffer
	CRect crct;
	GetClientRect(&crct);
	DispBBuffer.GetBitmap(&bmp);
	pDC->BitBlt(0,0,crct.Width(),crct.Height(),&bbDC,0,0,SRCCOPY);
	
	bbDC.DeleteDC();
	memDC.DeleteDC();
	ReleaseDC(pDC);
	
}

void CFinalBitmapWnd::OnSize(UINT nType, int cx, int cy) 
{
	
	CMDIChildWnd::OnSize(nType, cx, cy);
	
	CRect crct;
	BITMAP bmp;
	GetClientRect(&crct);
	DispBmp.GetBitmap(&bmp);
	
	CDC *pDC=GetDC();
	DispBBuffer.DeleteObject();
	DispBBuffer.CreateCompatibleBitmap(pDC,crct.Width(),crct.Height());
	ReleaseDC(pDC);
	
	
	if(crct.Width()==0 || crct.Height()==0) return;
	
	if(Adjust)
	{	
		int nw,nh;
		int xdiff,ydiff;
		float bmaspect,cltaspect;
		
		
		xdiff=crct.Width()-LastWidth;
		ydiff=crct.Height()-LastHeight;
		bmaspect=(float)bmp.bmWidth/bmp.bmHeight;
		cltaspect=(float)crct.Width()/crct.Height();
		
		if(abs(xdiff)>abs(ydiff))	//Retain X and adjust Y to maintain Aspect Ratio
		{
			nw=crct.Width();
			nh=(int)(crct.Width()/bmaspect);
		}
		else						//Retain Y and adjust X to maintain Aspect Ratio
		{
			nh=crct.Height();
			nw=(int)(bmaspect*crct.Height());
		}
		
		Adjust=0;
		SetWindowPos(NULL,0,0,nw,nh,SWP_NOMOVE|SWP_SHOWWINDOW|SWP_NOZORDER|SWP_NOACTIVATE);   
		LastWidth=crct.Width();
		LastHeight=crct.Height();
		Adjust=1;
		
	}
	
	GetClientRect(&crct);
	zfactor=(float)100*crct.Width()/bmp.bmWidth;
	SetTitle();
	UpdateDims();
}

void CFinalBitmapWnd::SetTitle()
{
	CString tstr,tstr2;
	int i;
	
	i=hfname.ReverseFind('\\');
	if(i!=-1)
	{
		tstr2=hfname.Right(hfname.GetLength()-i-1);
	} 	
	tstr.Format("%s -  %3.2f%% - file = %s",TITLEVIEW2D,zfactor,tstr2);
	SetWindowText(tstr);
	
}

BOOL CFinalBitmapWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CMDIFrameWnd* pParentWnd, CCreateContext* pContext) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	return CMDIChildWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, pContext);
}

void CFinalBitmapWnd::OnDropFiles(HDROP hDropInfo) 
{
	// TODO: Add your message handler code here and/or call default
	char fname[MAX_PATH];
	CString tstr;
	DragQueryFile(hDropInfo,0,fname,MAX_PATH);
	tstr=fname;
	theApp.ImportBitmap(tstr);
	
	//	CMDIChildWnd::OnDropFiles(hDropInfo);
}

void CFinalBitmapWnd::OnEditPaste() 
{
	// TODO: Add your command handler code here
	COleDataObject DObj;
	HRESULT res;
	
	res=DObj.AttachClipboard();
	if(DObj.IsDataAvailable(CF_DIB))
	{
		CFile *fle;         
		fle=DObj.GetFileData(CF_DIB);
		BITMAPINFOHEADER ihdr;
		fle->Read(&ihdr,sizeof(ihdr));
		Image timg;
		
		
		if(!(ihdr.biBitCount==8 || ihdr.biBitCount==16 || ihdr.biBitCount==24 || ihdr.biBitCount==32)) return;
		
		
		if(ihdr.biBitCount==8)
		{
			timg.CreateSolid(ihdr.biWidth,ihdr.biHeight,ImgRGBColor(0,0,0),ITYPE_INDEXED,ihdr.biBitCount);
			fle->Seek(256*sizeof(RGBQUAD),CFile::current);   
		}
		else
			timg.CreateSolid(ihdr.biWidth,ihdr.biHeight,ImgRGBColor(0,0,0),ITYPE_RGB,ihdr.biBitCount);
		
		unsigned char *dat;
		dat=timg.Lock();
		fle->Read(dat,ihdr.biWidth*ihdr.biHeight*(ihdr.biBitCount>>3));
		timg.UnLock();
		
		theApp.ImportBitmap(timg);
		delete fle;
	}
}

void CFinalBitmapWnd::DrawViewSpline(SplineLoop *ViewLoop)
{
	if(!ViewLoop) return;
	
	Stuff::Scalar t=0.0f,step=1.0f/VSRES;
	Stuff::Point3D np;
	Stuff::Vector3D nv;
	CPoint loc;
	CDC *dc;
	dc=GetDC();
	int i;
	
	UpdateDims();
	
	dc->SelectObject(WhitePen);
	dc->SelectObject(GetStockObject(NULL_BRUSH));
	
	
	ViewLoop->Evaluate(0.0f,&np,&nv);
	dc->MoveTo(GridToMap(np));	
	
	for(t=step;t<=1.0f;t+=step)
	{
		ViewLoop->Evaluate(t,&np,&nv);
		dc->LineTo(GridToMap(np));
	} 
	
	for(i=0;i<EDCPOINTS;i++)
	{
		ViewLoop->GetCPoint(i,&np,&nv);
		loc=GridToMap(np);
		dc->Rectangle(loc.x-5,loc.y-5,loc.x+5,loc.y+5);
	}
	
	
	ReleaseDC(dc);
	
}

void CFinalBitmapWnd::OnMouseMove(UINT nFlags, CPoint point) 
{
	
	if(nFlags&MK_LBUTTON)
	{
		UpdateDims();
		if(nFlags&MK_CONTROL)
		{
			
			CPoint Dist;
			Dist=point-LastPoint;	
			
			if(nFlags&MK_SHIFT)
			{
				if(theApp.CamInfo.TarATrkFlg)	theApp.CamInfo.TarTrackAlt+=-Dist.y/100;
				else theApp.CamInfo.TargetLoc.y+=Dist.y;
				
				if(theApp.CamInfo.GetMode()==CameraInfo::CM_FREE)
					if(theApp.CamInfo.CamATrkFlg)	theApp.CamInfo.CamTrackAlt+=-Dist.y/100;
					else theApp.CamInfo.Loc.y+=Dist.y;
			}	//end of if Lbutton && Shift
			else
			{
				if(theApp.CamInfo.CamATrkFlg) theApp.CamInfo.CamTrackAlt+=-Dist.y/100;
				else theApp.CamInfo.Loc.y+=-Dist.y/100;
			}//end of if Lbutton && !Shift
		}//end of if Ctrl
		else
		{
			if(nFlags&MK_SHIFT)
			{
				if(theApp.CamInfo.UseTarget)
				{
					Stuff::Point3D tpt=MapToGrid(point);
					theApp.CamInfo.TargetLoc.x=tpt.x;
					theApp.CamInfo.TargetLoc.z=tpt.z;
				}
				else
				{
					if(theApp.CamInfo.GetMode()==CameraInfo::CM_FREE)
					{
						Stuff::Point3D tpt=MapToGrid(point),otloc=theApp.CamInfo.TargetLoc;
						theApp.CamInfo.TargetLoc.x=tpt.x;
						theApp.CamInfo.TargetLoc.z=tpt.z;
						theApp.CamInfo.TargetLoc.y=theApp.CamInfo.Loc.y;
						theApp.CamInfo.UseTarget=true;
						theApp.CamInfo.UpdateCPos();
						theApp.CamInfo.UseTarget=false;
						theApp.CamInfo.TargetLoc=otloc;
					}	
				}//end of if Use Target
			}	//end of if Lbutton && Shift
			else
			{
				if(theApp.CamInfo.GetMode()==CameraInfo::CM_TRACK && curpnt>=0)
				{
					Stuff::Point3D tpt,p3d=MapToGrid(point);
					Stuff::Vector3D v3d;
					theApp.CamInfo.ViewLoop->GetCPoint(curpnt,&tpt,&v3d);
					theApp.CamInfo.ViewLoop->SetCPoint(curpnt,p3d,v3d);
				}	
				
				if(theApp.CamInfo.GetMode()==CameraInfo::CM_FREE)
				{
					Stuff::Point3D tpt=MapToGrid(point);
					theApp.CamInfo.Loc.x=tpt.x;
					theApp.CamInfo.Loc.z=tpt.z;
				}	
			}//end of if Lbutton && !Shift
		}//end of !Ctrl
		theApp.CamInfo.UpdateCPos();
		ReDraw();
	}//end of if Lbutton 
	
	CMDIChildWnd::OnMouseMove(nFlags, point);
}

void CFinalBitmapWnd::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	UpdateDims();
	LastPoint=point;
	if(theApp.CamInfo.GetMode()==CameraInfo::CM_TRACK)
	{
		curpnt=theApp.CamInfo.ViewLoop->GetClosestCPoint(MapToGrid(point));
	}	
	OnMouseMove(nFlags, point);
	CMDIChildWnd::OnLButtonDown(nFlags, point);
}

Stuff::Point3D CFinalBitmapWnd::MapToGrid(CPoint &pnt)
{
	Stuff::Point3D tpnt;
	Stuff::Scalar xs,zs,xgsze,zgsze;
	xs=theApp.RVWnd->ActiveHField->GetXScale();
	zs=theApp.RVWnd->ActiveHField->GetZScale();
	xgsze=theApp.TData.HFLayer.Img.GetWidth()*xs;
	zgsze=theApp.TData.HFLayer.Img.GetHeight()*zs;
	Stuff::Scalar xmapsize,ymapsize;
	xmapsize=(float)crct.Width();
	ymapsize=(float)crct.Height();
	
	tpnt.x=(pnt.x/xmapsize)*xgsze;
	tpnt.z=(pnt.y/ymapsize)*zgsze;
	
	//	tpnt.x=((pnt.x-crct.Width()/2)*xs)/(zfactor/100)+(DBmp.bmWidth/2)*xs;
	//	tpnt.z=((pnt.y-crct.Height()/2)*zs)/(zfactor/100)+(DBmp.bmHeight/2)*zs;
	//tpnt.y=theApp.RVWnd->ActiveHField->GetHeight(tpnt.x,tpnt.z);
	tpnt.y=0.0f;
	
	return tpnt;
}

CPoint CFinalBitmapWnd::GridToMap(Stuff::Point3D &pnt)
{
	CPoint tpnt;
	Stuff::Scalar xs,zs,xgsze,zgsze;
	xs=theApp.RVWnd->ActiveHField->GetXScale();
	zs=theApp.RVWnd->ActiveHField->GetZScale();
	xgsze=(theApp.TData.HFLayer.Img.GetWidth())*xs;
	zgsze=(theApp.TData.HFLayer.Img.GetHeight())*zs;
	Stuff::Scalar xmapsize,ymapsize;
	xmapsize=(float)crct.Width();
	ymapsize=(float)crct.Height();
	
	tpnt.x=(int)((pnt.x/xgsze)*xmapsize);
	tpnt.y=(int)((pnt.z/zgsze)*ymapsize);
	
	/*
	tpnt.x=(int)(
	(pnt.x-(DBmp.bmWidth/2)*xs)*(zfactor*.01))/xs+crct.Width()/2;
	tpnt.y=(int)(
	(pnt.z-(DBmp.bmHeight/2)*zs)*(zfactor*.01))/zs+crct.Height()/2;
	*/	
	return tpnt;
}


void CFinalBitmapWnd::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	curpnt=-1;	
	
	CMDIChildWnd::OnLButtonUp(nFlags, point);
}

void CFinalBitmapWnd::UpdateDims()
{
	GetClientRect(&crct);
	DispBmp.GetBitmap(&DBmp);
}




void CFinalBitmapWnd::DrawCamera()
{
	if(!theApp.RVWnd || !theApp.RVWnd->ActiveHField) return;
	CDC *dc;
	dc=GetDC();
	
	
	UpdateDims();
	
	Stuff::Point3D np;
	Stuff::Vector3D nv;
	CPoint loc,tloc;
	
	dc->SelectObject(RedPen);
	dc->SelectObject(RedBrush);
	
	if(theApp.CamInfo.GetMode()==CameraInfo::CM_TRACK)
	{
		//theApp.ViewLoop->Evaluate(theApp.RVWnd->CTime,&np,&nv);
		np=theApp.CamInfo.Loc;
		nv=theApp.CamInfo.Dir;
		
		loc=GridToMap(np);
		dc->Rectangle(loc.x-5,loc.y-5,loc.x+5,loc.y+5);
	}
	else
	{
		np=theApp.CamInfo.Loc;
		nv=theApp.CamInfo.Dir;
		loc=GridToMap(np);
		dc->Rectangle(loc.x-5,loc.y-5,loc.x+5,loc.y+5);
	}
	
	if(theApp.CamInfo.UseTarget)
	{
		tloc=GridToMap(theApp.CamInfo.TargetLoc);
		
		dc->SelectObject(BluePen);
		dc->SelectObject(GetStockObject(NULL_BRUSH));
		dc->Rectangle(tloc.x-5,tloc.y-5,tloc.x+5,tloc.y+5);
		
		dc->SelectObject(RDPen);
		dc->MoveTo(loc);
		dc->LineTo(tloc);
	}
	else
	{
		Stuff::Scalar xs,zs;
		xs=theApp.RVWnd->ActiveHField->GetXScale();
		zs=theApp.RVWnd->ActiveHField->GetZScale();
		
		dc->SelectObject(RedPen);
		dc->MoveTo(loc);
		nv.Normalize(nv);
		np.x+=nv.x*20*xs;
		np.z+=nv.z*20*zs;
		dc->LineTo(GridToMap(np));
	}
	
	
	
	ReleaseDC(dc);
}




void CFinalBitmapWnd::OnRButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CMDIChildWnd::OnRButtonDown(nFlags, point);
}

void CFinalBitmapWnd::OnRButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CMDIChildWnd::OnRButtonUp(nFlags, point);
}

void CFinalBitmapWnd::BoundSpline(SplineLoop *ViewLoop)
{
	int i;
	Stuff::Point3D np;
	Stuff::Vector3D nv;
	CPoint loc;
	UpdateDims();
	for(i=0;i<EDCPOINTS;i++)
	{
		ViewLoop->GetCPoint(i,&np,&nv);
		loc=GridToMap(np);
		if(loc.x<0) loc.x=0;
		if(loc.y<0) loc.y=0;
		if(loc.x>theApp.TData.HFLayer.Img.GetWidth()) loc.x=theApp.TData.HFLayer.Img.GetWidth();
		if(loc.y>theApp.TData.HFLayer.Img.GetHeight()) loc.y=theApp.TData.HFLayer.Img.GetHeight();
		np=MapToGrid(loc);
		ViewLoop->SetCPoint(i,np,nv);
	}
	
}

void CFinalBitmapWnd::DrawGrid(ToDrawTriangle **tlist,int tnum,COLORREF col,float cx,float cy,float rad)
{
    CDC *pDC,memDC,bbDC;
	BITMAP bmp,bmp2;
	DispBmp.GetBitmap(&bmp);
	pDC=GetDC();
	
	CPen pen(PS_SOLID,1,col);

    memDC.CreateCompatibleDC(pDC);
    memDC.SelectObject(&DispBmp);
    bbDC.CreateCompatibleDC(pDC);
    bbDC.SelectObject(&DispBBuffer);
	
	//Blt image to back buffer
	DispBBuffer.GetBitmap(&bmp);
	DispBmp.GetBitmap(&bmp2);
/*
	bbDC.StretchBlt(0,0,bmp.bmWidth,bmp.bmHeight,&memDC,
		0,0,bmp2.bmWidth,bmp2.bmHeight,SRCCOPY);
*/	
	UpdateDims();
	bbDC.SelectObject(pen);
	bbDC.SelectObject(GetStockObject(NULL_BRUSH));
	Stuff::Point3D np;
	CPoint oloc,loc;
	
	int i;

	for(i=0;i<tnum;i++)
	{
		oloc=GridToMap(tlist[i]->GetV0());
		bbDC.MoveTo(oloc);
		loc=GridToMap(tlist[i]->GetV1());
		bbDC.LineTo(loc);
		loc=GridToMap(tlist[i]->GetV2());
		bbDC.LineTo(loc);
		bbDC.LineTo(oloc);
	}

	CRect rect;
	
	np.x=cx+rad;
	np.y=0.0f;
	np.z=cy+rad;

	loc=GridToMap(np);

	rect.bottom=loc.y;
	rect.right=loc.x;

	np.x=cx-rad;
	np.y=0.0f;
	np.z=cy-rad;

	loc=GridToMap(np);

	rect.top=loc.y;
	rect.left=loc.x;

	bbDC.Ellipse(&rect);

	//Display the backbuffer
	CRect crct;
	GetClientRect(&crct);
	DispBBuffer.GetBitmap(&bmp);
	pDC->BitBlt(0,0,crct.Width(),crct.Height(),&bbDC,0,0,SRCCOPY);
	
	bbDC.DeleteDC();
	memDC.DeleteDC();
	pen.DeleteObject();
	ReleaseDC(pDC);
}


void CFinalBitmapWnd::DrawGrid(ToDrawTriangle *tlist,int tnum)
{
    CDC *pDC,memDC,bbDC;
	BITMAP bmp,bmp2;
	DispBmp.GetBitmap(&bmp);
	
	pDC=GetDC();
	
    memDC.CreateCompatibleDC(pDC);
    memDC.SelectObject(&DispBmp);
    bbDC.CreateCompatibleDC(pDC);
    bbDC.SelectObject(&DispBBuffer);
	
	//Blt image to back buffer
	DispBBuffer.GetBitmap(&bmp);
	DispBmp.GetBitmap(&bmp2);
	bbDC.StretchBlt(0,0,bmp.bmWidth,bmp.bmHeight,&memDC,
		0,0,bmp2.bmWidth,bmp2.bmHeight,SRCCOPY);
	
	UpdateDims();
	bbDC.SelectObject(WhitePen);
	
	Stuff::Point3D np;
	CPoint oloc,loc;
	
	int i;

	for(i=0;i<tnum;i++)
	{
		oloc=GridToMap(tlist[i].GetV0());
		bbDC.MoveTo(oloc);
		loc=GridToMap(tlist[i].GetV1());
		bbDC.LineTo(loc);
		loc=GridToMap(tlist[i].GetV2());
		bbDC.LineTo(loc);
		bbDC.LineTo(oloc);
	}
	
	//Display the backbuffer
	CRect crct;
	GetClientRect(&crct);
	DispBBuffer.GetBitmap(&bmp);
	pDC->BitBlt(0,0,crct.Width(),crct.Height(),&bbDC,0,0,SRCCOPY);
	
	bbDC.DeleteDC();
	memDC.DeleteDC();
	
	ReleaseDC(pDC);
}

