(function ($) {

Drupal.Nodejs = Drupal.Nodejs || {'callbacks': {}, 'socket': false};

Drupal.behaviors.nodejs = {
  attach: function (context, settings) {
    if (!Drupal.Nodejs.socket) {
      if (Drupal.Nodejs.connect()) {
        Drupal.Nodejs.sendAuthMessage();
      }
    }
  }
};

Drupal.Nodejs.runCallback = function (name, module, message) {
  if (message == undefined) message = {};

  if ($.isFunction(Drupal.Nodejs.callbacks[module][name])) {
    try {
      Drupal.Nodejs.callbacks[module][name](message);
    }
    catch (exception) {}
  }
  else {
    return false;
  }
};
Drupal.Nodejs.runCallbacks = function (name, message) {
  if (message == undefined) message = {};

  $.each(Drupal.Nodejs.callbacks, function () {
    if ($.isFunction(this[name])) {
      try {
        this[name](message);
      }
      catch (exception) {}
    }
  });
}

Drupal.Nodejs.connect = function () {
  var scheme = Drupal.settings.nodejs.secure ? 'https' : 'http',
      url = scheme + '://' + Drupal.settings.nodejs.host + ':' + Drupal.settings.nodejs.port;

  Drupal.settings.nodejs.connectTimeout = Drupal.settings.nodejs.connectTimeout || 5000;
  if (typeof io === 'undefined') {
     return false;
  }
  Drupal.Nodejs.socket = io.connect(url, {'connect timeout': Drupal.settings.nodejs.connectTimeout});
  Drupal.Nodejs.socket.on('connect', function() {

    Drupal.Nodejs.runCallbacks('connect');
    Drupal.Nodejs.socket.on('message', Drupal.Nodejs.fromServerMessage);

    if (Drupal.ajax != undefined) {
      // Monkey-patch Drupal.ajax.prototype.beforeSerialize to auto-magically
      // send sessionId for AJAX requests so we can exclude the current browser
      // window from resulting notifications. We do this so that modules can hook
      // in to other modules ajax requests without having to patch them.
      Drupal.Nodejs.originalBeforeSerialize = Drupal.ajax.prototype.beforeSerialize;
      Drupal.ajax.prototype.beforeSerialize = function(element_settings, options) {
        options.data['nodejs_client_socket_id'] = Drupal.Nodejs.socket.socket.sessionid;
        return Drupal.Nodejs.originalBeforeSerialize(element_settings, options);
      };
    }
  });
  Drupal.Nodejs.socket.on('disconnect', function() {
    Drupal.Nodejs.runCallbacks('disconnect');
    if (Drupal.ajax != undefined) {
      Drupal.ajax.prototype.beforeSerialize = Drupal.Nodejs.originalBeforeSerialize;
    }
  });
  setTimeout("Drupal.Nodejs.checkConnection()", Drupal.settings.nodejs.connectTimeout + 250);
};

Drupal.Nodejs.fromServerMessage = function (message) {
  if (message.module != undefined && message.module != 'all') {
    Drupal.Nodejs.runCallback('fromServerMessage', message.module, message);
  }
  else {
    Drupal.Nodejs.runCallbacks('fromServerMessage', message);
  }
}
Drupal.Nodejs.toServerMessage = function (message) {
  return Drupal.Nodejs.socket.emit('message', message);
}

Drupal.Nodejs.checkConnection = function () {
  if (!Drupal.Nodejs.socket.socket.connected) {
    Drupal.Nodejs.runCallbacks('connectionFailure');
  }
};

})(jQuery);

// vi:ai:expandtab:sw=2 ts=2

;
(function ($) {
Drupal.chatroomNodejs = {};

Drupal.chatroomNodejs.fromServerMessage = function (message) {
	if (message.module != 'chatroom') return false;

	if (message.type == 'message') {
		Drupal.chatroom.addMessage(message);
	}
	else if (message.type == 'notification') {
		Drupal.chatroom.addNotification(message);
	}
	else if (message.type == 'kicked') {
		Drupal.chatroom.kicked(message);
	}
	else if (message.type == 'banned') {
		Drupal.chatroom.banned(message);
	}
	else if (message.type == 'script') {
		Drupal.chatroom.runScript(message);
	}
}
Drupal.chatroomNodejs.sendMessage = function (message) {
	Drupal.Nodejs.toServerMessage({
		module: 'chatroom',
		message: message
	});
}
Drupal.chatroomNodejs.online = function (message) {
	if (message.presence == 'list') {
		Drupal.chatroom.initUserList();

		for (var i in message.userData) {
			if ($.inArray('chat', message.userData[i].locations) == -1) {
				continue;
			}

			Drupal.chatroom.updateUserList(message.userData[i].user, 'online');
		}
	}
	else if (message.presence == 'online') {
		for (var i in message.userData) {
			if ($.inArray('chat', message.userData[i].locations) == -1) {
				continue;
			}

			Drupal.chatroom.updateUserList(message.userData[i].user, message.presence);
		}
	}
	else if (message.presence == 'offline') {
		for (var i in message.userData) {
			Drupal.chatroom.updateUserList(message.userData[i].user, message.presence);
		}
	}
}

Drupal.Nodejs.callbacks.chatroom = {
	fromServerMessage: Drupal.chatroomNodejs.fromServerMessage,
	online: Drupal.chatroomNodejs.online,
}

})(jQuery);

;
(function ($) {
Drupal.NodejsAuthentication = {};

Drupal.NodejsAuthentication.authenticate = function (message) {
  var authMessage = {
    module: 'authentication',
    authToken: Drupal.settings.nodejs.authToken,
    location: Drupal.settings.nodejs.location,
  };
  Drupal.Nodejs.toServerMessage(authMessage);
};

Drupal.NodejsAuthentication.clientId = function (message) {
	if (message.module != 'authenticate') return false;

	if (message.type == 'clientId') {
		Drupal.settings.nodejs.clientId = message.clientId;

		Drupal.Nodejs.runCallbacks('authenticated', message.clientId);
	}
};

Drupal.Nodejs.callbacks.authentication = {
	connect: Drupal.NodejsAuthentication.authenticate,
	fromServerMessage: Drupal.NodejsAuthentication.clientId,
}

})(jQuery);
;
(function ($) {
Drupal.NodejsOnline = {};

Drupal.NodejsOnline.users = function (message) {
	if (message.module != 'online') return false;

	if (message.type == 'presence') {
		Drupal.Nodejs.runCallbacks('online', message);
	}
};

Drupal.Nodejs.callbacks.online = {
	fromServerMessage: Drupal.NodejsOnline.users,
}

})(jQuery);
;

