#import "JubChatClient.h"

@implementation JubChatClient
@synthesize connection = _connection;
@synthesize roster = _roster;
@synthesize contactManager = _contactManager;
@synthesize presence = _presence;
@synthesize ui = _ui;

- initWithConfig: (JubConfig*)config
{
	self = [super init];

	@try {
		_chatMap = [[OFMutableDictionary alloc] init];

		_connection = [XMPPConnection new];
		_connection.username = config.username;
		_connection.domain = config.domain;
		_connection.server = config.server;
		_connection.password = config.password;
		[_connection addDelegate: self];

		_roster = [[XMPPRoster alloc] initWithConnection: _connection];
		[_roster addDelegate: self];

		_contactManager = [[XMPPContactManager alloc]
		    initWithConnection: _connection
				roster: _roster];

		_streamManagement = [[XMPPStreamManagement alloc]
		    initWithConnection: _connection];

		[_connection asyncConnectAndHandle];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_roster release];
	[_contactManager release];
	[_streamManagement release];
	[_connection release];
	[_presence release];
	[_chatMap release];

	[super dealloc];
}

- (id<JubChatUI>)chatForContact: (XMPPContact*)contact
{
	OFAutoreleasePool *pool = [OFAutoreleasePool new];
	OFString *bareJID = [contact.rosterItem.JID bareJID];

	id<JubChatUI> chat = [_chatMap objectForKey: bareJID];
	if (chat == nil) {
		OFString * title =
		    [@"Chat with " stringByAppendingString: bareJID];

		chat = [[[[_ui chatUIClass] alloc]
		    initWithTitle: title
		       closeBlock: ^{
				[_chatMap removeObjectForKey: bareJID];
			}
			sendBlock: ^(OFString *text) {
				XMPPMessage *msg =
				    [XMPPMessage messageWithType: @"chat"];
				msg.body = text;
				[contact sendMessage: msg
					  connection: _connection];
			}
		] autorelease];

		[_chatMap setObject: chat
			     forKey: bareJID];
	}

	[pool release];

	return chat;
}

- (void)connection: (XMPPConnection*)connection
     wasBoundToJID: (XMPPJID*)jid
{
	of_log(@"Bound to JID: %@", [jid fullJID]);

	[_roster requestRoster];
}

-   (void)connection: (XMPPConnection*)connection
  didReceivePresence: (XMPPPresence*)presence
{
	if ([presence.from isEqual: connection.JID]) {
		[_ui         client: self
		  didChangePresence: presence];
		OF_SETTER(_presence, presence, YES, 0);
	}
}

- (void)rosterWasReceived: (XMPPRoster*)roster
{
	XMPPPresence *pres = [XMPPPresence presence];
	[pres setStatus: @"Hello from JubJub"];
	[_connection sendStanza: pres];
}
@end
