function callBackId = urbiSetCallback(con, f, mytag)
% Associate the execution of a function to specifically tagged messages 
% This function associates a function f to a tag on a given connection.c
%
%  e.g.  urbiSetCallback(myrobot,@f,'callbacktag')
%
% If the function urbiProcessEvent reads a message with this tag on this
% connection, the function f will be called with a umessage as argument:
%
%   cont = f(umessage)
%
% The callback function f should return either 0, and in this case the 
% callback is deleted, or 1, and in this case the callback continues.
%
% urbiSetCallBack returns an id for the callback so that later on it can be
% deleted manually using urbiDeleteCallBack(callBackId);

if (nargin~=3)
    error(['urbiSetCallback(con, f, mytag)\n' ...
           '  con : ID of the connection to the Urbi server\n' ...
           '  f : function f(umessage) executed upon message reception\n' ...
           '  mytag : tag of the messages to be processed by this function'],1);
end


global Internal_Call_Back_Array Internal_Call_Back_connections
persistent Internal_Call_Back_identificator 

if (size(Internal_Call_Back_connections, 1) == 0)
    % First call return id zero
    Internal_Call_Back_identificator = 0;
    Internal_Call_Back_connections = con;
    Internal_Call_Back_Array{con.id + 1} = [];
else
    % Other calls increase the next id
    Internal_Call_Back_identificator = Internal_Call_Back_identificator + 1;
    if (~ismember(con.id, [Internal_Call_Back_connections.id]))
        Internal_Call_Back_connections = [con Internal_Call_Back_connections];
        Internal_Call_Back_Array{con.id +  1} = [];        
    end;
end;

Internal_Call_Back_Array{con.id + 1} = [Internal_Call_Back_Array{con.id + 1} ; 
struct('id', Internal_Call_Back_identificator, 'function', f, 'tag', mytag) ];
callBackId = Internal_Call_Back_identificator;
 
