% Copyright (C) 2013-2015 Czech Technical University in Prague
%
% Authors:
%     - Carlos Jenkins <carlos@jenkins.co.cr>
%
% Permission is hereby granted, free of charge, to any person
% obtaining a copy of this software and associated documentation
% files (the "Software"), to deal in the Software without
% restriction, including without limitation the rights to use,
% copy, modify, merge, publish, distribute, sublicense, and/or sell
% copies of the Software, and to permit persons to whom the
% Software is furnished to do so, subject to the following
% conditions:

% The above copyright notice and this permission notice shall be
% included in all copies or substantial portions of the Software.

% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
% OTHER DEALINGS IN THE SOFTWARE.
%
% File : rpp_make_rtw_hook.m
% Abstract:
%     Build process hooks file.
%
%     This file is hook file that invoke target-specific functions or
%     executables at specified points in the build process. In particular, this
%     file handle the copying of required files before the compilation stage.
%
% References:
%     rtw_ug.pdf p. 1066-1072 and 1131

function rpp_make_rtw_hook(hookMethod, modelName, rtwRoot, templateMakefile, ...
                           buildOpts, buildArgs)

    switch hookMethod
        case 'error'
            % Called if an error occurs anywhere during the build. If no error
            % occurs during the build, then this hook will not be called. Valid
            % arguments at this stage are hookMethod and modelName. This enables
            % cleaning up any static or global data used by this hook file.
            disp(['### Build procedure for model: ''', modelName, ...
                  ''' aborted due to an error.']);


        case 'entry'
            % Called at start of code generation process (before anything
            % happens).
            % Valid arguments at this stage are hookMethod, modelName, and
            % buildArgs.

            % FIXME: Implement step integrity verification?


        case 'before_tlc'
            % Called just prior to invoking TLC Compiler (actual code
            % generation).
            % Valid arguments at this stage are hookMethod, modelName, and
            % buildArgs.


        case 'after_tlc'
            % Called just after to invoking TLC Compiler (actual code
            % generation).
            % Valid arguments at this stage are hookMethod, modelName, and
            % buildArgs.

            % FIXME: Implement model tasking mode check?


        case 'before_make'
            % Called after code generation is complete, and just prior to
            % kicking off make process (assuming code generation only is not
            % selected). All arguments are valid at this stage.

            % Copy extra runtime header to code generation directory
            copyfile(fullfile(getpref('rpp', 'TargetRoot'), 'rpp_simulink_runtime.h'));

            % Copy extra makefiles and library files to code generation
            % directory
            rpp_write_makefiles(modelName);


        case 'after_make'
			% Called after make process is complete. All arguments are valid at
            % this stage.

            % Download generated binary to the board
            rpp_do_download(modelName);


        case 'exit'
            % Called at the end of the build process.  All arguments are valid
            % at this stage.
            disp(['### Successful completion of build ', ...
                  'procedure for model: ', modelName]);

    end
end


function rpp_write_makefiles(modelName)

    modelRoot = Simulink.fileGenControl('getConfig').CodeGenFolder;
    buildFolder = fullfile(modelRoot, 'slprj');

    % Get configuration variables and create paths configuration makefile
    CompilerRoot = getpref('rpp', 'CompilerRoot');
    CCSRoot      = getpref('rpp', 'CCSRoot');
    TargetRoot   = getpref('rpp', 'TargetRoot');
    RppLibRoot   = getpref('rpp', 'RppLibRoot');

    TargetPaths = fullfile(buildFolder, 'target_paths.mk');

    fid = fopen(TargetPaths, 'w');
    fwrite(fid, sprintf('%s\n\n', '# RPP paths'));
    fwrite(fid, sprintf('COMPILER_ROOT = %s\n', CompilerRoot));
    fwrite(fid, sprintf('CCS_ROOT      = %s\n', CCSRoot));
    fwrite(fid, sprintf('TARGET_ROOT   = %s\n', TargetRoot));
    fwrite(fid, sprintf('RPP_LIB_ROOT  = %s\n', RppLibRoot));
    fclose(fid);

    % Copy the RPP version of target_tools.mk into the build area
    tgtToolsFile = 'target_tools.mk';
    copyfile(fullfile(TargetRoot, tgtToolsFile), ...
             fullfile(buildFolder, tgtToolsFile));

end


function rpp_do_download(modelName)
    if verLessThan('matlab', '8.1')
        makertwObj = get_param(gcs, 'MakeRTWSettingsObject');
		makertwBuildDirectory = makertwObj.BuildDirectory;
		makertwArgs = makertwObj.BuildInfo.BuildArgs;
	else
		makertwObj = rtwprivate('get_makertwsettings', gcs, 'BuildInfo');
		makertwBuildDirectory = rtwprivate('get_makertwsettings', gcs, 'BuildDirectory');
		makertwArgs = makertwObj.BuildArgs;
    end

    % Check if user choose to Download to RPP board in Settings
    download = 0;
	use_openocd = 0;
	use_sdram = 0;
    for i=1:length(makertwArgs)
        if strcmp(makertwArgs(i).DisplayLabel, 'RPP_DOWNLOAD')
            download = str2double(makertwArgs(i).Value);
        elseif strcmp(makertwArgs(i).DisplayLabel, 'RPP_USE_OPENOCD')
            use_openocd = str2double(makertwArgs(i).Value);
        elseif strcmp(makertwArgs(i).DisplayLabel, 'RPP_DOWNLOAD_TO_SDRAM')
            use_sdram = str2double(makertwArgs(i).Value);
        end
    end

    if download
        if getenv('RPP_NO_DOWNLOAD')
            disp(['RPP_NO_DOWNLOAD defined - skipping downloading to target.'])
        else
            rpp_download(modelName, makertwBuildDirectory, use_openocd, use_sdram);
        end
    end

end
