function obj = laneMarking(typeOrObjects,varargin)
%laneMarking Construct a lane marking object of the given LaneBoundaryType
%   lm = laneMarking(type) returns a lane marking object of the specified
%   LaneBoundaryType. Following types are supported:
%     Unmarked     - No physical lane marker exists.
%     Solid        - Single unbroken lane marker.
%     Dashed       - Single line of dashed lane markers.
%     DoubleSolid  - Double unbroken lane markers.
%     DoubleDashed - Double dashed lane markers
%     SolidDashed  - Solid marker followed by dashed marker.
%     DashedSolid  - Dashed marker followed by solid marker.
%
%   lm = laneMarking(type, Name, Value, ...) specifies additional
%   name-value pair arguments described below:
%
%     Color      A 1-by-3 array specifying the RGB MATLAB color of the lane
%                marking. The default value is [1 1 1]. A MATLAB color
%                string can also be specified.
%
%     Width      A scalar specifying the width of the lane marking in
%                meters. For double marking types, this is the width used
%                for each individual marking and the space in between the
%                two markings. The default is 0.15m.
%
%     Strength   A scalar specifying the strength metric for the lane
%                marking from 0 to 1. A value of 0 corresponds to a marking
%                that is not visible and a value of 1 corresponds to a
%                marking that is perfectly visible. The default value is 1.
%
%     Length     A scalar specifying the length of the visible part of the
%                lane marking for applicable marking types such as Dashed
%                in meters. The default is 3m.
%
%     Space      A scalar specifying the space following the visible part
%                of the lane marking for applicable marking types such as
%                Dashed in meters. The default is 9m.
%
%     SegmentRange  A vector specifying the normalized range values for
%                   lane marking types present on a lane. Specify
%                   'SegmentRange' if you create a Composite lane
%                   marking object. The default value for each element in
%                   'SegmentRange' is inversely proportional to the number
%                   of lane marking types contained in the Composite lane
%                   marking object. The proportionality constant is 1.
%
%
%   % Example 1
%   % ---------
%   % Create a curved road with three lanes
%   s = drivingScenario;
%   roadCenters = [0 0; 10 0; 53 -20];
%
%   lm = [laneMarking('Solid')
%         laneMarking('Dashed','Length',1.5,'Space',3)
%         laneMarking('Solid')];
%
%   road(s, roadCenters, 'Lanes', lanespec(2,'Marking',lm));
%   plot(s);
%
%
%   % Example 2
%   % ---------
%   % Create a road with 3 lanes and 4 boundary markings
%   % Specify the third marking as composite marking.
%
%   s = drivingScenario;
%   roadCenters = [0 0; 10 0; 53 -20];
%
%   lm = [laneMarking('Solid')
%         laneMarking('Dashed')
%         laneMarking([ laneMarking('Dashed') laneMarking('Solid')],'SegmentRange',[0.7 0.3])
%         laneMarking('Solid')];
%
%   road(s, roadCenters, 'Lanes', lanespec(3,'Marking',lm));
%   plot(s);
%
%   See also lanespec, road, drivingScenario

%   Copyright 2017-2019 The MathWorks, Inc.


% Check for when try to create composite marking with unsupported array of LaneBoundaryType.
if ~isa(typeOrObjects,'driving.scenario.LaneMarking') && ~isa(typeOrObjects,'LaneBoundaryType') && ~(ischar(typeOrObjects) || isstring(typeOrObjects))
    error(message('driving:scenario:UnsupportedMarking'));
end

% For uniform lane markings
if ~isa(typeOrObjects,'driving.scenario.LaneMarking')
    % Error for unsupported marking types
    if ischar(typeOrObjects) || isstring(typeOrObjects)
        typeOrObjects = validatestring(typeOrObjects,{'Solid','DoubleSolid','Unmarked','Dashed',...
            'DoubleDashed','DashedSolid','SolidDashed'},mfilename, 'type');
    else
        % Must be LaneBoundaryType
        validateattributes(typeOrObjects,{'LaneBoundaryType'},{'scalar'},mfilename,'type');
        % BottsDots is not supported
        if typeOrObjects == LaneBoundaryType.BottsDots
            error(message('driving:scenario:UnsupportedMarkingType'));
        end
    end

    switch typeOrObjects
        case {'Solid','DoubleSolid'}
            % Construct a solid marking
            obj = driving.scenario.SolidMarking(typeOrObjects,varargin{:});
        case {'Unmarked'}
            % Construct the unmarked/none marking
            obj = driving.scenario.LaneMarking(typeOrObjects);
        case {'Dashed','DoubleDashed','DashedSolid','SolidDashed'}
            % Construct a dashed marking
            obj = driving.scenario.DashedMarking(typeOrObjects,varargin{:});
    end
else
    % For multiple lane markings.
    obj = driving.scenario.CompositeMarking(typeOrObjects,varargin{:});
end
