// MainFrm.cpp : implementation of the CMainFrame class
//


#include "stdafx.h"
#include "ex5.h"

#include "MainFrm.h"

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

// The sprite types
enum
{
	SPR_BUG,
	SPR_MOUTH,
	SPR_CHOMPER,
	SPR_PLAYER,
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_WM_KEYDOWN()
	ON_WM_SETCURSOR()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
	mb_Active=TRUE;

	// Frame rate counters
	LastTime        = 0;
	CurTime         = 0;
	FpsTime         = 0;
	DeltaTime       = 0;
	FramesRendered  = 0;
	Fps             = 0;
}

CMainFrame::~CMainFrame()
{
	delete Bug;
	delete Chomper;
	delete Mouth;
	delete Player;
	delete screen;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CFrameWnd::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers

BOOL CMainFrame::InitDirectDraw()
{
	HWND hWnd = AfxGetMainWnd()->m_hWnd;
	screen = new CDXScreen();
	screen->CreateFullScreen(hWnd,640,480,8);
	screen->LoadPalette("BUG.BMP");

	// Load the tiles
	Bug = new CDXTile;
	Bug->Create(screen, "BUG.BMP", 84, 80, 0);

	Mouth   = new CDXTile;
	Mouth->Create(screen, "MOUTH.BMP", 39, 36, 0);

	Chomper = new CDXTile;
	Chomper->Create(screen, "CHOMPER.BMP", 38, 34, 0);

	Player  = new CDXTile;
	Player->Create(screen, "PLAYER.BMP", 38, 36, 0);

	// Set the bitmap transparent color
	Bug->SetColorKey(8);
	Mouth->SetColorKey(8);
	Chomper->SetColorKey(8);
	Player->SetColorKey(8);

	// Seed the random-number generator with current time
	srand((unsigned)time(NULL));

	// Change the default font
	screen->GetBack()->ChangeFont("Comic Sans MS", 0, 18);

	Run();
	return TRUE;
}

BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext) 
{
	CString sClassName = ::AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);
	if (!Create(sClassName, NULL, dwDefaultStyle, rectDefault,
                pParentWnd, NULL, 0L, pContext))
	  {
		return FALSE;
	  }
	
	return TRUE;
}

void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	switch (nChar)
	{
		case VK_ESCAPE:
			{
				screen->GetBack()->ReleaseDC();
				PostMessage(WM_CLOSE, 0, 0);
				mb_Active=FALSE;
				break;
			}
	}
	CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}


BOOL CMainFrame::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	SetCursor(NULL);

	return TRUE;
}

void CMainFrame::UpdateSprites()
{
	CDXSprite* Node;
//	CDXSprite* Save;

	// Loop the list and update the sprites
	for(Node = Sprites.GetFirst(); Node != NULL; Node = Sprites.GetNext(Node))
	{
//		Save = Node->m_Next;

		Node->SetPosX(Node->GetPosX() + Node->GetVelX());
		Node->SetPosY(Node->GetPosY() + Node->GetVelY());

		if(Node->GetPosX() < 0)
		{
			Node->SetVelX(Node->GetVelX() - (2 * Node->GetVelX()));
            Node->SetPosX(1);
		}
		if(Node->GetPosX() > (640 - Node->GetTile()->GetBlockWidth()))
		{
			Node->SetVelX(Node->GetVelX() - (2 * Node->GetVelX()));
			Node->SetPosX(639 - Node->GetTile()->GetBlockWidth());
		}
		if(Node->GetPosY() < 0)
		{
			Node->SetVelY(Node->GetVelY() - (2 * Node->GetVelY()));
			Node->SetPosY(1);
		}
		if(Node->GetPosY() > (480 - Node->GetTile()->GetBlockHeight()))
		{
			Node->SetVelY(Node->GetVelY() - (2 * Node->GetVelY()));
			Node->SetPosY(479 - Node->GetTile()->GetBlockHeight());
		}
	}
}

void CMainFrame::Run()
{
	MSG msg;

while(mb_Active)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))	
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			if(GetAsyncKeyState(VK_INSERT)) 
			{
				int Type = rand()%3;
				int PosX = rand()%556;
				int PosY = rand()%400;
				int VelX = rand()%3;
				int VelY = rand()%3;

				switch(Type)
				{
					case SPR_BUG:
						{
							CDXSprite *s;
							s = new CDXSprite();
							s->Create(Bug);
							s->SetPosX(PosX);
							s->SetPosY(PosY);
							s->SetVelX(VelX);
							s->SetVelY(VelY);
							Sprites.AddSprite(s);
							//Bug,Type,PosX,PosY,VelX,VelY,0,0,0);
						}
					case SPR_MOUTH: //Sprites.AddSprite(Mouth,Type,PosX,PosY,-VelX,VelY,0,0,0);
						{
							CDXSprite *s;
							s = new CDXSprite();
							s->Create(Mouth);
							s->SetPosX(PosX);
							s->SetPosY(PosY);
							s->SetVelX(-VelX);
							s->SetVelY(VelY);
							Sprites.AddSprite(s);
						}
					case SPR_CHOMPER: //Sprites.AddSprite(Chomper,Type,PosX,PosY,VelX,-VelY,0,0,0);
						{
							CDXSprite *s;
							s = new CDXSprite();
							s->Create(Chomper);
							s->SetPosX(PosX);
							s->SetPosY(PosY);
							s->SetVelX(VelX);
							s->SetVelY(-VelY);
							Sprites.AddSprite(s);
						}
					case SPR_PLAYER: //Sprites.AddSprite(Player,Type,PosX,PosY,-VelX,-VelY,0,0,0);
						{
							CDXSprite *s;
							s = new CDXSprite();
							s->Create(Player);
							s->SetPosX(PosX);
							s->SetPosY(PosY);
							s->SetVelX(-VelX);
							s->SetVelY(-VelY);
							Sprites.AddSprite(s);
						}
				}

			}
			if(GetAsyncKeyState(VK_DELETE)) 
				Sprites.DelSprite(Sprites.GetFirst());
			
						// Loop the sprite list and update the sprites
			UpdateSprites();

			// Clear the back buffer
			screen->Fill(0);

			// Draw all the sprites in the list
			Sprites.Draw(screen->GetBack() , 0 , 0 , CDXBLT_TRANS );

			// Frame rate calculations
			CurTime   = timeGetTime();
			DeltaTime = CurTime - LastTime;
			LastTime  = CurTime;
			FpsTime  += DeltaTime;

			FramesRendered++;

			if (FpsTime > 1000)
			{
				Fps = FramesRendered;
				FramesRendered  = 0;
				FpsTime = 0;
			}

			char str[12];
			sprintf(str, "FPS: %d", Fps);

			// Print the frame rate to the screen
			screen->GetBack()->GetDC();
			screen->GetBack()->SetFont();
			screen->GetBack()->TextXY(5, 5, 255, str);
			screen->GetBack()->TextXY(5, 20, 255, "INSERT - ADD SPRITE");
			screen->GetBack()->TextXY(5, 35, 255, "DELETE - DEL SPRITE");
			screen->GetBack()->ReleaseDC();

			screen->Flip();  // Then display it
		}
	}	
}


void CMainFrame::OnTimer(UINT nIDEvent) 
{
	CFrameWnd::OnTimer(nIDEvent);
}
