%

% Copyright 2017-2018 The MathWorks, Inc.
function metadataRange = getMetadataRange(maxMetadataRows, range)
    import xls.internal.Range;
    if xls.internal.util.inBaseWorkspace(range)
        range = evalin('base', range);
    end
    range = string(range);
    len = strlength(range);
    if len == 0 || isnan(len)
        metadataRange = getRange(maxMetadataRows, 1);
    else
        options = ["ignorecase", "tokens", "once"];
        % if maxMetadataRows == 5, then...
        % ...rowRange of 1:10 returns 1:6
        value = regexp(range, Range.RowRange, options{:});
        if ~isempty(value)
            metadataRange = getRange(maxMetadataRows, value{1});
            return;
        end

        % ...colRange of A:CC returns A1:CC6
        value = regexp(range, Range.ColRange, options{:});
        if ~isempty(value)
            metadataRange = getColumnRange(maxMetadataRows, value);
            return;
        end

        % ...rectangularRange of A3:B9 returns A3:B8
        value = regexp(range, Range.RectRange, options{:});
        if ~isempty(value)
            metadataRange = getRectangularRange(maxMetadataRows, value(1:end-1));
            return;
        end

        % parse error, use first rows and let readtable validate the range
        metadataRange = getRange(maxMetadataRows, 1);
    end
end

function range = getRange(maxMetadataRows, startRow)
    if ischar(startRow)
        startRow = str2double(startRow);
    end

    range = string(startRow + ":" + (startRow + maxMetadataRows));
end

function metadataRange = getColumnRange(maxMetadataRows, value)
    % get first rows of columns passed in
    value(1) = value(1) + 1;
    value(2) = value(2) + (maxMetadataRows + 1);
    metadataRange = value.join(':');
end

function metadataRange = getRectangularRange(maxMetadataRows, value)
    % add first digit to maxMetadataRows and append to second part of range
    value(3) = value(3) + (str2double(value(2)) + maxMetadataRows);
    % recombine first and second parts
    value(1) = value(1) + value(2);
    value(2) = [];
    metadataRange = value.join(':');
end
