function r = urbiProcessEvents(n, timeout)
% Receive messages from server and launch appropriate callbacks
% This function checks whether there are messages on all urbi connections
% associated with a callback.
% If yes, it parses them and calls the associated callbacks functions with
% an urbiMessage structure as argument
%
%   n specifies an upper limit of the number of messages which can be processed
%     in one call of processEvents (this is for allowing to give the
%     control back if there are too many messages)
%
%   timeout specifies the number of milliseconds during which the function
%   waits before returning when there are no messages on the input  
%     if timeout == -1, then the function returns immediately if there are
%     no messages or else returns the number of callBacks that have been called
%     if timeout == -2, then the function never returns 

if (nargin~=2)
    error(['urbiProcessEvents(n, timeout)\n' ...
           '  n : maximum number of messages to process\n' ...
           '  timeout : time after which function returns if no message is received'],1);
end


global Internal_Call_Back_Array Internal_Call_Back_connections

% Initialise callback number to null
r = 0;
connections = size(Internal_Call_Back_connections, 2);
% update the timeout control
t = cputime;
while (1)
    for i=1:connections
        con = Internal_Call_Back_connections(i);
        % Listen to the connection where callbacks are defined
        string = pnet(con.id, 'readline', 'noblock');

        if (~isempty(string))
            msg = urbiFullParse(string,con); 
            
            Array = Internal_Call_Back_Array{con.id + 1};
            for i=1:size(Array, 1)
                if (strcmp(msg.tag, Array(i).tag))
                    % Make the function argument
                    C = Array(i);

                    %Call the Callback function
                    if ( ~feval(C.function, msg) )
                        urbiDeleteCallback(con, C.id);
                        % Connection number may have changed
                        connections = size (Internal_Call_Back_connections, 2);
                    end;

                    r = r + 1;
                    if (r == n)
                        % We've reached the callback limit
                        return;
                    end;
                end;
            end;
            % update the timeout control
            t = cputime;
        else
            if ((((cputime - t) * 1000 > timeout) | (timeout == -1)) & (timeout ~= -2))
                return;
            end;
        end;
    end;
end;
