/***********************************************************************
 * TestAudio.C
 *  
 *    Application to test the gif library
 *
 *
 * Toby Opferman Copyright (c) 2002
 *
 ***********************************************************************/
 
 
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <gif.h>
#include <gdi.h>
 
#define TGIF_CLASS_NAME "TESTGIF"
#define TGIF_TITLE      "Test Gif Display"
#define SIZE_X 500
#define SIZE_Y 500


typedef struct _IMAGE_LIST
{
	char *pszImageName;

} IMAGE_LIST, *PIMAGE_LIST;

char *g_ImageList[] =
{ 
	"..\\..\\..\\res\\pictures\\AmeliaStand.gif",
	"..\\..\\..\\res\\pictures\\ameliawalk.gif",
	"..\\..\\..\\res\\pictures\\ameliawalk2.gif",
	"..\\..\\..\\res\\pictures\\ameliawalk3.gif",
	"..\\..\\..\\res\\pictures\\ameliawalk4.gif",
	"..\\..\\..\\res\\pictures\\ameliafw.gif",
	"..\\..\\..\\res\\pictures\\ameliafw2.gif",
	"..\\..\\..\\res\\pictures\\ameliafw3.gif",
	"..\\..\\..\\res\\pictures\\ameliafw4.gif",
	"..\\..\\..\\res\\pictures\\ameliaright1.gif",
	"..\\..\\..\\res\\pictures\\ameliaright2.gif",
	"..\\..\\..\\res\\pictures\\ameliaright3.gif",
	"..\\..\\..\\res\\pictures\\ameliaright4.gif",
	"..\\..\\..\\res\\pictures\\amelialeft1.gif",
	"..\\..\\..\\res\\pictures\\amelialeft2.gif",
	"..\\..\\..\\res\\pictures\\amelialeft3.gif",
	"..\\..\\..\\res\\pictures\\amelialeft4.gif",
	NULL
};


typedef struct _IMAGE_INFO
{
	UINT Width;
	UINT Height;
	HGDI  hGDI;

} IMAGE_INFO, *PIMAGE_INFO;

typedef struct _IMAGES
{
	BOOL TimerIsOn;
	UINT uiCurrentImage;
	UINT uiImages;
	UINT uiImageStart;
	UINT uiImageEnd;
	IMAGE_INFO ImageInfo[100];
	HGDI hOffscreenSurface;
	int X, Y;
	int MoveX, MoveY;

} IMAGES, *PIMAGES;



 BOOL WINAPI GifTest_RegisterClass(HINSTANCE hInstance);
 LRESULT CALLBACK GifTest_WindowProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
 HWND WINAPI GifTest_CreateWindow(HINSTANCE hInstance, UINT Width, UINT Height, PIMAGES pImages);
 int WINAPI GifTest_MessageLoop(HINSTANCE hInstance, HWND hWnd);
void GifTest_CreateHandler(HWND hWnd, PIMAGES pImages);
 void GifTest_PaintScreen(HWND hWnd);
 void GifTest_PaintSprite(PIMAGES Images);
 void CALLBACK GifTest_Animate(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);

 /***********************************************************************
  * main
  *
  *    Entry Point For console Applications
  *
  * Parameters
  *     Standard console Entry Point Parameters
  * 
  * Return Value
  *     Result of the program
  *
  ***********************************************************************/
 int __cdecl main(int argc, char **argv)
 {
	 HGIF hGif;
	 char *ScreenBuffer;
	 HINSTANCE hInstance = GetModuleHandle(NULL);	 
	 IMAGES Images = {0};
	 HWND hWnd;
	 UINT Index;

	 for(Index = 0; g_ImageList[Index]; Index++)
	 {
		 hGif = Gif_Open(g_ImageList[Index]);

		 Images.ImageInfo[Index].Width  = Gif_GetImageWidth(hGif, 0);
         Images.ImageInfo[Index].Height = Gif_GetImageHeight(hGif, 0);
         Images.ImageInfo[Index].hGDI   = GDI_Init(NULL, Images.ImageInfo[Index].Width, Images.ImageInfo[Index].Height);

   		 ScreenBuffer = GDI_BeginPaint(Images.ImageInfo[Index].hGDI);
		 Gif_GetImage32bpp(hGif, 0, ScreenBuffer);
		 GDI_EndPaint(Images.ImageInfo[Index].hGDI);
		 Gif_Close(hGif);
	 }

	 Images.hOffscreenSurface   = GDI_Init(NULL, SIZE_X, SIZE_Y);

     GifTest_PaintSprite(&Images);

	 Images.uiImages = Index;

	 GifTest_RegisterClass(hInstance);
	 hWnd = GifTest_CreateWindow(hInstance, SIZE_X, SIZE_Y, &Images);
     InvalidateRect(hWnd, NULL, FALSE);
     GifTest_MessageLoop(hInstance, hWnd);
     
     return 0;
 }




                   
 /***********************************************************************
  * GifTest_RegisterClass
  *  
  *    Registers the Test Window Proc Class
  *
  * Parameters
  *     instance Handle
  * 
  * Return Value
  *     TRUE on Success, FALSE on Failure
  *
  ***********************************************************************/
 BOOL WINAPI GifTest_RegisterClass(HINSTANCE hInstance)
 {
     WNDCLASSEX WndClassEx = {0};

     WndClassEx.cbSize        = sizeof(WndClassEx);
     WndClassEx.style         = 0;
     WndClassEx.lpfnWndProc   = GifTest_WindowProc;
     WndClassEx.cbWndExtra    = 0;
     WndClassEx.hInstance     = hInstance;
     WndClassEx.hIcon         = NULL;
     WndClassEx.hCursor       = NULL;
     WndClassEx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
     WndClassEx.lpszMenuName  = "";
     WndClassEx.lpszClassName = TGIF_CLASS_NAME;
     WndClassEx.hIconSm       = NULL;
     
     return RegisterClassEx(&WndClassEx);
 }



 /***********************************************************************
  * GifTest_CreateWindow
  *  
  *    Creates The Test Window
  *
  * Parameters
  *     instance Handle
  * 
  * Return Value
  *     Window Handle on Success, NULL on Failure
  *
  ***********************************************************************/
 HWND WINAPI GifTest_CreateWindow(HINSTANCE hInstance, UINT Width, UINT Height, PIMAGES pImages)
 {
     HWND hWnd = NULL;

     if(!FindWindow(TGIF_CLASS_NAME, NULL))
     {
        if(hWnd = CreateWindowEx(0, TGIF_CLASS_NAME, TGIF_TITLE, WS_SYSMENU | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_OVERLAPPED, 0,  0, Width, Height, HWND_DESKTOP, NULL,  hInstance, (PVOID)pImages))
        {
            ShowWindow(hWnd, SW_SHOWNORMAL);
            UpdateWindow(hWnd);
        }
     }

     return hWnd;
 }



 /***********************************************************************
  * GifTest_MessageLoop
  *  
  *    Handles Window Messages to be dispatched to the Cubix Window
  *
  * Parameters
  *     instance Handle, Window Handle
  * 
  * Return Value
  *     Exit Value
  *
  ***********************************************************************/
 int WINAPI GifTest_MessageLoop(HINSTANCE hInstance, HWND hWnd)
 {
     MSG Msg = {0};
     BOOL bMessageLoop = TRUE;

     while(bMessageLoop)
     {
         if(GetMessage(&Msg, 0, 0, 0))
         {
             TranslateMessage(&Msg);
             DispatchMessage(&Msg);
        }
        else
        {
            bMessageLoop = FALSE;
        }
     }

     return Msg.wParam;
 }



 

 /***********************************************************************
  * GifTest_WindowProc
  *  
  *    Handles Window Messages Send to the window
  *
  * Parameters
  *     Standard Windows Proc Handler
  * 
  * Return Value
  *     Exit Value
  *
  ***********************************************************************/
 LRESULT CALLBACK GifTest_WindowProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
 {
     LRESULT dwRetValue = 0;
	 PIMAGES pImages = (PIMAGES)GetWindowLong(hWnd, GWL_USERDATA);

     switch(wMsg)
     {
         case WM_CREATE:
              GifTest_CreateHandler(hWnd, (PIMAGES)((LPCREATESTRUCT)lParam)->lpCreateParams);
              break;

		 case WM_KEYDOWN:
			  if(pImages->TimerIsOn == FALSE)
			  {
				  switch(LOWORD(wParam))
				  {
					  case VK_UP:
						   pImages->MoveX = 0;
						   pImages->MoveY = -4;
						   pImages->uiImageStart = 1;
						   pImages->uiImageEnd   = 4;
						   break;
					  case VK_DOWN:
						   pImages->MoveX = 0;
						   pImages->MoveY = 4;
						   pImages->uiImageStart = 5;
						   pImages->uiImageEnd   = 8;
						   break;
					  case VK_LEFT:
						   pImages->MoveX = -4;
						   pImages->MoveY = 0;
						   pImages->uiImageStart = 13;
						   pImages->uiImageEnd   = 16;
						   break;
					  case VK_RIGHT:
						   pImages->MoveX = 4;
						   pImages->MoveY = 0;
						   pImages->uiImageStart = 9;
						   pImages->uiImageEnd   = 12;
						   break;
				  }
				  pImages->uiCurrentImage = pImages->uiImageStart - 1;
				  pImages->TimerIsOn = TRUE;
				  SetTimer(hWnd, 1, 1000/30, (TIMERPROC)GifTest_Animate);
			  }
			  break;

		 case WM_KEYUP:
			  pImages->TimerIsOn = FALSE;
			  break;

         case WM_PAINT:
              GifTest_PaintScreen(hWnd);
              break;

         case WM_CLOSE:
         case WM_DESTROY:
              ShowCursor(TRUE);
              PostQuitMessage(0);
              break;

         default:
              dwRetValue = DefWindowProc(hWnd, wMsg, wParam, lParam);
     }

     return dwRetValue;
 }

 /***********************************************************************
  * GifTest_PaintScreen
  *  
  *    
  *
  * Parameters
  *     
  * 
  * Return Value
  *     None
  *
  ***********************************************************************/
void CALLBACK GifTest_Animate(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
    PIMAGES pImages = (PIMAGES)GetWindowLong(hWnd, GWL_USERDATA);
	
	pImages->uiCurrentImage++;
	
	pImages->X +=  pImages->MoveX;
	pImages->Y +=  pImages->MoveY;
	
	KillTimer(hWnd, 1);

	if(pImages->X < 0)
	{
		pImages->X = 0;
	}

	if(pImages->X > 600)
	{
		pImages->X = 600;
	}

	if(pImages->Y < 0)
	{
		pImages->Y = 0;
	}

	if(pImages->Y > 410)
	{
		pImages->Y = 410;
	}


	if(pImages->uiCurrentImage > pImages->uiImageEnd)
	{
		pImages->uiCurrentImage = pImages->uiImageStart;
	}

	if(pImages->TimerIsOn)
	{
		SetTimer(hWnd, 1, 1000/30, (TIMERPROC)GifTest_Animate);
	}
	else
	{
		pImages->uiCurrentImage = 0;
	}

	GifTest_PaintSprite(pImages);

    InvalidateRect(hWnd, NULL, FALSE);	  
}

 /***********************************************************************
  * GifTest_PaintSprite
  *  
  *    
  *
  * Parameters
  *     
  * 
  * Return Value
  *     None
  *
  ***********************************************************************/
void GifTest_PaintSprite(PIMAGES Images)
{
	HDC ImageDc;
	HDC ImageDc2;
    UINT Index = Images->uiCurrentImage;
	DWORD *pScreen;
	DWORD *pImage;
	UINT IndexX, IndexY;
	DWORD SkipColor;

	GDI_ClearVideoBuffer(Images->hOffscreenSurface);
    pScreen = (DWORD *)GDI_BeginPaint(Images->hOffscreenSurface);
	pImage = (DWORD *)GDI_BeginPaint(Images->ImageInfo[Index].hGDI);

	SkipColor = *pImage;
	for(IndexY = 0; IndexY < Images->ImageInfo[Index].Height; IndexY++)
	{
		for(IndexX = 0; IndexX < Images->ImageInfo[Index].Width; IndexX++, pImage++)
		{
			if(SkipColor != *pImage)
			{
				pScreen[((Images->X + IndexX)) + ((Images->Y + IndexY)*SIZE_X)] = *pImage;
			}
		}
	}

    //BitBlt(ImageDc, Images->X, Images->Y, Images->ImageInfo[Index].Width, Images->ImageInfo[Index].Height, ImageDc2, 0, 0, SRCCOPY);

	GDI_EndPaint(Images->ImageInfo[Index].hGDI);
    GDI_EndPaint(Images->hOffscreenSurface);

}

 /***********************************************************************
  * GifTest_PaintScreen
  *  
  *    
  *
  * Parameters
  *     
  * 
  * Return Value
  *     None
  *
  ***********************************************************************/
 void GifTest_PaintScreen(HWND hWnd)
 {
     HDC hDC;
     PAINTSTRUCT ps;
     RECT Rect;
     PIMAGES pImages = (PIMAGES)GetWindowLong(hWnd, GWL_USERDATA);
     HDC ImageDc;

	 
	 ImageDc = GDI_GetDC(pImages->hOffscreenSurface);

     hDC = BeginPaint(hWnd, &ps);

     GetClientRect(hWnd, &Rect);

     BitBlt(hDC, 0, 0, SIZE_X, SIZE_Y, ImageDc, 0, 0, SRCCOPY);

     EndPaint(hWnd, &ps);

	 GDI_ReleaseDC(pImages->hOffscreenSurface);
 }





 /***********************************************************************
  * GifTest_CreateHandler
  *  
  *    Handles processing virtual keys
  *
  * Parameters
  *     Window Handle, Virtual Key
  * 
  * Return Value
  *     None
  *
  ***********************************************************************/
void GifTest_CreateHandler(HWND hWnd, PIMAGES pImage)
{
   SetWindowLong(hWnd, GWL_USERDATA, (ULONG)pImage);
}




