#pragma option w32
#jumptomain NONE
#codesize

#define _WINGDI_ TRUE
#define _WINBASE_ TRUE
#include "windows.h--"
#include "rsrc.rc"

#define MAX_SMILIES	30

dword SmileyArray[MAX_SMILIES];  //Finite array size when compilied
                                 //As an alternate, one could use
                                 //the Linked List object instead
                                 //to create a dynamic array that
                                 //can grow at run time, but for
                                 //simplicity this will surfice for
                                 //the graphical object example.

dword hInst;
dword hBackDC,hBackBmp;

#include "rand.h--"
#include "csprite.h--"
#include "drawproc.h--"

void main()
WNDCLASSEX wc;
MSG msg;
dword hwnd;
{
	hInst=GetModuleHandleA(0);
	InitRand32();
	wc.cbSize=sizeof(WNDCLASSEX);
	wc.style=CS_HREDRAW|CS_VREDRAW;
	wc.lpfnWndProc=#WndProc;
	wc.lpszMenuName=wc.cbWndExtra=wc.cbClsExtra=0;
	wc.hInstance=hInst;
	wc.hbrBackground=COLOR_WINDOW;
	wc.lpszClassName="smilies";
	wc.hIcon=LoadIconA(hInst,BIGICON);
	wc.hIconSm=LoadIconA(hInst,SMALLICON);
	wc.hCursor=LoadCursorA(0,IDC_ARROW);
	RegisterClassExA(#wc);
	hwnd=CreateWindowExA(WS_EX_OVERLAPPEDWINDOW,"smilies","smilies",
                      WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,400,300,0,0,hInst,0);
	ShowWindow(hwnd,SW_SHOW);
	UpdateWindow(hwnd);
	WHILE(GetMessageA(#msg,0,0,0)){
		TranslateMessage(#msg);
		DispatchMessageA(#msg);
	}
	ExitProcess(msg.wParam);
}

dword WndProc(dword hWnd,msg,wPar,lPar)
{
dword	hDC;
PAINTSTRUCT ps;
RECT TempRect;
	switch(msg){
		CASE WM_CREATE:
// Create needed DC's for graphical useage
			hDC=GetDC(hWnd);
			hBackDC=CreateCompatibleDC(EAX);
			hBackBmp=CreateCompatibleBitmap(hDC,400,300);
			SelectObject(hBackDC,hBackBmp);
// Do OOP initializations
			Initialization(hWnd);
			SetTimer(hWnd,555,70,NULL);
			ReleaseDC(hWnd,hDC);
			break;
		CASE WM_TIMER:
			IF(wPar==555)InvalidateRect(hWnd,NULL,FALSE);
			break;
		case WM_PAINT:
			DrawProc();
			hDC=BeginPaint(hWnd,#ps);
			BitBlt(hDC,0,0,400,300,hBackDC,0,0,SRCCOPY);
			EndPaint(hWnd,#ps);
			BREAK;
   case WM_DESTROY:
// Destroy any created DC's before exiting...
			KillTimer(hWnd,555);
			DeleteDC(hBackDC);
			DeleteObject(hBackBmp);
// Clean up OOP stuff
			Cleanup();
      PostQuitMessage(0);
      EAX=0;
      BREAK;
   default:
      DefWindowProcA(hWnd,msg,wPar,lPar);
  }
}

void Initialization(dword hWnd)
{
RECT TempRect;
	GetClientRect(hWnd,#TempRect);
/* This loop will crate MAX_SMILES unique objects of CSprite Objects..
 and then initialize each with the Instance handle, a drawing DC, and
 the drawing rect to draw within, and lastly a random speed is set to each
 sprite object.*/
	FOR(EBX=0;EBX<MAX_SMILIES;EBX++){
		SmileyArray[4*EBX]=newobject(sizeof(CSprite));
		EDI=EAX;
		EDI.CSprite.Init();
		LoadBitmap(hInst,Rand32(3)+200);
		EDI.CSprite.setBitmap(EAX);
		EDI.CSprite.setDrawingDC(hBackDC);
		EDI.CSprite.setScreenSize(TempRect.right,TempRect.bottom);
		EDI.CSprite.setSpeed(Rand32(25)+5);
	}
}

void Cleanup()
{
	FOR(EBX=0;EBX<MAX_SMILIES;EBX++)destroy(SmileyArray[4*EBX]);    // DESTROY IT!
}
