classdef lumpedElement < handle & matlab.mixin.CustomDisplay & matlab.mixin.Copyable & matlab.mixin.SetGet
 %LUMPEDELEMENT Creates a lumped element circuit to load an antenna
 % 
 %   d = lumpedElement creates a lumped element circuit. The default
 %   location is at the antenna feed.
 %
 %   d = lumpedElement('Property1', value1,'Property2', value2,...)
 %   returns a lumped elements circuit, based on the specified properties.
 %   Properties you do not specify retain their default values.
 %
 %   lumpedElement properties:
 %
 %   Impedance  - Complex impedance of circuit in ohms
 %   Frequency  - Frequency in Hz
 %   Location   - The location of the load on the antenna surface in 
 %                cartesian coordinates. The default location is at the
 %                antenna feed.
 %
 %   % Examples
 %   % Load the dipole antenna at the feed and half the distance from the
 %   % feed to the top. Load at the feed is 50 ohms and at the other location
 %   % is 50+ j*20 ohms. Both the loads are frequency independent.
 %   d = dipole;
 %   l1 = lumpedElement('Impedance', complex(50, -20), 'Location', [0 0 0.5]);
 %   l2 = lumpedElement('Impedance', 50, 'Location', 'feed');
 %   d.Load = [l1, l2];
 %   show(d);
 %
 %   See also dielectric
 
 %   Copyright 2016 The MathWorks, Inc.
    
    properties(SetObservable)
        % A vector of complex impedance of circuit in ohms
        Impedance
        % A vector of frequency values in Hz. If the Frequency is empty
        % then the impedance is assumed to be invariant with frequency.
        Frequency
        % The x, y, z values of the location need to be specified. Only one
        % location can be specified for every lumpedElement. If the load
        % needs to be added to the antenna feed, the user can specify the
        % loaction as 'feed'.
        Location
    end
    
    properties(SetAccess= protected)        
        isLoadChanged = false;        
    end
    
    methods % -----Constructor----- %
        function obj = lumpedElement(varargin)
            parserObj = inputParser;            
            addParameter(parserObj,'Impedance',[]);
            addParameter(parserObj,'Frequency',[]);
            addParameter(parserObj,'Location', 'feed');
            parse(parserObj,varargin{:});                        
            obj.Impedance  = parserObj.Results.Impedance;
            obj.Frequency  = parserObj.Results.Frequency;
            obj.Location   = parserObj.Results.Location;
        end
    end
    
    methods %-------Set/Get-------- %        
        
        function set.Impedance(obj,propVal)
            if ~isempty(propVal)
                validateattributes(propVal,{'numeric'},                 ...
                    {'vector','finite','nonnan'}, 'lumpedElement', 'Impedance');
                validateattributes(real(propVal),{'numeric'},           ...
                    {'vector','real','finite','nonnan', 'nonnegative'}, ...
                    'lumpedElement', 'Impedance');
            end
            if ~isequal(obj.Impedance, propVal)
                obj.Impedance = propVal;
                %setLoadChanged(obj, true);
            end
        end        
        
        function set.Frequency(obj,propVal)
            if ~isempty(propVal)
                validateattributes(propVal,{'numeric'},                 ...
                    {'vector','real','finite','nonnan','positive'},     ...
                    'lumpedElement', 'Frequency');
            end
            if ~isequal(obj.Frequency, propVal)
                obj.Frequency = propVal;
                %setLoadChanged(obj, true);
            end
        end
        
        function set.Location(obj,propVal)
            if ~isempty(propVal)
                if ischar(propVal) || (isstring(propVal) && isscalar(propVal))
                    propVal = validatestring(propVal, {'feed'});
                    if ~strcmpi(obj.Location, propVal)                         
                            obj.Location = propVal;
                            %setLoadChanged(obj, true); %Shashank
                    end
                else
                    validateattributes(propVal,{'numeric'},             ...
                        {'vector','finite','nonnan', 'numel',3},        ...
                        'lumpedElement', 'Location');
                    if ~isequal(obj.Location, propVal)                            
                            obj.Location = propVal;
                            %setLoadChanged(obj, true); %Shashank
                    end
                end
            end
        end
        
        function setLoadChanged(obj, bool)   
            if isscalar(obj)
                obj.isLoadChanged = bool;
            else
                for m = 1:numel(obj)
                    obj(m).isLoadChanged = bool;
                end
            end
        end
        
        function bool = getLoadChanged(obj)
            if isscalar(obj)
                bool = obj.isLoadChanged;
            else
                val = zeros(1, numel(obj));
                for m = 1:numel(obj)
                    val(m) = obj(m).isLoadChanged;
                end
                if any(val) == true
                    bool = true;
                else
                    bool = false;
                end
            end
        end   
        
        function props = getObjectProperties(obj)
            G = getPropertyGroups(obj);
            props = (G.PropertyList);
        end
    end
    
    methods (Access=protected)
        function group = getPropertyGroups(obj) %#ok<MANU>
            propList = {'Impedance', 'Frequency', 'Location'};
            group = matlab.mixin.util.PropertyGroup(propList,'');                        
        end        
    end
end