classdef (Hidden) LogicAnalyzerCursor
    %LogicAnalyzerCursor Cursor object for dsp.LogicAnalyzer
    %   This object is used to describe the properties of each cursor
    %   displayed in the Logic Analyzer window. 
    
    %   Copyright 2012-2014 The MathWorks, Inc.

    properties
        %Location Location of the cursor
        %   Specify the value of the cursor location in seconds. The
        %   default value for this property is 0.
        Location = 0;
        
        %Color Color used for cursor display
        %   Specify Color as an [R G B] value.
        %   The default value for this property is [1 1 0] or 'Yellow'.
        Color = [1 1 0];
    
        %Locked Lock the cursor
        %   Specify Locked to be one of false | true. Specifying a
        %   value of true implies that the cursor is locked (that is, its
        %   Location cannot be changed). 
        Locked = false;
    end
    
    properties (Hidden)
        Name = '';
    end
    
    properties (Hidden, Dependent)
        Time;
    end
    
    properties (Access = private)
        %Tag Cursor tag
        %   Unique tag for the cursor. The tag provided allows the user to
        %   identify the cursor easily.
        Tag = '';
    end
    
    methods
        function obj = LogicAnalyzerCursor(varargin)
            % constructor
            % pv pairs should be multiple of 2 and all properties should be
            % char
            if nargin~= 0 && (mod(nargin,2) ~= 0 || isCharOrString(varargin(1:2:end)))
                error(message('dspshared:LogicAnalyzer:pvpairs'));
            end
            for ii = 1:nargin/2
                obj.(char(varargin{(2*ii)-1})) = varargin{2*ii};
            end
        end
        
        function obj = set.Time(obj, value)
            obj.Location = value;
        end
        
        function value = get.Time(obj)
            value = obj.Location;
        end
        
        function obj = set.Location(obj, value)
            % Location must be a scalar non-negative finite numeric value
            propName = 'Location';
            validateattributes(value, ...
                {'numeric'}, {'real','finite','nonnegative','scalar'},'', ...
                propName);
            obj.(propName) = value;
        end
        
        function obj = set.Color(obj, value)
            % Color can be one of the set specifiedy
            if ischar(value) || isstring(value)
                colorSet = getLogicAnalyzerDisplayColorSet;
                colorSet([1 5])=''; % black and red are not allowed
                validatestring(value, colorSet, '', 'Color');
                value = uiservices.hexColorToRGB(uiservices.stringColorToHexColor(value));
            end
            obj.Color = value;
        end % set.Color
        
        function obj = set.Locked(obj, value)
            % locked can be set to true or false
            propName = 'Locked';
            validateattributes(value, ...
                {'logical'}, {},'', propName);
            obj.(propName) = value;
        end
        function found = findByTag(obj, tag)
            if strcmpi(obj.getTag, tag)
                found = obj;
            else
                found = [];
            end
        end
    end
    
    methods (Hidden, Static)
        function obj = fromGraphicalSettings(gs, indx)
            if iscell(gs.times)
                gs.times = [gs.times{:}];
            end
            if iscell(gs.lockedCursors)
                gs.lockedCursors = [gs.lockedCursors{:}];
            end
            inputs = {'Location', gs.times(indx), ...
                'Tag', sprintf('C%d', gs.instanceNumbers(indx))};
            if any(gs.lockedCursors == indx-1)
                inputs = [inputs {'Locked', true}];
            end
            if isfield(gs, 'colors') && numel(gs.colors) >= indx && ~isempty(gs.colors{indx})
                inputs = [inputs {'Color', uiservices.hexColorToRGB(gs.colors{indx})}];
            end
            if isfield(gs, 'names') && numel(gs.names) >= indx
                inputs = [inputs {'Name', gs.names{indx}}];
            end
            
            obj = dsp.LogicAnalyzerCursor(inputs{:});
        end
    end
    
    methods(Hidden)
        
        function s = struct(this)
            s = builtin('struct', this);
            s = rmfield(s, {'Time', 'Name'});
        end
        
        function gs = toGraphicalSettings(this, varargin)
            if nargin < 2 || any(strcmp(varargin, 'Location')) || any(strcmp(varargin, 'Time'))
                gs.time = this.Location;
            end
            if nargin < 2 || any(strcmp(varargin, 'Locked'))
                gs.isLocked = this.Locked;
            end
            if nargin < 2 || any(strcmp(varargin, 'Color'))
            
                if ischar(this.Color)
                    gs.color = uiservices.stringColorToHexColor(lower(this.Color));
                else
                    gs.color = uiservices.rgbToHexColor(this.Color);
                end
                if strcmp(gs.color, '#ffff00')
                    gs.color = 'default';
                end
            end
            if nargin < 2 || any(strcmp(varargin, 'Name'))
                gs.name = this.Name;
            end
        end
        
        function setValues = set(obj, propName) %#ok<INUSL>
            % allows tab completion
            switch(propName)
                case 'Color'
                    setValues = getLogicAnalyzerDisplayColorSet;
            end
        end % set
        
        function tag = getTag(obj)
            tag = obj.Tag;
        end
        
        function obj = setTag(obj, tag)
            obj.Tag = tag;
        end
    end % Hidden methods
    
end % classdef

function b = isCharOrString(propertyNames)

b = ~all(cellfun(@(inp) ischar(inp) || isstring(inp), propertyNames));

end

