% mff_importevents - import information from MFF 'eventsxxxxx.xml'
%                    files. If several files are detected, information
%                    from all files is imported.
%
% Usage:
%   [events, timezone] = mff_importevents(mffFile, begTime, srate, correctevents);
%
% Inputs:
%  mffFile - filename/foldername for the MFF file
%  begTime - [float] time onset of the experiment
%  srate   - [float] sampling rate
%  correctevents - [0|1] correct (overwrite) event files who have special
%                  characters and cannot be imported by the Java library
%                  (default is 0 or false)
%
% Output:
%  events   - EEGLAB event structure
%  timezone - time zone

% This file is part of mffmatlabio.
%
% mffmatlabio 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
% (at your option) any later version.
%
% mffmatlabio 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 mffmatlabio.  If not, see <https://www.gnu.org/licenses/>.

function [events, timeZone] = mff_importevents(mffFile, begTime, srate, correctEvents)

events = [];
timeZone = [];
mff_path;

if nargin < 4
    correctEvents = false;
end

% create a factory
mfffactorydelegate = javaObject('com.egi.services.mff.api.LocalMFFFactoryDelegate');
mfffactory = javaObject('com.egi.services.mff.api.MFFFactory', mfffactorydelegate);

% Create Signal object and read in event track file.
% Note that 3 is the value associated with the event track resource type.
eventFile = dir( fullfile(mffFile, 'Events_*.xml'));
if isempty(eventFile), return; end
timeZone = [];
eventCount = 1;
showWarning = true;

% use vararg2str to save events so they may be exported
eeglabExport = true;
if ~exist('vararg2str', 'file')
    eeglabExport = false;
end

for iEvent = 1:length(eventFile)

    if eventFile(iEvent).bytes == 0
        fprintf(2, 'Empty event file detected %s\n', fullfile( eventFile(iEvent).folder, eventFile(iEvent).name));
        continue
    end
    eventtrackfilename = fullfile( eventFile(iEvent).folder, eventFile(iEvent).name);

    if correctEvents
        disp('Overwriting event files and removing special characters');
        fixcharabove128(eventtrackfilename);
    end
    
    eventtracktype = javaObject('com.egi.services.mff.api.MFFResourceType', javaMethod('valueOf', 'com.egi.services.mff.api.MFFResourceType$MFFResourceTypes', 'kMFF_RT_EventTrack'));
    eventtrackObj = mfffactory.openResourceAtURI(eventtrackfilename, eventtracktype);

    % scan file and rewrite special characters
    
    try
        res = eventtrackObj.loadResource();
    catch
        error('Error loading event file. Try calling the function pop_mffimport from the command line and set the option to correct events.');
    end
    if res
        
        name      = eventtrackObj.getName();
        trackType = eventtrackObj.getTrackType();
        eventlist = eventtrackObj.getEvents();
        nevents = eventlist.size();
        fprintf('Importing %d events from file %s...\n', nevents, eventFile(iEvent).name);
        
        % Read through each event track and inspect count of events
        % and beginTime for last event in each.
        if nevents>0

            multiplier = 24*60*60*srate;
            events(nevents).description = ''; % create last event
            
            for eventnum = 1:nevents
                
                eventObj = eventlist.get(eventnum-1);
                
                % Get keys for event and display key codes
                events(eventCount).begintime    = char(eventObj.getBeginTime());
                if events(eventCount).begintime(end-1) == '-'
                    events(eventCount).begintime = [ events(eventCount).begintime(1:end-1) '0' events(eventCount).begintime(end) ':00' ];
                elseif events(eventCount).begintime(end-2) == '-'
                    events(eventCount).begintime = [ events(eventCount).begintime(1:end-2) events(eventCount).begintime(end) ':00' ];
                end
                events(eventCount).classid      = char(eventObj.getClassID());
                events(eventCount).code         = char(eventObj.getCode());
                events(eventCount).description  = char(eventObj.getDescription());
                events(eventCount).duration     = eventObj.getDuration();
                events(eventCount).label        = char(eventObj.getLabel());
                events(eventCount).relativebegintime = eventObj.getRelativeBeginTime();
                events(eventCount).sourcedevice = char(eventObj.getSourceDevice());
                events(eventCount).name         = char(name);
                events(eventCount).tracktype    = char(trackType);
                
                % compute latency in days with ms -> convert to samples
                % eventCount = 1; 
                if events(eventCount).relativebegintime > 0 % for data epochs, this is required
                    events(eventCount).latency = events(eventCount).relativebegintime / 1000000 * srate;
                    % see bug 44, STAT events are supposed to be 42 ms
                    % before the time locking events, this fixes the problem
                else
                    events(eventCount).latency = (mff_decodetime(events(eventCount).begintime)-begTime)*multiplier;
                end

                % dual time recoding
%                 tmp = mff_encodetime(events(eventCount).latency/multiplier+begTime, '08:00')
%                 fprintf('%s\n%s\n', events(eventCount).begintime, tmp);
                
                events(eventCount).type    = events(eventCount).code;
                
                % import keys
                keylist = eventObj.getKeys();
                events = mff_importkeys(events, eventCount, keylist, eeglabExport);
                
                eventCount = eventCount+1;
                
            end
        end
    else
        fprintf('Could not load event file %s\n', eventtrackfilename);
    end
end
if ~isempty(events)
    % get the time zone (duplicate code in mff_importevents and mff_importinfo)
    minusSign = find(events(end).begintime == '+');
    if isempty(minusSign)
        minusSign = find(events(end).begintime == '-');
        minusSign = minusSign(end);
    end
    timeZone = events(end).begintime(minusSign(end):end);
    if length(timeZone) > 6
        timeZone =  [];
        disp('Issue with decoding the time zone');
    end
end

% % same as above but 10% faster. Was not retained because the increased
% % complexitity. Does not support importing keys
% 
% begintime         = cell(1,eventcount);
% classid           = cell(1,eventcount);
% code              = cell(1,eventcount);
% description       = cell(1,eventcount);
% duration          = cell(1,eventcount);
% label             = cell(1,eventcount);
% relativebegintime = cell(1,eventcount);
% sourcedevice      = cell(1,eventcount);
% eventkeys         = cell(1,eventcount);
% for eventnum = 1:eventcount
% 
%     eventObj = eventlist.get(eventnum-1);
%     
%     % Get keys for event and display key codes
%     begintime{eventnum}    = eventObj.getBeginTime();
%     classid{eventnum}      = eventObj.getClassID();
%     code{eventnum}         = eventObj.getCode();
%     description{eventnum}  = eventObj.getDescription();
%     duration{eventnum}     = eventObj.getDuration();
%     label{eventnum}        = eventObj.getLabel();
%     relativebegintime{eventnum} = eventObj.getRelativeBeginTime();
%     sourcedevice{eventnum} = eventObj.getSourceDevice();
%     eventkeys{eventnum}    = eventObj.getKeys();
%     
% end
% 
% disp('Converting events to Matlab format...')
% begintime    = cellfun(@(x)char(x), begintime, 'uniformoutput', false);
% begintime2   = cellfun(@(x)mff_decodetime(x), begintime, 'uniformoutput', false);
% classid      = cellfun(@(x)char(x), classid, 'uniformoutput', false);
% code         = cellfun(@(x)char(x), code, 'uniformoutput', false);
% description  = cellfun(@(x)char(x), description, 'uniformoutput', false);
% label        = cellfun(@(x)char(x), label, 'uniformoutput', false);
% relativebegintime = cellfun(@(x)char(x), relativebegintime, 'uniformoutput', false);
% sourcedevice = cellfun(@(x)char(x), sourcedevice, 'uniformoutput', false);
% eventkeys    = cellfun(@(x)char(x), eventkeys, 'uniformoutput', false);
% 
% events = struct('begintime', begintime, 'latency', begintime2, 'classid', classid, 'code', code, 'description', description, ...
%                 'label', label, 'relativebegintime', relativebegintime, 'sourcedevice', sourcedevice, 'eventkeys', eventkeys);

% Save as above but not faster
% eventlist = eventlist.toArray;
% eventlist = cell(eventlist);
% 
% begintime    = cellfun(@(x)char(x.getBeginTime()), eventlist, 'uniformoutput', false);
% begintime2   = cellfun(@(x)mff_decodetime(x), begintime, 'uniformoutput', false);
% classid      = cellfun(@(x)char(x.getClassID()), eventlist, 'uniformoutput', false);
% code         = cellfun(@(x)char(x.getCode()), eventlist, 'uniformoutput', false);
% description  = cellfun(@(x)char(x.getDescription()), eventlist, 'uniformoutput', false);
% label        = cellfun(@(x)char(x.getLabel()), eventlist, 'uniformoutput', false);
% sourcedevice = cellfun(@(x)char(x.getSourceDevice()), eventlist, 'uniformoutput', false);
% eventkeys    = cellfun(@(x)char(x.getKeys()), eventlist, 'uniformoutput', false);
% 
% relativebegintime = cellfun(@(x)x.getRelativeBeginTime(), eventlist, 'uniformoutput', false);
% duration          = cellfun(@(x)x.getDuration(), eventlist, 'uniformoutput', false);
% 
% events = struct('begintime', begintime, 'latency', begintime2, 'classid', classid, 'code', code, 'type', code, 'description', description, ...
%                 'label', label, 'duration', duration, 'relativebegintime', relativebegintime, 'sourcedevice', sourcedevice, 'eventkeys', eventkeys);

function fixcharabove128(fileName1)

fileName2 = [ fileName1 'x' ];
fid1 = fopen(fileName1, 'r');
fid2 = fopen(fileName2, 'w');
if fid1 == -1, error('Cannot open file %s', fileName1); end
if fid2 == -1, error('Cannot open file %s', fileName2); end

while ~feof(fid1)
    str = fgetl(fid1);
    str(str > 128) = ' ';
    fprintf(fid2, '%s\n', str);
end
fclose(fid1);
fclose(fid2);
delete(fileName1);
copyfile(fileName2, fileName1);
delete(fileName2);

