function [outData] = commSISOChannelTransform(inData)
%COMMSISOCHANNNELTRANSFORM Transform function from Multipath Rayleigh
%   Fading Channel and Multipath Rician Fading Channel blocks to SISO
%   Fading Channel block.

% Copyright 2017-2018 The MathWorks, Inc.

%#ok<*AGROW>
InstanceData = inData.InstanceData;
oldBlockParams = {InstanceData.Name};

% Figure out Rayleigh or Rician
[~, paramIdx] = find(strcmp('K', oldBlockParams));
if isempty(paramIdx)
    fadingDist = 'Rayleigh';
else
    fadingDist = 'Rician';
end

outData.NewInstanceData = struct( ...
    'Name',  'FadingDistribution', ...
    'Value', fadingDist);

% Direct parameter mapping from old to new block
paramMap = ... 
    ... % Old block param       New block param
    {'avgPathGaindB',           'AveragePathGains'; ...
     'pathDelays',              'PathDelays'; ...
     'normalizePathGains',      'NormalizePathGains'; ...
     'maxDopplerShift',         'MaximumDopplerShift'; ...
     'seed',                    'Seed'; ...
     'outPathGains',            'PathGainsOutputPort'; ...
     'outDelay',                'ChannelFilterDelayOutputPort'; ...
     'K',                       'KFactor'; ...
     'fdLOS',                   'DirectPathDopplerShift'; ...
     'thetaLOS',                'DirectPathInitialPhase'};
     
for i = 1:size(paramMap, 1)
    [~, paramIdx] = find(strcmp(paramMap{i,1}, oldBlockParams));
    if ~isempty(paramIdx) 
        outData.NewInstanceData(end+1) = struct( ...
            'Name',  paramMap{i,2}, ...
            'Value', InstanceData(paramIdx).Value);
    end    
end

% Map visualization parameter from old to new block
[~, paramIdx] = find(strcmp('openVisAtStart', oldBlockParams));
if ~isempty(paramIdx) && strcmp(InstanceData(paramIdx).Value, 'on')
    outData.NewInstanceData(end+1) = struct( ...
        'Name',  'Visualization', ...
        'Value', 'Impulse and frequency responses');
end

% Map Doppler parameters from old to new block
[~, paramIdx] = find(strcmp('spectrumType', oldBlockParams));
if ~isempty(paramIdx)
    switch InstanceData(paramIdx).Value
      case 'Jakes'
        dopSpectrum = 'doppler(''Jakes'')';
      case 'Flat' 
        dopSpectrum = 'doppler(''Flat'')';
      case 'Gaussian'
        [~, tmpIdx] = find(strcmp('sigmaGaussian', oldBlockParams));          
        dopSpectrum = ['doppler(''Gaussian'', ', InstanceData(tmpIdx).Value, ')'];
      case 'Rounded'
        [~, tmpIdx] = find(strcmp('coeffRounded', oldBlockParams));          
        dopSpectrum = ['doppler(''Rounded'', ', InstanceData(tmpIdx).Value, ')'];
      case 'Restricted Jakes'
        [~, tmpIdx] = find(strcmp('freqMinMaxRJakes', oldBlockParams));          
        dopSpectrum = ['doppler(''Restricted Jakes'', ', InstanceData(tmpIdx).Value, ')'];
      case 'Asymmetrical Jakes'
        [~, tmpIdx] = find(strcmp('freqMinMaxAJakes', oldBlockParams));          
        dopSpectrum = ['doppler(''Asymmetric Jakes'', ', InstanceData(tmpIdx).Value, ')'];
      case 'Bi-Gaussian'
        dopSpectrum = 'doppler(''BiGaussian'', ''NormalizedStandardDeviations'', [';
        [~, tmpIdx] = find(strcmp('sigmaGaussian1', oldBlockParams));          
        dopSpectrum = [dopSpectrum, InstanceData(tmpIdx).Value, ', ']; 
        [~, tmpIdx] = find(strcmp('sigmaGaussian2', oldBlockParams));
        dopSpectrum = [dopSpectrum, InstanceData(tmpIdx).Value, '], ''NormalizedCenterFrequencies'', [']; 
        [~, tmpIdx] = find(strcmp('centerFreqGaussian1', oldBlockParams));          
        dopSpectrum = [dopSpectrum, InstanceData(tmpIdx).Value, ', ']; 
        [~, tmpIdx] = find(strcmp('centerFreqGaussian2', oldBlockParams));
        dopSpectrum = [dopSpectrum, InstanceData(tmpIdx).Value, '], ''PowerGains'', [']; 
        [~, tmpIdx] = find(strcmp('gainGaussian1', oldBlockParams));          
        dopSpectrum = [dopSpectrum, InstanceData(tmpIdx).Value, ', ']; 
        [~, tmpIdx] = find(strcmp('gainGaussian2', oldBlockParams));
        dopSpectrum = [dopSpectrum, InstanceData(tmpIdx).Value, '])'];
      case 'Bell'
        [~, tmpIdx] = find(strcmp('coeffBell', oldBlockParams));          
        dopSpectrum = ['doppler(''Bell'', ', InstanceData(tmpIdx).Value, ')'];        
      case 'Specify as dialog parameter'
        [~, tmpIdx] = find(strcmp('dopplerSpectrum', oldBlockParams)); 
        oldDopSpectrum = InstanceData(tmpIdx).Value;
        dopSpectrum = convertDopObjVector(oldDopSpectrum);
    end
    
    outData.NewInstanceData(end+1) = struct( ...
        'Name',  'DopplerSpectrum', ...
        'Value', dopSpectrum);
end

outData.NewBlockPath = inData.ForwardingTableEntry.('__slOldName__');

end

function dopplerStruct = convertDopObjVector(dopplerObj)
% Convert Doppler object row vector into Doppler structure cell array

s = strfind(dopplerObj, 'doppler.');

isSingleDopObj = (length(s) == 1); % One Doppler object or not

s(end+1) = length(dopplerObj)+1;
dopplerStruct = '';
for i = 1:length(s)-1
    switch dopplerObj(s(i)+(8:11))
        case 'jake' % Jakes
            dopplerStruct = [dopplerStruct, 'doppler(''Jakes''),'];
        case 'flat' % Flat
            dopplerStruct = [dopplerStruct, 'doppler(''Flat''),']; 
        case 'gaus' % Gaussian
            dopplerStruct = [dopplerStruct, ...
                formulateDopplerStruct('Gaussian', dopplerObj(s(i):s(i+1)-1))];
        case 'roun' % Rounded
            dopplerStruct = [dopplerStruct, ...
                formulateDopplerStruct('Rounded', dopplerObj(s(i):s(i+1)-1))];
        case 'rjak' % Restricted Jakes
            dopplerStruct = [dopplerStruct, ...
                formulateDopplerStruct('Restricted Jakes', dopplerObj(s(i):s(i+1)-1))];
        case 'ajak' % Asymmetric Jakes
            dopplerStruct = [dopplerStruct, ...
                formulateDopplerStruct('Asymmetric Jakes', dopplerObj(s(i):s(i+1)-1))];
        case 'bell' % Bell
            dopplerStruct = [dopplerStruct, ...
                formulateDopplerStruct('Bell', dopplerObj(s(i):s(i+1)-1))];
        case 'biga' % Bi-Gaussian
            dopplerStruct = [dopplerStruct, 'doppler(''BiGaussian'''];
            % Retrieve P-V pairs
            paramStr = lower(dopplerObj(s(i)+18:s(i+1)-1));
            allP = regexp(paramStr, '['']\w*['']', 'match');
            allP = cellfun(@(x)(x(2:end-1)), allP, 'UniformOutput', false);
            allV  = regexp(paramStr, '[,].*?[,)]', 'match');
            allV = cellfun(@(x)(x(2:end-1)), allV, 'UniformOutput', false);
            % Formulate Doppler structure inputs
            pos1 = find(strcmp(allP, 'sigmagaussian1'));
            pos2 = find(strcmp(allP, 'sigmagaussian2'));
            if ~isempty(pos1) || ~isempty(pos2)
                dopplerStruct = [dopplerStruct, ', ''NormalizedStandardDeviations'', ['];
                if ~isempty(pos1)
                    dopplerStruct = [dopplerStruct, allV{pos1}];
                else
                    dopplerStruct = [dopplerStruct, '1/sqrt(2)'];
                end
                if ~isempty(pos2)
                    dopplerStruct = [dopplerStruct, ', ', allV{pos2}, ']'];
                else
                    dopplerStruct = [dopplerStruct, ', 1/sqrt(2)]'];
                end
            end
            pos1 = find(strcmp(allP, 'centerfreqgaussian1'));
            pos2 = find(strcmp(allP, 'centerfreqgaussian2'));
            if ~isempty(pos1) || ~isempty(pos2)
                dopplerStruct = [dopplerStruct, ', ''NormalizedCenterFrequencies'', ['];
                if ~isempty(pos1)
                    dopplerStruct = [dopplerStruct, allV{pos1}];
                else
                    dopplerStruct = [dopplerStruct, '0'];
                end
                if ~isempty(pos2)
                    dopplerStruct = [dopplerStruct, ', ', allV{pos2}, ']'];
                else
                    dopplerStruct = [dopplerStruct, ', 0]'];
                end
            end
            pos1 = find(strcmp(allP, 'gaingaussian1'));
            pos2 = find(strcmp(allP, 'gaingaussian2'));
            if ~isempty(pos1) || ~isempty(pos2)
                dopplerStruct = [dopplerStruct, ', ''PowerGains'', ['];
                if ~isempty(pos1)
                    dopplerStruct = [dopplerStruct, allV{pos1}];
                else
                    dopplerStruct = [dopplerStruct, '0.5'];
                end
                if ~isempty(pos2)
                    dopplerStruct = [dopplerStruct, ', ', allV{pos2}, ']'];
                else
                    dopplerStruct = [dopplerStruct, ', 0.5]'];
                end
            end
            dopplerStruct = [dopplerStruct, '),'];            
    end
end

dopplerStruct(end) = '';

if ~isSingleDopObj
    dopplerStruct = ['{', dopplerStruct, '}'];
end

end

function paramDopStruct = formulateDopplerStruct(type, paramInput)

paramDopStruct = ['doppler(''', type, ''''];
param = regexp(paramInput, '[(].*[)]', 'match');
if ~isempty(param)
    paramDopStruct = [paramDopStruct, ', ', param{1}(2:end-1)];
end
paramDopStruct = [paramDopStruct, '),'];            

end

% [EOF]
