(function()
{
	Common.Object.create('Typical.Chat.Connector', {

		client 	: null,
		
		userKey : null,
		
		_isConnected  : null,
		
		onConnect : null,

		Connector : function()
		{
			this.isConnected = false;
			
			this.onConnect = new Common.Dispatcher();
			
			this.client = new APE.Client();

			this.client.addEvent('load', this._onLoad.bind(this));
			this.client.addEvent('ready', this._onReady.bind(this));
		},
		
		connect : function(userKey)
		{
			this.userKey = userKey;
			
			var domain = document.domain.split('www.').pop();
			
			this.client.load({
								 identifier : 'chat',
								 domain : domain,
								 server	: domain + ':6969'
							 });
		},
		
		_onLoad : function()
		{
			this.client.core.start({ userKey : this.userKey });
		},

		_onReady : function()
		{
			this._isConnected = true;
			
			this.onConnect.dispatch();	
		},
		
		isConnected : function()
		{
			return this._isConnected;
		},
		
		disconnect : function()
		{
			this.client.core.quit();
		},
		
		request : function(action, actionParameters, callback)
		{
			this.client.core.request.send(action, actionParameters, {callback : {run : function(data)
																						{
																							if(callback)
																								callback(data.data);
																						}}});
		},
		
		onCmd : function(name, callback)
		{
			this.client.onRaw(name, function(data)
			{
				callback(data.data);
			});
		},
		
		join : function(roomName, callbacks)
		{						
			this.client.addEvent('multiPipeCreate', this._onMultiPipeCreate.bind(this, roomName, callbacks));

			this.client.core.join('mainroom');
		},
		
		_onMultiPipeCreate : function(roomName, callbacks, pipe, pipeOptions)
		{
			// Room is joined?
			if(pipe.name != roomName)
				return;
				
			// Get users.
			var users = [];
			
			for(var i = 0; i < pipeOptions.users.length; i++)
			{
				if(pipeOptions.users[i].properties)
					users.push(pipeOptions.users[i].properties.userData);
			}
			
			pipe.addEvent('userJoin', this._onUserJoin.bind(this, callbacks.onUserJoin));
			pipe.addEvent('userLeft', this._onUserLeft.bind(this, callbacks.onUserLeft));
				
			// Callback.
			var result = {
							users : users,
							send : pipe.send.bind(pipe),
							onCmd : function(name, callback)
							{
								pipe.onRaw(name.toLowerCase(), function(data)
								{
									delete data.data.pipe;
									
									callback(data.data);
								});
							}
						};
			
			callbacks.onJoin(result);
		},
		
		_onUserJoin : function(callback, user, pipe)
		{
			if(callback)
				callback(user.properties ? user.properties.userData : null);
		},
		
		_onUserLeft : function(callback, user, pipe)
		{
			if(callback)
				callback(user.properties ? user.properties.userData : null);
		}

	});
})();
