#include "animator.h"

static char szClass1[32];
static char szClass2[32];

#ifdef __cplusplus
extern "C" {
#endif

HICON NEAR PASCAL       GetNextIcon (short);
VOID NEAR PASCAL        DrawIconic (HWND, HICON);

#ifdef __cplusplus
}
#endif

//////////////////////////////////////////////////////////////////////////
// TimerCallback - this is the function called by the timer which fires
// off every five milleseconds (or close to that).  It is not exact since
// Windows is message driven.  It steps through the animStruct and
// figures out whether or not it is worthy of animation, and if it is,
// and the user has chosen "Go!", then it decrements a time counter.
// When this time counter has reached 0 or less, we re-initialize the
// counter and change the icon.  This way, all of the animations currently
// animating can use one timer.
//////////////////////////////////////////////////////////////////////////

VOID _export CALLBACK TimerCallback (HWND hWnd, UINT uMsg, 
	UINT uIDEvent, DWORD dwTime)
{
	short i;
	
	// For all eight possible animation sessions...
	for (i=0; _lPageFlags && i<MAXANIMATIONS ; i++)
	{
		if (!IsWindow(HWNDANIM(i)) || !ISANIMATING(i) || !HWNDTARGET(i)) 
		{
			continue;
		}
		// If the countdown is at 0...display the next icon:
		if (!COUNTDOWN(i))
		{
			HICON hIcon = GetNextIcon(i);

			SetClassWord (HWNDTARGET(i), GCW_HICON, hIcon);
			InvalidateAll (HWNDTARGET(i),hIcon);
			SET_COUNTDOWN (i, TIMEINT(i)-(TIMEINT(i)%MINTIME));
		}
		// Otherwise, decrement the countdown by MINTIME amount.
		else
		{
			SET_COUNTDOWN (i, COUNTDOWN(i)-MINTIME);
		}
	}
}



//////////////////////////////////////////////////////////////////////////
// GetNextIcon() - shifts through the list of icons.
//////////////////////////////////////////////////////////////////////////

HICON NEAR PASCAL GetNextIcon(short i)
{

	if (HICONS(i)[INDEX(i)+1] == (HICON)NULL)
	{
		SET_INDEX (i, 0);
	}
	else
	{
		SET_INDEX (i, INDEX(i)+1);
	}
	return HICONS(i)[INDEX(i)] ;
}



//////////////////////////////////////////////////////////////////////////
// InvalidateAll() - Enumerates the sibling instances of a module that
// is loaded, making all of the instances invalidate themselves.
//////////////////////////////////////////////////////////////////////////

VOID WINAPI InvalidateAll (HWND hWnd, HICON hIcon)
{
	HWND hWndNext;
			  
	if (!IsWindow(hWnd)) return;

	GetClassName (hWnd, (LPSTR)szClass1, sizeof(szClass1));

	for (hWndNext = GetWindow((HWND)hWnd,GW_HWNDFIRST); // was GetWindow(hWnd...
		 hWndNext;     
		 hWndNext = GetWindow(hWndNext, GW_HWNDNEXT))
	{
		GetClassName (hWndNext,(LPSTR)szClass2,sizeof(szClass2));

		if (lstrcmp ((LPSTR)szClass1, (LPSTR)szClass2) == 0)
		{
			DrawIconic(hWndNext, hIcon);
		}
	}
}


//////////////////////////////////////////////////////////////////////////
// DrawIconic() - If iconic, it goes a head and tells the minimized 
// window to redraw its non-client.
//////////////////////////////////////////////////////////////////////////

VOID NEAR PASCAL DrawIconic (HWND hWnd, HICON hIcon)
{
	
	if (IsIconic(hWnd))
	{
		RedrawWindow (hWnd, (LPRECT)NULL, (HRGN)NULL,
			RDW_ERASE|RDW_FRAME|RDW_INTERNALPAINT|RDW_INVALIDATE);
	}
}
