function generatedFiles = plc_postcg_callback_keba(fileName)

%   Copyright 2012 The MathWorks, Inc.

% PostCG call back file for KEBA IedEdit
if ischar(fileName)
    fileName = {fileName};
end

for j = 1: length(fileName)
    
    outputDir = getOutputDir(fileName{j});
    if ~exist(outputDir, 'dir')
        mkdir(outputDir);
    end
    
    str = fileread(fileName{j});
    
    % Remove empty definitions
    str = regexprep(str,'VAR\s+END_VAR','');
    str = regexprep(str,'VAR_TEMP\s+END_VAR','');
    str = regexprep(str,'VAR_GLOBAL\s+END_VAR','');
    str = regexprep(str,'VAR_INPUT\s+END_VAR','');
    str = regexprep(str,'VAR_GLOBAL CONSTANT\s+END_VAR','');
    
    % Replace TRUNC to TRUNC_TO_DINT
    str = regexprep(str,'TRUNC','TRUNC_TO_DINT');
    
    % Replace ARRAY with Type Name and save Types in a *.tu file
    strtemp = regexpi(str,'ARRAY\s\[\d+\.\.\d+\]\sOF\s\w+\W','match');
    [str, typeFileName] = replaceArraykeywordWithVarName(str,strtemp,fileName{j},outputDir);
    
    varGlobalStr = getSection(str, 'VAR_GLOBAL', 'END_VAR');
    
    if ~isempty(varGlobalStr)
        varGlobalStr = strrep(varGlobalStr, 'VAR_GLOBAL', 'VAR_EXTERNAL');
        varGlobalStr = regexprep(varGlobalStr,' :=[^;]+;',';');
        varGlobalStr = sprintf(['\n' varGlobalStr]);
    end
    
    str = functionBlockToAlgorithm(str);
    
    strnew = separateoutFunctionBlock(str);
    
    strnew = modifyFunctionBlock(strnew, varGlobalStr);
    
    generatedFiles = dump2file(strnew,outputDir);
    
    generatedFiles{end + 1} = typeFileName; %#ok<AGROW>
    %     str = concatBlocks(strnew);
end
end

function outputDir = getOutputDir(fileName)
[stOutputDir, folderName] = fileparts(fileName);
outputDir = fullfile(stOutputDir, folderName);
end

function [str, typeFileName] = replaceArraykeywordWithVarName(str, strtemp, fileName, outputDir)
% Replace Array Keyword to Variable Type Name
strTU = '';
if isempty(strtemp)~=1
    for i=1:length(strtemp)
        repstr = ['Array_Type_Var',num2str(i)];
        str = regexprep(str,'ARRAY\s\[\d+\.\.\d+\]\sOF\s\w+\W',repstr,'once');
        % Add ARRAY_TYPE into a *.tu file
        strTU = strcat(strTU,sprintf('\nTYPE\n\t%s:%s;\nEND_TYPE',repstr,strtemp{1,i}(1:end-1)));
    end
end
loc_start = regexp(str,'TYPE');
loc_end  = regexp(str,'END_TYPE');
if ~isempty(loc_end)
    loc_start = loc_start(1:2:end);
    for i=1:length(loc_end)
        strTU = sprintf('%s\n%s',strTU,str(loc_start(i):loc_end(i)+7));
    end
end

varGlobalConstantStr = getSection(str, 'VAR_GLOBAL CONSTANT', 'END_VAR');
str = strrep(str, 'VAR_GLOBAL CONSTANT', '----');

if ~isempty(varGlobalConstantStr)
    varGlobalConstantStr = strrep(varGlobalConstantStr, 'VAR_GLOBAL ', '');
    varGlobalConstantStr = strrep(varGlobalConstantStr, 'END_VAR', 'END_CONSTANT');
    strTU = sprintf([strTU '\n' varGlobalConstantStr]);
end

[~, typeFileName, ~] = fileparts(fileName);
typeFileName = [typeFileName, '.tu_iec'];
typeFileName = fullfile(outputDir, typeFileName);

sfprivate ('str2file',strTU, typeFileName);

end

function str = functionBlockToAlgorithm(str)

str = regexprep(str, '\sFUNCTION_BLOCK ', 'START_OF_BLOCKFUNCTION_BLOCK ');
str = regexprep(str, '\sEND_FUNCTION_BLOCK\s', '#END_EDIT_BLOCK\nEND_FUNCTION_BLOCKEND_OF_BLOCK ');
str = regexprep(str, '\sFUNCTION\s', 'START_OF_BLOCKFUNCTION ');
str = regexprep(str, '\sEND_FUNCTION\s', '#END_EDIT_BLOCK\nEND_FUNCTIONEND_OF_BLOCK ');

end

function strnew  = separateoutFunctionBlock(str)

loc_start = regexp(str,'START_OF_BLOCK','end');
loc_end   = regexp(str,'END_OF_BLOCK');

if ~isempty(loc_end)
    for i = 1:length(loc_end)
        strnew{i} = sprintf('%s',str(loc_start(i)+1:loc_end(i)-1));
    end
end
end

function strnew =  modifyFunctionBlock(strnew, varGlobalStr)
for i=1:length(strnew)
    functionBlockStr = strnew{i};
    
    if ~isempty(regexp(functionBlockStr,'FUNCTION_BLOCK', 'once'))
        functionBlockStr = regexprep(functionBlockStr,'\n','\n#DUMMY_EDIT_BLOCK\n','once');
    end
    
    if ~isempty(regexp(functionBlockStr, '\s+VAR\s+', 'once'))
        functionBlockStr = regexprep(functionBlockStr, 'END_VAR\s+VAR_TEMP', '');
    else
        functionBlockStr = regexprep(functionBlockStr, 'VAR_TEMP','VAR');
    end
    
    strnew{i} = functionBlockStr;
    loc =  regexp(functionBlockStr,'END_VAR');
    if ~isempty(loc)
        if ~isempty(regexp(functionBlockStr,'FUNCTION_BLOCK', 'once'))
            strnew{i} = sprintf('%sEND_VAR%s\n#BEGIN_EDIT_BLOCK%s', functionBlockStr(1:loc(end)-1), varGlobalStr, functionBlockStr(loc(end)+8:end));
        else
            % this is a FUNCTION
            strnew{i} = sprintf('%sEND_VAR\n#BEGIN_EDIT_BLOCK%s', functionBlockStr(1:loc(end)-1), functionBlockStr(loc(end)+8:end));
        end
    end
end
end

function str = concatBlocks(strnew)
str = '';
for i= length(strnew) : -1 : 1
    str = sprintf([str '\n' strnew{i}]);
end

str = sprintf(['ALGORITHM_BLOCK PLC_PRG\n' ...
    '#DUMMY_EDIT_BLOCK\n\n' ...
    str ...
    '\n' ...
    'END_ALGORITHM_BLOCK']);
end

function sectionStr = getSection(str, startStr, stopStr)
sectionStr = '';
startLoc = strfind(str, startStr);
if ~isempty(startLoc)
    subStr = str(startLoc(1) : end);
    endLoc = strfind(subStr, stopStr);
    if ~isempty(endLoc)
        sectionStr = subStr(1 : (endLoc(1) + length(stopStr) - 1));
    end
end
end

function functionFileNames = dump2file(strnew, outputDir)
for i=1:numel(strnew)
    temp = regexp(strnew{i},'FUNCTION_BLOCK (\w*)','tokens');
    if isempty(temp)
        temp = regexp(strnew{i},'FUNCTION (\w*)','tokens');
    end
    functionBlockName = temp{1};
    functionFileName = sprintf('%s.pu_iec', functionBlockName{1});
    functionFileName = fullfile(outputDir, functionFileName);
    sfprivate ('str2file',strnew{i},functionFileName);
    functionFileNames{i} = functionFileName; %#ok<AGROW>
end
end

% LocalWords:  Ied TRUNC tu strnew iec BLOCKFUNCTION BLOCKEND FUNCTIONEND PRG
% LocalWords:  pu
