function cellToObject(busCell, scope)
%  Simulink.Bus.cellToObject converts a cell array containing bus information
%  to bus objects.
%
%  Usage:
%  ======
%   1. Convert a cell array that contains bus information to a set of
%      bus objects in the MATLAB base workspace:
%      >> Simulink.Bus.cellToObject(busCell);
%
%   2. Convert a cell array that contains bus information to a set of
%      bus objects in a Simulink data dictionary:
%      >> scope = Simulink.data.dictionary.open('myfile.sldd');
%      >> Simulink.Bus.cellToObject(busCell, scope);
%
%   Required Inputs:
%      busCell: Cell array that contains bus information for a set of bus objects
%
%   Optional Inputs:
%      scope: This argument specifies a Simulink.data.Dictionary
%             object. If unspecified, this argument defaults to the MATLAB base workspace.
%
%  The input cell array must contain nx1 cells.
%
%  Each of these 'n' cells is a 1x7 cell array, where the first element of
%  the cell is the bus object name, the second element is HeaderFile,
%  the third element is Description, the fourth element is DataScope,
%  the fifth element is Alignment, the sixth element is PreserveElementDimensions 
%  and the seventh element is a [kx1] cell array, 
%  where 'k' is the number of elements in the bus object.
%
%  Each of these 'k' cells defines a bus element and must contain these
%  fields in order: Name, Dimensions, DataType, Complexity
%  and SamplingMode.
%  Each 'k' cell may also contain these fields in order:
%  DimensionsMode, Min, Max, Unit, Description.
%
%  For example, this cell array defines bus object BC1, which contains signals
%  'a' and 'b':
%
%  busCell = { ...
%    { ...
%      'BC1', ...            % Bus Object Name
%      'MyHeader.h', ...     % Header File
%      'My description', ... % Description
%      'Exported', ...       % Data Scope
%      '-1', ...             % Alignment
%      '0',...               % Preserve Element Dimensions 
%      {{'a',1,'double','real','Sample'}; ...
%       {'b',1,'double','real','Sample','Fixed',-3,3,'m','b is the distance from origin'}},...
%    }, ...
%  };
%  Simulink.Bus.cellToObject(busCell);
%
%   See also Simulink.Bus.save
%   See also Simulink.Bus.objectToCell

% Copyright 2005-2022 The MathWorks, Inc.

if nargin == 0 || nargin > 2
    DAStudio.error('Simulink:tools:slbusInvalidNumInputs');
elseif nargin == 1
    scope = Simulink.data.BaseWorkspace;
end

% Convert to internal abstraction from user documented API for SLDD
if isa(scope, 'Simulink.data.Dictionary')
    scope = Simulink.data.DataDictionary(scope.filepath);
end

numBus = length(busCell);
for idx = 1:numBus
    thisCell = busCell{idx};
    
    if length(thisCell) == 2
        % Backward compatible format - data scope and header file
        % and description and alignment information is missing
        busName  = thisCell{1};
        headerFile = '';
        description = '';
        dataScope = 'Auto';
        alignment = -1;
        preserveElementDimensions = false;
        elemInfo = thisCell{2};
    elseif length(thisCell) == 4
        % Backward compatible format - data scope and alignment information is missing
        busName  = thisCell{1};
        headerFile = thisCell{2};
        description = thisCell{3};
        dataScope = 'Auto';
        alignment = -1;
        preserveElementDimensions = false;
        elemInfo = thisCell{4};
    elseif length(thisCell) == 5
        % Backward compatible format - alignment information is missing
        busName  = thisCell{1};
        headerFile = thisCell{2};
        description = thisCell{3};
        dataScope = thisCell{4};
        alignment = -1;
        preserveElementDimensions = false;
        elemInfo = thisCell{5};
    elseif length(thisCell) == 6
        busName  = thisCell{1};
        headerFile = thisCell{2};
        description = thisCell{3};
        dataScope = thisCell{4};
        alignment = str2num(thisCell{5});
        preserveElementDimensions = false;
        elemInfo = thisCell{6};
    else 
        busName  = thisCell{1};
        headerFile = thisCell{2};
        description = thisCell{3};
        dataScope = thisCell{4};
        alignment = str2num(thisCell{5});
        preserveElementDimensions = str2num(thisCell{6});
        elemInfo = thisCell{7};
    end
    
    numElm = length(elemInfo);
    
    slbusObj = Simulink.Bus;
    slbusObj.DataScope = dataScope;
    slbusObj.HeaderFile = headerFile;
    slbusObj.Description = description;
    slbusObj.Alignment = alignment;
    if sl('busUtils','NDIdxBusUI')
        slbusObj.PreserveElementDimensions = preserveElementDimensions;
    end
    clear elems;
    
    % The element information is defined in a cell array contained within 
    % the outer cell that defines that bus object itself 
    if(iscell(elemInfo))
        
        for eIdx = 1:numElm
            thisElm = elemInfo{eIdx};
            
            elems(eIdx) = Simulink.BusElement;  %#ok
            elems(eIdx).Name         = thisElm{1}; %#ok<AGROW>
            elems(eIdx).Dimensions   = thisElm{2}; %#ok<*AGROW>
            elems(eIdx).DataType     = thisElm{3};
            if isnumeric(thisElm{4})
                if (thisElm{4}(1)) ~= -1
                    warning(message('Simulink:DataType:BusElementNonInheritSampleTimeSpecifiedNoBlock', num2str(thisElm{4}(1)), elems(eIdx).Name, busName));
                end
            else
                tempElm = thisElm(4:end);
                thisElm = [thisElm{1:3} -1 tempElm];
            end
            elems(eIdx).SampleTime = thisElm{4};
            elems(eIdx).Complexity   = thisElm{5};
            
            samplingMode = thisElm{6}; 
            if isstring(samplingMode) 
                samplingMode = convertStringsToChars(samplingMode); 
            end
            
            elems(eIdx).SamplingMode = [samplingMode, ' based'];
            if length(thisElm) > 6
                elems(eIdx).DimensionsMode = thisElm{7};
            end
            
            if length(thisElm) > 7
                elems(eIdx).Min = thisElm{8};
                elems(eIdx).Max = thisElm{9};
            end
            
            if length(thisElm) > 9
                elems(eIdx).DocUnits = thisElm{10};
                elems(eIdx).Description = thisElm{11};
            end
            
            if eIdx == numElm
                slbusObj.Elements = elems;
            end
        end
        
    else        
        %The element information can also be defined as a array of
        %Simulink.BusElement objects
        if(isvector(elemInfo))
            for eIdx = 1:numElm
                thisElm = elemInfo(eIdx);
                
                elems(eIdx) = Simulink.BusElement;  %#ok
                elems(eIdx).Name         = thisElm.Name;
                elems(eIdx).Dimensions   = thisElm.Dimensions;
                elems(eIdx).DataType     = thisElm.DataType;
                elems(eIdx).SampleTime   = thisElm.SampleTime;
                elems(eIdx).Complexity   = thisElm.Complexity;
                elems(eIdx).SamplingMode = thisElm.SamplingMode;
                
                elems(eIdx).DimensionsMode = thisElm.DimensionsMode;
                elems(eIdx).Min = thisElm.Min;
                elems(eIdx).Max = thisElm.Max;
                elems(eIdx).DocUnits = thisElm.DocUnits;
                elems(eIdx).Description = thisElm.Description;                
                
                if eIdx == numElm
                    slbusObj.Elements = elems;                
                end
            end
        end
    end
    scope.assignin(busName, slbusObj);
end

%endfunction

% LocalWords:  nx
