%% Testklasse zum Verhalten von subsref
classdef Reftest
   properties
      data1
      data2       
      skalar
   end
   
   properties (Dependent = true)
       n_el
   end
   
   methods
       function out = get.n_el(obj)
          out = size(obj.data1,1);           
       end
       
       
       function out = subsref(obj,S)
           % Angepasste subsref-Funktion:
           % Bei Aufruf mit eindimensionalem Index werden die zeilenweise
           % zugeordnete Ausgaben erzeugt, in allen anderen Faellen soll 
           % das normale Verhalten abgebildet werden.
           % 
           % Mehrzeilige Felder werden Indexweile (Zeilenindex)
           % uebertragen, einzeilige Felder komplett
           DEBUG = true;
           
           if DEBUG
               disp('subsref')
           end

           %% Normales Verhalten von subsref:
           if ~strcmpi(S(1).type,'()')
               out = builtin('subsref',obj,S);
               return
           end
           
           %% Sonderverhalten fuer direkte Elementindizierung
           % Wird das Objekt direkt numerisch indiziert, sollen die
           % properties zeilenweise dem Ausgabeobjekt zugeordnet werden.
           % Eine sonstige Veraenderung ist zu vermeiden.

           
           % Darstellen des subsref-structures
           if DEBUG
               n_idx = numel(S);
               for i = 1:n_idx
                   fprintf('S(%2d).type = %4s     S(%2d).subs = %1s  ',i,S(i).type,i,'')
                   display(S(i).subs)
               end
           end
           
           % S(1) sollte immer existieren; S.type muss '()' sein.
           rtref = S(1);
           idx = rtref.subs{:};
           if numel(rtref.subs) > 1
               error('Index exceeds matrix dimensions')
           end
                      
           % Sonderfall 1: Komplettes Elementarray obj.(:)
           if strcmpi(rtref.subs{:},':')
              disp('Komplettes Array 1')
              
              if numel(S) > 1              
                   out = builtin('subsref',obj,S(2:end));
              else
                  out = obj;
              end
              return
           end
           
           % Sonderfall 2: Komplettes Elementarray obj(1:end)
           % -> ist kein Sonderfall, da "end" ueberladen
           

           % Felder ueber Meta-Klasse einlesen;
           % Nur independent properties werden kopiert
           mc = ?Reftest;
           props = mc.Properties;
           
           % Temporaeres Objekt mit Indizierung der ersten Stufe erzeugen
           % Nur independent, einzeilige Felder komplett
           temp = Reftest;
           for i = 1:numel(props)
               pi = props{i};
               if ~pi.Dependent
                   if size(obj.(pi.Name),1) == 1
                       temp.(pi.Name) = obj.(pi.Name);
                   else
                       temp.(pi.Name) = obj.(pi.Name)(idx,:);
                   end
               end
           end
           
           
           if ~(numel(S) > 1)
               % Ohne weitere Indizierung: komplettes Objekt der
               % entsprechenden Teile wird ausgegeben
               out = temp;
           else
               % Unterindizierung auf Ausgabe der Vorindizierung
               out = builtin('subsref',temp,S(2:end));
           end
       end
       
       
       function out = end(obj,k,n)
           % (doc end):
           % You can overload the end statement for a user object by 
           % defining an end method for the object. The end method should 
           % have the calling sequence end(obj,k,n), where obj is the user 
           % object, k is the index in the expression where the end syntax 
           % is used, and n is the total number of indices in the 
           % expression. For example, consider the expression 
           %    A(end-1,:)
           % The MATLAB software calls the end method defined for A using 
           % the syntax
           %    end(A,1,2)
           %
           % Mehr doku zum Ueberladen von "end" nicht auffindbar           
           if ~((k == 1))
               error('object is only single indexed!')
           end
           out = obj.n_el;
       end
       
   end
    
end
