// COPYRIGHT (C) 1990-1999.  All Rights Reserved. - TIMER2.CPP
// Zinc Software Incorporated.  Pleasant Grove, Utah  USA
// May be freely copied, used and distributed.

// This example derives a class from ZafUTime and then increments the 
// time by creating a ZafTimer to notify it every second.  When the notified
// the derived UTime increments one second.	 To prevent the need of having
// to have a timer for each object the derived UTime checks to see if the
// needed timer already exists.  If the timer exits then it only adds itself
// to the timers notify list.  When being destroyed it also checks the timer
// to see if other objects are added to the timer.  If no other objects are
// added to the timer it deletes the timer.

#include <zaf.hpp>
#include "timer2.hpp"

// ----- ANIMATED TIME OBJECT -----------------------------------------------

AnimatedUTime::AnimatedUTime(int left, int top, int width) :
	ZafUTime(left, top, width)
{
	SetAutoClear(false);
	SetViewOnly(true);
	SetNoncurrent(true);

	// Get a pointer to the Timer device if it exists and cast it from a 
	// ZafDevice pointer to a ZafTimer. The GetObject() function returns
	// a pointer of type ZafDevice if it exists, otherwise it returns null.
	// The DynamicPtrCast() function will cast the pointer to of type ZafTimer.
	ZafTimer *timerDevice = 
		DynamicPtrCast(zafEventManager->GetObject(ZAF_ITEXT("ANIMATED_TIMER")),
		ZafTimer);

	// If the timer does not exist.
	if (!timerDevice)
	{
		// Create a timer in the on state, set it to go off every second.
		timerDevice = new ZafTimer(D_ON, 1000);
		
		// Set the timer's stringID to make it possible to get a pointer latter.
		timerDevice->SetStringID(ZAF_ITEXT("ANIMATED_TIMER"));

		// Add the timer to the eventManger so it will be pulled.
		eventManager->Add(timerDevice);

		// Set the message the timer should send.
		timerDevice->SetNotifyMessage(ONE_SECOND);
	}

	// Add the TimeDate object to the timer list.
	timerDevice->Add(this);
}


AnimatedUTime::~AnimatedUTime()
{
	// Get a pointer to the Timer device and cast it from a ZafDevice 
	// pointer to a ZafTimer.
	ZafTimer *timer = 
		DynamicPtrCast(zafEventManager->GetObject(ZAF_ITEXT("ANIMATED_TIMER")),
		ZafTimer);

	// If the timer has more than one object added to it only subtract 
	// the object from the list. 
	if (timer->NotifyCount() > 1)
	{
		*timer
			- this;
	}
	// If this is the only object added to the timer subtract the 
	// timer from the event manager and delete the timer.
	else
	{
		*zafEventManager
			- timer;
		delete timer;
   }
}

		
ZafEventType AnimatedUTime::Event(const ZafEventStruct &event)
{
	ZafEventType ccode = event.type;
	switch(ccode)
	{
	case ONE_SECOND:
		// Calling GetSystemTime() gets the system utime data.
		utimeData->GetSystemTime();
		break;
	default:
		ccode = ZafUTime::Event(event);
		break;
	}
	return(ccode);
}

// ----- Main() -------------------------------------------------------------

int ZafApplication::Main(void)
{
	// Ensure main() is linked properly.
	LinkMain();
	
	// Create two windows and add an animated time object to each.
	ZafWindow *window = new ZafWindow(20, 5, 33, 3);
	window->AddGenericObjects(new ZafStringData("Animated UTime Window 1"));
	window->Add(new AnimatedUTime(4, 1, 24));

	ZafWindow *window1 = new ZafWindow(25, 7, 33, 3);
	window1->AddGenericObjects(new ZafStringData("Animated UTime Window 2"));
	window1->Add(new AnimatedUTime(4, 1, 24));

	// Add the windows to the window manager.
	zafWindowManager->Add(window);
	zafWindowManager->Add(window1);

	// Get the user input.
	Control();

	// Return success.
	return (0);
}

