// UB_DTIM.CPP
//
// Copyright (c) 1996-1999 Symbian Ltd.  All rights reserved.
//


#include "ub_std.h"

enum TDeltaTimerPanic
	{
	ECancelNotRunning,
	EQueWhileActive,
	ECAncelNotRunning,
	EBadQueue,
	};

void Panic(TDeltaTimerPanic aPanic)
	{
	User::Panic(_L("CDeltaTimer"),aPanic);
	}

EXPORT_C CDeltaTimer* CDeltaTimer::NewL(TInt aPriority)
//
// C'tor
//
	{
	return CDeltaTimer::NewL(aPriority,KDeltaTimerDefaultGranularity);
	}

EXPORT_C CDeltaTimer* CDeltaTimer::NewL(TInt aPriority,TTimeIntervalMicroSeconds32 aGranularity)
//
// C'tor
//
	{
	CDeltaTimer* cdt=new(ELeave) CDeltaTimer(aPriority,aGranularity);
	TInt r=cdt->iTimer.CreateLocal();
	if (r!=KErrNone)
		{
		delete cdt;
		User::Leave(r);
		}
	CActiveScheduler::Add(cdt);
	return cdt;
	}

EXPORT_C CDeltaTimer::CDeltaTimer(TInt aPriority,TTimeIntervalMicroSeconds32 aGranularity)
//
// Private C'tor
//
	:CActive(aPriority),iQueue(_FOFF(TDeltaTimerEntry,iLink)),iGranularity(aGranularity)
	{
	}

EXPORT_C void CDeltaTimer::Queue(TTimeIntervalMicroSeconds32 aTimeInMicroSeconds,TDeltaTimerEntry& anEntry)
//
// Queue a new timer
//
	{

	TTimeIntervalMicroSeconds32 time=aTimeInMicroSeconds.Int()/iGranularity.Int();

	if (time.Int()==0)
		time=1;

	iQueue.Add(anEntry,time.Int());
	Activate();
	}


void CDeltaTimer::Activate()
//
// Queue a request on the timer.
// The timer runs every tenth of a second and decremented the delta of the head of the queue.
//
	{
	if (IsActive())
		return;
	if (!iQueue.IsEmpty())
		{
		SetActive();
		iTimer.After(iStatus,iGranularity.Int()-1); // -1 to compensate for +1 in kernel!
		}
	}

void CDeltaTimer::RunL()
//
// Call all zero delta callbacks
	{

	iQueue.CountDown();

	TDeltaTimerEntry* ent=iQueue.RemoveFirst();
	while (ent)
		{       
		ent->iCallBack.CallBack();
		ent=iQueue.RemoveFirst();
		}

	Activate();
	}

void CDeltaTimer::DoCancel()
//
// Cancel request.
//
	{
	iTimer.Cancel();
	}

EXPORT_C void CDeltaTimer::Remove(TDeltaTimerEntry& anEntry)
//
// 
//
	{

	iQueue.Remove(anEntry);
	Activate();
	}

CDeltaTimer::~CDeltaTimer()
//
// D'tor
//
	{
	Cancel();
	TDeltaTimerEntry* ent=iQueue.RemoveFirst();
	while (ent)
		{       
		ent=iQueue.RemoveFirst();
		}
	}

