function umessage = urbiFullParse(full_string, con)
% Perform the full parsing of a message from the Urbi server
%  This function returns a struct containing all the data
%  contained in the message :
%
%  umessage.timeStamp  : the time stamp of the message
%  umessage.tag        : the tag of the message
%  umessage.type       : the type of the message: 'numeric', 'string',
%                        'list', 'system', 'object', 'image', 'sound',
%                         or 'otherBIN'
%  umessage.value      : message content:
%                           numeric         if type == numeric
%                           character array if type == string
%                           cell array      if type == list
%                           character array if type == system
%                           character array if type == object
%                           character array if type == image
%                           struct          if type == sound
%                                (with fields samples, Fs, nbits, length)
%                           bytes array     if type == otherBIN

if (nargin <2)
    error(['urbiFullParse(full_string, con)\n' ...
           '  full_string : message from the server\n' ...
           '  con : id of the connection'],1);
end

string = strread(full_string, '%s');

% parse header
[timeStamp, tag] = strread(string{1}, '[%u:%s]', 'whitespace', ']');

if (min(size(tag)) == 0) 
    tag = '';
end

%parse message content
f = sscanf(string{2}, '%f') ;
if ~isempty(f)
    type =  'numeric';
    value = f;
    image = [];
    sound = [];
    bin   = [];
else
    s = string{2};
    if strcmp(s, 'BIN')
        if strcmp(string{4}, 'jpeg')
            io_buffer = 'imageB.jpg';
            type = 'image';
            pnet(con.id, 'readtofile', io_buffer, sscanf(string{3}, '%u')) ;
            value = imread(io_buffer) ;
        elseif strcmp(string{4}, 'raw')
            type = 'sound';
            % Parse the sound and store the structure
            Fs      = str2num ( string{6} );
            length   = str2num ( string{3} );
            nbits    = str2num ( string{7} );
            channel = str2num ( string{5} );
            duration = length/(Fs*channel*(nbits/8))*1000;
            samples = pnet(con.id, 'read', length);
            value = struct('samples',samples,'Fs',Fs,'nbits', nbits, 'length', length, 'channel', channel, 'duration',duration);
        else
            type = 'otherBIN';
            value   = pnet(con.id, 'read', str2num ( string{3} ), 'noblock');
        end;
   else
       if strcmp(s, '***')
           type = 'system';
           value = sprintf('%s ',string{3:end});
       elseif strcmp(s, '!!!')
           type = 'error';
           value = sprintf('%s ',string{3:end});         
       elseif strcmp(s, 'OBJ')
           type = 'object';
           value = strtrim(char(strrep(full_string,string(1),'')));
       elseif strcmp(s(1),'[')
           type = 'list';
           s=char(strrep(full_string,string(1),''));
           s=strrep(s,'[','{');
           s=strrep(s,']','}');
           s=strrep(s,'"','''');
           s = ['value={' s '};'];
           eval(s);
       else
           type = 'string';
           value = sprintf('%s ',string{2:end});
       end;
    end;
end;

umessage = struct('timeStamp', timeStamp, 'tag', tag, 'type', type, 'value', value);
