%
%   Klasse Data 4.1.3
%
classdef Data < handle 
    
  properties
    file = [];   % Excel-Datei, optional
    x = [];
    y = [];
  end  % properties 
    
  methods
    % Konstruktor: verzweigt auf 2 Konstruktoren  
    function obj = Data( varargin )
      % n = nargin
      if( nargin == 0 )
        obj = Data0( obj );
      elseif( nargin == 1 )
        % Werte als Cell-Array angekommen
        obj = Data1( obj, varargin{1} );
      else
        obj.file = []; 
        errordlg( 'Zu viele Argumente für Klasse Data!', ... 
                  'Data-Konstruktor' );  
        obj = Data.empty; 
      end
    end
           
    % Daten an Data-Objekt übergeben (2 Spalten)
    function plus( obj, data )
      sz = size( data );
      if( sz(2) ~= 2 )
        errordlg( 'Nicht exakt zwei Spalten in Daten!', 'plus' );
        return;
      end
      % Daten als Spalten der Matrix data 
      d_x = data(:,1);
      d_y = data(:,2);
      % Daten unten an x bzw. y anhängen 
      obj.x = [obj.x; d_x];
      obj.y = [obj.y; d_y];  
    end
    
    % Informationen über die Daten: Anzahl, min ... max  
    function disp( obj )
      if( isempty( obj ) )
        fprintf( 'Leeres Daten-Objekt \n' );
      elseif( length(obj.x) ~= length(obj.y) )
        fprintf( 'FEHLER: Spalten unterschiedlich lang! \n' );
        fprintf( '  Anzahl x = %d, Anzahl y = %d \n', ...
                    length(obj.x), length(obj.y) );
      else
        fprintf( '%d Daten im Objekt \n', length(obj.x) ); 
        fprintf( ' Spalte 1: %g ... %g \n', min(obj.x), max(obj.x) ); 
        fprintf( ' Spalte 2: %g ... %g \n', min(obj.y), max(obj.y) );
      end
    end
 
    % varargs enthält evtl. weitere plot-Optionen
    function plot( obj, varargin )    
      if( length( obj.x ) ~= length( obj.y ) )
        errordlg( 'Spalten unterschiedlich lang!', 'plot' ); 
        return;        
      end
      % Daten plotten, mit oder ohne weitere Optionen 
      if( nargin == 2 )
        opts = varargin{1}; 
        plot( obj.x, obj.y, opts );
      else
        plot( obj.x, obj.y );
      end
      grid on
    end
    
    % Mittelwert der x-Werte, wobei y die Häufigkeit angibt
    function mw = mean( obj )
      x_s = 0; 
      y_s = 0;
      for( n = 1 : length( obj.x ) )
        y_val  = obj.y(n);            % y-Wert (Häufigkeit)
        x_s = x_s + obj.x(n)*y_val;   % gewichtete Summation für MW
        y_s = y_s + y_val;            % Summe der Gewichtungen 
      end
      mw = x_s / y_s;   % Summe geteilt durch die gewichtete Anzahl
    end   
    
     % Standardabweichung, wobei x-Breite berücksichtigt
    function sa = std( obj )
      mw = mean( obj );  % Mittelwert
      x_s = 0; 
      y_s = 0;
      for( n = 1 : length( obj.x ) )
        d_q2 = (obj.x(n) - mw)^2;   % Abweichungsquadrate 
        y_val = obj.y(n);           % y-Wert (Häufigkeit)
        x_s = x_s + d_q2*y_val;     % gew. Summation der Quadrate
        y_s = y_s + y_val;          % Summe der Gewichtungen 
        end
        sa = sqrt( x_s / y_s );       % Wurzel aus der Summe 
    end  
        
  end  % methods
  
  
  % Private Methoden  
  methods (Access = private)  
    
    % Konstruktor 0: ohne Argumente
    function obj = Data0( obj )
      obj.file = [];
    end
    
    % Konstruktor 1: mit filename oder '' bzw. []
    function obj = Data1( obj, data )
      if( ~ischar( data ) )
        obj.file = [];   % leere Liste 
      else
        % Leerstring
        if( ~isempty(data) )
          obj.file = data;
        else
          getFilename( obj );   % Dateinamen holen         
        end
      end   
    end
 
    function getFilename( obj )
      [f,p] = uigetfile( '*.xlsx', 'Daten-Datei auswählen' );
      if( f == 0 )
        % msgbox( 'Leere Liste erzeugt!', 'Konstruktor' );
        obj.file = [];
      else
        obj.file = [p,f];
      end       
     end
    
  end % private methods 
  
end
