%Load AVL IFile combustion data
%   LOAD_IFILE loads the specified AVL IFile into a MATLAB structure.
%
%   input = LOAD_IFILE(filename,offset_correction)
%
%   Set offset_correction = 0 to prevent cylinder pressure offset
%   correction as specified in the AVL IFile itself.
%
%   Copyright (C) Xarin Limited, 2000-2024
%   All rights reserved.
%
%   Redistribution and use in source and binary forms, with or without
%   modification, are permitted provided that the following conditions are met:
%
%   * Redistributions of source code must retain the above copyright notice, this
%     list of conditions and the following disclaimer.
%
%   * Redistributions in binary form must reproduce the above copyright notice,
%     this list of conditions and the following disclaimer in the documentation
%     and/or other materials provided with the distribution
%   * Neither the name of Xarin Limited nor the names of its
%     contributors may be used to endorse or promote products derived from this
%     software without specific prior written permission.
%
%   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
%   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
%   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
%   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
%   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
%   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
%   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
%   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
%   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
%   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%
%   Version 3.1 (8 October 2024)
%
%   For support and latest version visit www.catool.org
%

function result = load_ifile(filename,offset_correction)

% Determine where executable resides

[pathstr, name, ext] = fileparts(mfilename('fullpath'));

% Check if we are 32 or 64-bit

[~,max_array_size] = computer;
is64bit = max_array_size> 2^31;

% Check if the catool executable is present

if ispc == 1 && exist([ pathstr '\catool.exe'], 'file') ~= 2

	% Download the latest catool executable

	if is64bit
		URL = ['https://catool.org/files/catool-latest-win64.zip'];
	else
		URL = ['https://catool.org/files/catool-latest-win32.zip'];
	end

elseif ismac == 1 && exist([ pathstr '/catool'], 'file') ~= 2

	URL = ['https://catool.org/files/catool-latest-macos.zip'];

elseif isunix == 1 && exist([ pathstr '/catool'], 'file') ~= 2

	if is64bit
		URL = ['https://catool.org/files/catool-latest-linux64.zip'];
	else
		URL = ['https://catool.org/files/catool-latest-linux32.zip'];
	end

else

	URL = '';

end

if ~isempty(URL)

	temp_zipfile = [ tempname '.zip'];

	disp('Downloading latest catool from catool.org...');

	[~,status] = urlwrite(URL, temp_zipfile );

	if status == 1

		% Unzip it where load_ifile.m is located

		disp('Installing latest catool...');

		unzip(temp_zipfile, pathstr);

		% Delete the temporary zip file

		delete(temp_zipfile);

	else

		disp(['It was not possible to automatically download the catool binary.  Please download from ' URL ' and extract the file to the same directory as load_ifile.m']);

	end

end

if nargin == 0
	disp('You must specify the filename of the AVL IFile to load');
	return;
end

if nargin == 1
	offset_correction = 1;
end

% Check if the IFile needs to be unzipped

temp_zipfile = tempname;

try
    zip_result = unzip(filename, temp_zipfile);

    if size(zip_result,2) == 1
        % Substitute filename with unzipped file

        filename = zip_result{1};
        delete_zipfile = 1;
    else
        delete_zipfile = 0;
    end
catch
    delete_zipfile = 0;
end

% Generate unique script name

temp_script = [ tempname '.ccf'];
temp_matfile = [ tempname '.mat'];

[fid,msg] = fopen(temp_script, 'w+');

if fid < 0
    disp(msg);
else
    %   Create script
    fprintf(fid,'debug-level DEBUG\n');
    fprintf(fid,'locale ".utf8"\n');
    fprintf(fid,'input-file-type AVL_IFILE\n');
    fprintf(fid,'input-data ALL\n');
    fprintf(fid,'input-file \"%s\"\n',filename);
    fprintf(fid,'load-channels all\n');
    fprintf(fid,'load-file\n');
    if (offset_correction == 0)
        fprintf(fid,'channel all channel-offset type NONE\n');
    end
    fprintf(fid,'analyse none\n');
    fprintf(fid,'run-analysis\n');
    fprintf(fid,'output-file \"%s\"\n',temp_matfile);
    fprintf(fid,'output-data ALL\n');
    fprintf(fid,'output-file-type MATLAB\n');
    fprintf(fid,'output\n');

    fclose(fid);

	if ispc == 1
		catoolexe = ['"' pathstr '\catool.exe"'];
	else
		catoolexe = ['"' pathstr '/catool"'];
	end

    % Run script

    result = system([catoolexe ' --debug-level=SILENT "' temp_script '"']);

    % Delete temporary config file

    delete(temp_script);

    if result == 0
        % Check if catool generated a MAT file

        fid = fopen(temp_matfile, 'r');

        if fid < 0
            disp('catool has not generated a MAT file');
            result = -1;
        else
            fclose(fid);

            % Load IFile MAT file
            result = load(temp_matfile);

            % Delete temporary MAT file
            delete(temp_matfile);
        end
	else
		disp('catool did not exit successfully');
    end
end

if delete_zipfile == 1
    delete(filename);
end

end
