function result = subsref(obj, Struct)
%SUBSREF Reference into serial port objects.
%
%    Supported syntax for serial port objects:
%
%    Dot Notation:                  Equivalent Get Notation:
%    =============                  ========================
%    obj.Tag                        get(obj,'Tag')
%    obj(1).Tag                     get(get(obj,1),'Tag')
%    obj(1:4).Tag                   get(get(obj,[1:4]), 'Tag')
%    obj(1)
%
%    See also SERIAL/GET.
%

%    MP 7-13-99
%    Copyright 1999-2000 The MathWorks, Inc. 
%    $Revision: 1.3 $  $Date: 2000/07/19 12:47:35 $


% Initialize variables.
prop1 = '';
index1 = {};
StructL = length(Struct);

% Define possible error messages
error1 = 'Inconsistently placed ''()'' in subscript expression.';
error2 = 'Cell contents reference from a non-cell array object.';
error3 = 'Inconsistently placed ''.'' in subscript expression.';

% Parse the input.

% The first Struct can either be:
% obj(1); 
% obj.SampleRate;
switch Struct(1).type
case '.'
   prop1 = Struct(1).subs;
case '()'
   index1 = Struct(1).subs;
case '{}'
   error(error2);
otherwise
   error(['Unknown type: ' Struct(1).type,'.']);
end

if StructL > 1
   % Ex. obj(1).BytesAvailable;
   switch Struct(2).type
   case '.'
      if isempty(index1)
         % Ex. obj.BytesAvailable.Prop2
         error(error3);
      else
         % Ex. obj(1).BytesAvailable;
         prop1 = Struct(2).subs;
      end
   case '()'
      error(error1);   
   case '{}'
      error(error2);
   otherwise
      error(['Unknown type: ' Struct(2).type,'.']);
   end  
end   

% Index1 will be entire object if not specified.
if isempty(index1)
   index1 = 1:length(obj);
end

% Convert index1 to a cell if necessary.
if ~iscell(index1)
   index1 = {index1};
else
   if length([index1{:}]) == 1 & strcmp(index1{:}, ':')
       index1 = {[1:length(obj)]};
   end
end

% Return the specified value.
if ~isempty(prop1)
   % Ex. obj.BaudRate 
   % Ex. obj(2).BaudRate
   
   % Extract the object.
   [indexObj, errflag] = localIndexOf(obj, index1);
   if errflag
      localCheckError;
      error(lasterr);
   end
   
   % Get the property value.
   try
      result = get(indexObj, prop1);
   catch
      localCheckError;
      error(lasterr);
   end
else
   % Ex. obj(2);
   
   % Extract the object.
   [result, errflag] = localIndexOf(obj, index1);   
   if errflag
      localCheckError;
      error(lasterr);
   end
end

% *********************************************************************
% Index into an instrument array.
function [result, errflag] = localIndexOf(obj, index1)

% Initialize variables.
errflag = 0;

try
   % Get the field information of the entire object.
   jobj = igetfield(obj, 'jobject');
   type = igetfield(obj, 'type');
   constructor = igetfield(obj, 'constructor');	
   
   if isstr(constructor)
   	   % Ex. obj(1) when obj only contains one element.	
       constructor = {constructor};
   end
   
   % Create the first object and then append the remaining objects.
   if (length([index1{1}]) == 1)
       % This is needed so that the correct classname is assigned
       % to the object.
	   result = feval(constructor{index1{1}(1)}, jobj(index1{:}));
   else
       % The class will be instrument since there are more than 
       % one instrument objects.  
       result = obj;
   	   result = isetfield(result, 'jobject', jobj(index1{:}));
   	   result = isetfield(result, 'type', type(index1{:}));
       result = isetfield(result, 'constructor', constructor(index1{:}));
   end
catch
   lasterr('Index exceeds matrix dimensions.');
   result = [];
   errflag = 1;
   return;
end

% *************************************************************************
% Remove any extra carriage returns.
function localCheckError

% Initialize variables.
errmsg = lasterr;

% Remove the trailing carriage returns.
while errmsg(end) == sprintf('\n')
   errmsg = errmsg(1:end-1);
end

lasterr(errmsg);
