function color = CORAcolor(identifier, varargin)
% CORAcolor - returns the CORA default colors by identifier
%
% Syntax:
%    color = CORAcolor(identifier)
%
% Inputs:
%    identifier - name of CORA colormap, one of:
%       - 'CORA:reachSet'
%       - 'CORA:initialSet'
%       - 'CORA:finalSet'
%       - 'CORA:simulations'
%       - 'CORA:unsafe'
%       - 'CORA:safe'
%       - 'CORA:highlight1': orange
%       - 'CORA:highlight2': blue
%       - 'CORA:next': next color according to colororder
%       - 'CORA:color<i>': matlab default color order colors
%       - 'CORA:blue','CORA:red',...: matlab default colors 
%       - 'MATLAB:color<i>': matlab default color order colors
%       - 'MATLAB:blue','MATLAB:red',...: matlab default colors 
%       - 'CORA:...:light' for light colors 
%    varargin - depends on identifier, see below
%
% Outputs:
%    color - rbg triple
%
% Other m-files required: none
% Subfunctions: none
% MAT-files required: none
%
% See also: useCORAcolors, readPlotOptions

% Authors:       Tobias Ladner, Lukas Koller
% Written:       02-March-2023
% Last update:   24-March-2023 (TL, added 'CORA:next')
%                25-June-2024 (TL, added 'CORA:color')
%                25-August-2025 (LK, added 'CORA:...:light')
% Last revision: ---

% ------------------------------ BEGIN CODE -------------------------------

narginchk(1,Inf);
% Split the identifiers.
[pre,name,post] = aux_splitIdentifiers(identifier);

% Specify the admissible prefixes.
admissiblePre = {'CORA','MATLAB'};
% Specify the admissible colors.
admissableColors = [ ...
    {'blue','red','yellow','purple','green','light-blue','dark-red'},...
    arrayfun(@(i) sprintf('color%d',i),1:7,'UniformOutput',false)
];
admissableCORAColors = {
    'reachSet','initialSet','finalSet','simulations', ...
    'unsafe','unsafeLight','safe','invariant',...
    'highlight1','highlight2','next'};

% The prefix has to be 'CORA'.
inputArgsCheck({{pre,'str',admissiblePre}});
% Check the colors.
switch pre
    case 'CORA'
        inputArgsCheck({{name,'str',[admissableColors admissableCORAColors]}});
    case 'MATLAB'
        inputArgsCheck({{name,'str',admissableColors}});
end
% Check the postfix.
if ~isempty(post)
    inputArgsCheck({{post,'str',{'light','dark','none'}}});
else
    % Set the default postfix.
    post = 'none';
end

% Initialize the default color.
color = [0 0 0];

switch pre
    case 'CORA'
        switch name
            case 'reachSet'
                % varargin - {numColors, cidx}
                %    - numColors: number of reachSet colors
                %    - cidx: index of reachSet color
                narginchk(1,3);

                [numColors, cidx] = setDefaultValues({1 1}, varargin);
                inputArgsCheck({ ...
                    {identifier, 'str', 'CORA:reachSet'}; ... 
                    {numColors, 'att', 'numeric', {'integer','scalar','positive'}};
                    {cidx, 'att', 'numeric', {'integer','scalar','positive'}};
                    })
                if cidx > numColors
                    throw(CORAerror('CORA:wrongValue', 'second/third', 'Color index must not be larger than number of colors.'))
                end
              
                colorMain  = [0.2706 0.5882 1.0000]; % blue
                colorWorse = [0.6902 0.8235 1.0000]; % light blue
              
                if cidx == numColors
                    color = colorMain;
                elseif cidx == 1
                    color = colorWorse;
                else
                    color = colorWorse + (colorMain-colorWorse)*((cidx-1)/(numColors-1));
                end
              
            case 'initialSet'
                color = [1 1 1];
            case 'finalSet'
                color = [1 1 1] * 0.9;
            case 'simulations'
                color = [0 0 0];
            case 'unsafe'
                color = [0.9451 0.5529 0.5686]; % red
            case 'unsafeLight'
                color = [0.9059 0.7373 0.7373]; % light red
            case {'safe','invariant'}
                color = [0.4706 0.7725 0.4980]; % green
            case 'highlight1'
                color = [1.0000 0.6824 0.2980]; % orange
            case 'highlight2'
                color = [0.6235 0.7294 0.2118]; % light green
            case 'next'
                color = defaultPlotColor();
              
            % matlab default colors
            case {'color1','blue'}
                switch pre
                  case 'CORA'
                      color = [0 0.4470 0.7410]; % blue
                  case 'MATLAB'
                      if isMATLABReleaseOlderThan('R2025a')
                          color = [0 0.4470 0.7410];
                      else
                          color = [0.0660 0.4430 0.7450];
                      end
                  otherwise
                      throw(CORAerror("CORA:wrongValue","pre",admissiblePre))
                end
            case {'color2','red'}
                switch pre
                  case 'CORA'
                      color = [0.8500 0.3250 0.0980]; % red
                  case 'MATLAB'
                      if isMATLABReleaseOlderThan('R2025a')
                          color = [0.8500 0.3250 0.0980];
                      else
                          color = [0.8660 0.3290 0];
                      end
                  otherwise
                      throw(CORAerror("CORA:wrongValue","pre",admissiblePre))
                end
            case {'color3','yellow'}
                color = [0.9290 0.6940 0.1250];  % yellow
              
                switch pre
                  case 'CORA'
                      color = [0.8500 0.3250 0.0980]; % red
                  case 'MATLAB'
                      if isMATLABReleaseOlderThan('R2025a')
                          color = [0.8500 0.3250 0.0980];
                      else
                          color = [0.8660 0.3290 0];
                      end
                  otherwise
                      throw(CORAerror("CORA:wrongValue","pre",admissiblePre))
                end
            case {'color4','purple'}
                color = [0.4940 0.1840 0.5560];  % purple
            case {'color5','green'}
                color = [0.4660 0.6740 0.1880];  % green
            case {'color6','light-blue'}
                color = [0.3010 0.7450 0.9330];  % light blue
            case {'color7','dark-red'}
                color = [0.6350 0.0780 0.1840];  % dark red
            otherwise
                throw(CORAerror("CORA:wrongValue","first",[admissableColors admissableCORAColors]))
        end
    case 'MATLAB'
        switch name
            % Matlab default colors 
            case {'color1','blue'}                             % blue
                if isMATLABReleaseOlderThan('R2025a')
                    color = [0 0.4470 0.7410];
                else
                    color = [0.0660 0.4430 0.7450];
                end
            case {'color2','red'}                               % red
                if isMATLABReleaseOlderThan('R2025a')
                color = [ 0.8500 0.3250 0.0980];
                else
                    color = [0.8660 0.3290 0];
                end
            case {'color3','yellow'}                         % yellow
                color = [0.9290 0.6940 0.1250];
              
            case {'color4','purple'}                         % purple
                if isMATLABReleaseOlderThan('R2025a')
                    color = [0.4940 0.1840 0.5560];
                else
                    color = [0.5210 0.0860 0.8190];
                end
            case {'color5','green'}                           % green
                if isMATLABReleaseOlderThan('R2025a')
                color = [0.4660 0.6740 0.1880];
                else
                    color = [0.2310 0.6660 0.1960];
                end
            case {'color6','light-blue'}                 % light blue
                if isMATLABReleaseOlderThan('R2025a')
                    color = [0.3010 0.7450 0.9330];
                else
                    color = [0.1840 0.7450 0.9370];
                end
            case {'color7','dark-red'}                     % dark red
                if isMATLABReleaseOlderThan('R2025a')
                    color = [0.6350 0.0780 0.1840]; 
                else
                    color = [0.8190 0.0150 0.5450];
                end
              
            % unknown color
            otherwise
                throw(CORAerror("CORA:wrongValue","first",admissableColors))
        end
    otherwise
      throw(CORAerror("CORA:wrongValue","pre",admissiblePre))
    
end

% Specify a factor for lightening/darkening.
d = 0.2; % I.e., d% white + (1-d)% color
% Apply a color modification based on the postfix.
switch post
    case 'light'
        % Combine the color with white.
        color = [1 1 1].*d + color.*(1-d);
    case 'dark'
        % Combine the color with black.
        color = [0 0 0].*d + color.*(1-d);
    case 'none'
        % Apply no modification.
    otherwise
end
    
end


% Auxiliary functions -----------------------------------------------------

function [pre,name,post] = aux_splitIdentifiers(ids)
    % Use a regex to split the identifiers.
    tokens = regexp(ids,':','split');
    % Extract prefix.
    pre = tokens{1};
    % Extract the color name.
    name = tokens{2};
    % Extract postfix.
    if length(tokens) > 2
        post = tokens{3};
    else
        post = [];
    end
end

% ------------------------------ END OF CODE ------------------------------
