function varargout=dopEventMarks(eventData,varargin)
% dopOSCCI Mark II: dopEventMarks ~ 1-11-2010 (last edit)
%
% find the event/epoch markers in doppler data
%
% varargout=dopTrialMarks(eventData,varargin)
%
% > where eventData is a sample by column by z matrix for each event type/condition/etc.
%   z = 3rd dimension related to each event marker
%
% assume:
% - last point is correct: additional markers may have been erroneously
% added to the start but not the end of the data file.
% - correct markers will be set distance apart - indicated with 'sep' input
% = minimum distance/time between markers.
%
% dopEventMarks work backwards from end of file to find 'epochs' number of
% markers with 'sep' seconds of separation.  Markers with shorter
% separations will be skipped.
%
% Inputs:
% inputs.defaults=struct('epochs',0,... % number of epochs
%         'sep',20,... % minimum separation between trial markers
%         'sample',25); % sample rate of input (to figure out timing)
%         'eventLabels','mark1',...); % names of event channels
%         'evChs',0); % doppler external channel numbers
%         'evType',2,...); % event type: 0 = base, 1 = stim only, 2 = both
%         'evMatch',0);% if event type = 0 or 1, it needs a match for with 1 or 0, only 2 is independent
%
%
% if mismatch between events found in related channels (see dopTaskDef
% evType) then ignores markers from channel with most events.  Ignore is
% based upon between channel marker separations greater than the minimum
% within channel separation range.
%
fprintf('\n%s\n\t%s',['Running ',mfilename],...
    'Searching for event markers:');
try
    inputs.varargin=varargin;
    inputs.defaults=struct('epochs',0,... % number of epochs
        'sep',20,... % minimum separation between trial markers
        'sample',25,... % sample rate of input (to figure out timing)
        'eventLabels','mark1',...); % names of event channels
        'evChs',0,...); % doppler external channel numbers
        'evType',2,...); % event type: 0 = base, 1 = stim only, 2 = both
        'evMatch',1);% if event type = 0 or 1, it needs a match for with 1 or 0, only 2 is independent
    tm=setGetInputsStruct(inputs); % rp = raw process
    
    tm.translation='trial markers';
    tm.structAbbreviations='tm';
    tm.data=eventData; clear eventData
    
    % make sure the data is layed out the way we want
%     tm.ds=size(tm.data); % data size
%     if min(tm.ds)~=tm.ds(2); % want this to be a column
%         tm.data=tm.data'; end % flip it around
    
    tm.nEvs=size(tm.data,3); % just in case there are multiple channels
    if numel(tm.eventLabels)<tm.nEvs
        for i = 1 : tm.nEvs
            tm.eventLabels{i} = ['mark',num2str(i)];
        end
    end
    for i=1:tm.nEvs
        tm.tmp.ev=i; % temp channel
        tm.tmp.evn=tm.eventLabels{i}; % event name
        if iscell(tm.eventLabels)
            tm.tmp.evn=tm.eventLabels{tm.tmp.ev};
        end
        tm.mk.evNames{tm.tmp.ev}=tm.tmp.evn;
        %% figure out separation timing
        tm.sepSamples(tm.tmp.ev)=tm.sep(tm.tmp.ev)/(tm.sample^-1); % separation samples
        
        %% find event makers
        tm.tmp.mks=find(tm.data(:,:,tm.tmp.ev)); % temporary set of markers (number may vary between event channels)
        tm.mk.(tm.tmp.evn).rawMks=tm.tmp.mks'; % keep a record of raw markers
        tm.mk.(tm.tmp.evn).fndMks=length(tm.tmp.mks); % total number found
        tm.mk.(tm.tmp.evn).short=[];
        
        % counter
        tm.tmp.cnt=0;
        
        % tmp marker - based on number of desired markers
        tm.tmp.tm=tm.epochs(tm.tmp.ev);
        
        % search marker - based upon number of available markers
        % > isn't necessary to be out of while loop but will probably help
        % for later understanding of the approach.
        tm.tmp.sm=tm.mk.(tm.tmp.evn).fndMks-tm.tmp.cnt;
        
        tm.tmp.mk=[]; % clear markers
        tm.tmp.mk(tm.tmp.tm)=tm.tmp.mks(tm.tmp.sm); % start with the last point
        %         tm.tmp.cnt=tm.tmp.cnt+1; % update counter
        while tm.tmp.cnt<tm.mk.(tm.tmp.evn).fndMks-1 && tm.tmp.tm>1 % still makers left to examine & find
            tm.tmp.cnt=tm.tmp.cnt+1; % update counter
            tm.tmp.sm=tm.mk.(tm.tmp.evn).fndMks-tm.tmp.cnt; % search marker, next last
            tm.tmp.sep=tm.tmp.mk(tm.tmp.tm)-tm.tmp.mks(tm.tmp.sm);
            % if separation greater than minimum separation...
            if tm.tmp.sep>tm.sepSamples(tm.tmp.ev)
                % we have a suitable marker
                tm.tmp.tm=tm.tmp.tm-1; % next last - when this gets to one, while loop will end
                tm.tmp.mk(tm.tmp.tm)=tm.tmp.mks(tm.tmp.sm);
            else
                fprintf('\t%s\n',['Short marker ',num2str(tm.tmp.sm)]);
                tm.mk.(tm.tmp.evn).short=[tm.mk.(tm.tmp.evn).short tm.tmp.sm];
            end
        end
        %% prepare outputs
        tm.tmp.mk=tm.tmp.mk(~tm.tmp.mk==0); % remove numbers equal to zero
        % put markers into a cell in case of uneven numbers of epochs in
        % the different channels
        tm.mk.(tm.tmp.evn).marks=tm.tmp.mk;
        tm.mk.(tm.tmp.evn).fndEvents=length(tm.tmp.mk);
        
        
        %% > and success report
        tm.mk.(tm.tmp.evn).report=sprintf('%s\n\t%s\n\t%s\n\t%s\n',...
            ['Event channel ',num2str(tm.tmp.ev),' (''',tm.tmp.evn,...
            ''' external channel ',num2str(tm.evChs(tm.tmp.ev)),'):'],...
            ['Found ',num2str(tm.mk.(tm.tmp.evn).fndEvents),...
            ' epochs out of expected ', num2str(tm.epochs(tm.tmp.ev)),'.'],...
            [' - ',num2str(tm.mk.(tm.tmp.evn).fndMks), ' epochs were available:'],...
            [' > mean separation of ',...
            num2str(mean(diff(tm.tmp.mks))*(tm.sample^-1)), ' seconds']);  %,num2str(mean(diff(tm.tmp.mks))) ' samples',...
        fprintf('\n'); % make a line space
        disp(tm.mk.(tm.tmp.evn).report); % display the report
    end
    
    %% event matching
    % when lining up base with stim markers (see dop.def.evType) it will be
    % important to know that these correspond...
    if tm.nEvs>1
        for i=1:tm.nEvs
            if tm.evType(i)<2 %something, therefore not independent
                % event type: 0 = base, 1 = stim only, 2 = both
                tm.matchNames={tm.mk.evNames{i},tm.mk.evNames{tm.evMatch(i)}};
                if length(tm.mk.(tm.matchNames{1}).marks)~=...
                        length(tm.mk.(tm.matchNames{2}).marks)
                    fprintf('\t%s\n','Event number mismatch:',...
                        ['Between ',tm.matchNames{1},' and ',tm.matchNames{2}]);
                    % if separation between different events is greater than
                    % minimum separation within events, assume we missed one.
                    tm.minSep=min(tm.sepSamples([i,tm.evMatch(i)]));
                    
                    [tm.min tm.minInd]=... % max number and max index
                        min([tm.mk.(tm.matchNames{1}).fndEvents tm.mk.(tm.matchNames{2}).fndEvents]);
                    [tm.max tm.maxInd]=... % max number and max index
                        max([tm.mk.(tm.matchNames{1}).fndEvents tm.mk.(tm.matchNames{2}).fndEvents]);
                    tm.dropName=[tm.matchNames{tm.maxInd}];
                    tm.mk.(tm.dropName).drop=[];
                    for j=1:tm.mk.(tm.matchNames{tm.minInd}).fndEvents
                        k=j+length(tm.mk.(tm.dropName).drop);
                        % need to add extras to this if something missing
                        if abs(tm.mk.(tm.matchNames{1}).marks(j)-...
                                tm.mk.(tm.matchNames{2}).marks(k))>tm.minSep
                            tm.mk.(tm.dropName).drop(end+1)=k;
                        end
                    end
                    %% adjust length...hopefully
                    tm.mk.(tm.dropName).marks( tm.mk.(tm.dropName).drop)=[]; % clear marks
                end
            end
        end
    end
    if isfield(tm,'mk');
        varargout{1}=tm.mk;
    else
        varargout{1}=tm;
    end
    fprintf('\t%s\n','Done');
catch err
    %% catch dopOSCCI error
    % 
save(dopOSCCIdebug(mfilename));rethrow(err); 
%     dopOSCCIcrash(err,tm,mfilename);
end

clear tm inputs

