/*
   Project: Adun

   Copyright (C) 2005 Michael Johnston & Jordi Villa-Freixa

   Author: Michael Johnston

   This application is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This application is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include "AdunKernel/AdunTimer.h"

@implementation AdTimer

- (id) initWithEnvironment: (id) object observe: (BOOL) value
{
	if(self = [super initWithEnvironment: object observe: value])
		scheduledEvents = [[NSMutableDictionary dictionaryWithCapacity:1] retain];
	return self;
}

- (id) initWithEnvironment: (id) object
{
	return [self initWithEnvironment: object observe: YES];
}

- (id) init
{
	[self initWithEnvironment: nil];
}

- (void) dealloc
{
	[scheduledEvents release];
}

- (void) sendMessage: (SEL) message toObject: (id) obj interval: (int) interval name: (NSString*) name
{
	NSMutableDictionary* scheduledEvent;

	scheduledEvent = [NSMutableDictionary dictionaryWithObjects: 
					[NSArray arrayWithObjects: 
						NSStringFromSelector(message), 
						obj, 
						[NSNumber numberWithInt: interval], 
						[NSNumber numberWithInt: 0],
						nil]
				forKeys: 
					[NSArray arrayWithObjects: 
						@"Message", 
						@"Object", 
						@"Interval", 
						@"Counter",
						nil]];

	[scheduledEvents setObject: scheduledEvent forKey: name];
}

- (void) removeMessageWithName: (NSString*) name
{
	[scheduledEvents removeObjectForKey: name];
}

- (void) increment
{
	NSEnumerator* eventEnumerator;
	id scheduledEvent;
	int counter;
	NSString* selectorString;

	//we have to protect against the case where the message emptyPool
	eventEnumerator = [[scheduledEvents objectEnumerator] retain];
	while(scheduledEvent = [eventEnumerator nextObject])
	{
		counter = [[scheduledEvent valueForKey: @"Counter"] intValue];
		counter++;
		if([[scheduledEvent valueForKey: @"Interval"] intValue] == counter)
		{
			selectorString = [scheduledEvent valueForKey: @"Message"];
			[[scheduledEvent valueForKey: @"Object"] performSelector: NSSelectorFromString(selectorString)];
			[scheduledEvent setObject: [NSNumber numberWithInt: 0] forKey: @"Counter"];
		}
		else
			[scheduledEvent setObject: [NSNumber numberWithInt: counter] forKey: @"Counter"];
	}
	[eventEnumerator release];
}

- (void) resetAll
{
	NSEnumerator* eventEnumerator;
	id scheduledEvent;

	eventEnumerator = [scheduledEvents objectEnumerator];
	while(scheduledEvent = [eventEnumerator nextObject])
		[scheduledEvent setObject: [NSNumber numberWithInt: 0] forKey: @"Counter"]; 
}

- (void) resetCounterForMessageWithName: (NSString*) name
{
	id event;

	event = [scheduledEvents objectForKey: name];
	[event setObject: [NSNumber numberWithInt: 0] forKey: @"Counter"]; 
}

/**************

Coding

***************/

- (id) initWithCoder: (NSCoder*) decoder
{
	self = [super initWithCoder: decoder];
	if([decoder allowsKeyedCoding])
		scheduledEvents = [decoder decodeObjectForKey: @"ScheduledEvents"];
	else
		[NSException raise: NSInvalidArgumentException
			format: @"Object does not support non keyed coding (%@)", [self description]];

	return self;
}

- (void) encodeWithCoder: (NSCoder*) encoder
{
	[super encodeWithCoder: encoder];
	if([encoder allowsKeyedCoding])
		[encoder encodeObject: scheduledEvents forKey: @"ScheduledEvents"];
	else
		[NSException raise: NSInvalidArgumentException
			format: @"Object does not support non keyed coding (%@)", [self description]];
}

@end
