function dat = dspace2struct(filename,version,alternative_struct_name)
% ------------------------------------------------
% dat = dspace2struct(dspacename,version)
% Function to export dSPACE-mat-file to Matlab struct.
% The fieldnames of the struct are the same as the dSPACE-signalnames.
% ------------------------------------------------
% Output:
% dat ... matlab struct
%
% Input:
% filename ... (optional) .mat-File generated by dSPACE (string) (
% version ... (optional) version = 'NG' if using dSpace Next Genertion
% alternative_struct_name ...(optional) needed if structname is different
% from filename. Often caused by renaming .mat
% files after saving.
%
% author: Alexander Michel
% date: 2010/08/09
%
% changes: - 2011/06/29 Alexander Michel: - customized for dSpace Next
% Generation data structure
% - 2011/07/29 Alexander Michel: - GUI added when no file is
% provided
% - Path can be provided
% - 2012/05/02 Alexander Michel: - Bug fixing for dSpace NG naming
% of calculations
% - Multiple XData for dSpace NG
% added
% - 2013/06/17 Alexander Michel: - Array out for dSpace NG support
% added
% - 2013/07/11 Alexander Michel: - alternative structname support
%
% Copyright 2012 Thomas König, Alexander Michel
%
% This file is part of NumericPlots.
%
% NumericPlots is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% any later version.
%
% NumericPlots is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with NumericPlots. If not, see <http://www.gnu.org/licenses/>.

if(nargin<1 || strcmp(filename,''))
[fname datapath] = uigetfile('*.mat','choose .mat-file generated by dSPACE');
filename = fullfile(datapath, fname);
if isequal(fname,0) || isequal(datapath,0)
disp('User pressed cancel')
return;
else
disp(['User selected ', filename])
end
end

if(isempty(strfind(filename,'\')))
idx1name = 1;
else
idxes = strfind(filename,'\');
idx1name = idxes(end)+1;
end

if(nargin>2)
dspacename = alternative_struct_name;
else
if(isempty(strfind(filename,'.mat')))
dspacename = filename(idx1name:end);
else
dspacename = filename(idx1name:end-4);
end
end

if(nargin<2)
version = 'OG';
end

load(filename);

dspace = eval(genvarname(dspacename));
if(strcmp(version,'NG'))
for ii = 1:length(dspace.X)
dat.time{ii} = dspace.X(ii).Data;
end
else
dat.time = dspace.X.Data;
end
validx = [];
for ii = 1:length(dspace.Y)
if(strcmp(version,'NG'))
if(isempty(dspace.Y(ii).Path))
newfieldname = dspace.Y(ii).Name;
else
stridx = strfind(dspace.Y(ii).Path,'/');
newfieldname = dspace.Y(ii).Path(stridx(end)+1:end);
end
else
stridx = strfind(dspace.Y(ii).Name,'"');
lastname = dspace.Y(ii).Name(stridx(end-1)+1:stridx(end)-1);
stridxM1 = strfind(lastname,'[');
if(~isempty(stridxM1))
stridxM2 = strfind(lastname,']');
if(~isempty(stridxM2))
validx = sscanf(lastname(stridxM1:stridxM2),'[%i,%i]');
possiblefieldname = lastname(1:stridxM1-1);
end
else
possiblefieldname = lastname;
end
if(isempty(strfind(possiblefieldname,'In1')) && isempty(strfind(possiblefieldname,'Out1')))
newfieldname = possiblefieldname;
else
newfieldname = dspace.Y(ii).Name(stridx(end-3)+1:stridx(end-2)-1);
end
end
if(isvarname(newfieldname) == 0)
newfieldname = newfieldname(isstrprop(newfieldname,'alphanum'));
if(isvarname(newfieldname) == 0)
newfieldname = newfieldname(2:end);
end
end
if(strcmp(version,'NG'))
if(isfield(dat,newfieldname))
dat.(newfieldname).Data = [dat.(newfieldname).Data; dspace.Y(ii).Data];
else
dat.(newfieldname).Data = dspace.Y(ii).Data;
end
dat.(newfieldname).timeidx = dspace.Y(ii).XIndex;
else
if(isempty(validx))
dat.(newfieldname) = dspace.Y(ii).Data;
else
dat.(newfieldname){validx(2)} = dspace.Y(ii).Data;
validx = [];
end
end
end
if(~strcmp(version,'NG'));
dat.dSPACESettings.Capture = dspace.Capture;
dat.dSPACESettings.Description = dspace.Description;
dat.dSPACESettings.RTProgram = dspace.RTProgram;
end