function callbackKeyPressed(src, eventData)

global tags k t data_file connections
global playing
global auto_play_timer

% disp(['key pressed: ' eventData.Key])
eval(sprintf('trial_length = size(%s,2);',tags{1}));

if eventData.Key == 'c'
    h = findobj(gca,'Tag','pt'); % try to find the old point
    
    if isempty(h)
        warndlg('No point selected');
        return;
    end
    
    old_label = get(h,'UserData');
    new_label = inputdlg(['New label for point ' old_label(3:end)],'Get new label');

    if isempty(char(new_label))
        disp('New tag not set')
        return
    end

    new_label = ['t.' char(new_label)];

    disp(new_label)

    %Copy data to new label
    mask = strcmp(new_label,tags);%Check if label already exists
        
    new_label = char(new_label);

    if ~isempty(find(mask,1))
        %Label already exists
        disp('Found label in tags')
    else
        disp('New label not found, creating')
        tags{end+1} = new_label;
        eval(sprintf('%s = nan(3,%d);',new_label,trial_length));
    end
        
    %Apply replacements with gap tolerance

    %Back in time replacements
    for ki=k:-1:1
        fprintf('ki: %d\n',ki);

        k_current = ki;
        k_next = ki - 1;
        
        overwrite_sucess = overWrite(old_label,new_label,k_current,k_next);
        
        if overwrite_sucess
        else
            break
        end
    end

    %Foward in time replacements
    for ki=k+1:1:trial_length
        fprintf('ki: %d\n',ki);

        k_current = ki;
        k_next = ki + 1;
        
        overwrite_sucess = overWrite(old_label,new_label,k_current,k_next);
        
        if overwrite_sucess
        else
            break
        end
    end

    draw();
    
elseif eventData.Key == 'q'
    links = inputdlg('New connection one link per line','New connection',2);
    
    links = links{1};
    link1 = ['t.' links(1,:)];
    link2 = ['t.' links(2,:)];
    
    link1 = strtrim(link1);
    link2 = strtrim(link2);
    
    if isempty(connections)
        connections = {link1,link2};
    else
        connections = [connections; {link1,link2}];
    end
    draw(); 
    
elseif eventData.Key == 'k'
    %Change k
    k_i = str2double(char(inputdlg('Set iteration','Change iteration')));
    
    if isnan(k_i)
        return
    end
        
    k = max(k_i,1);
    k = min(k,trial_length);
    
    fprintf('k: %d\n',k)
    
elseif strcmp(eventData.Key,'rightarrow') 
    
    if strcmp(eventData.Modifier,'shift')
        k = k + 10;
    elseif strcmp(eventData.Modifier,'control')
        k = k + 100;
    else
        k = k + 1;  
    end
    
    k = min(k,trial_length);
    fprintf('k: %d\n',k)
    draw();
    
elseif strcmp(eventData.Key,'leftarrow')
    
    if strcmp(eventData.Modifier,'shift')
        k = k - 10;
    elseif strcmp(eventData.Modifier,'control')
        k = k - 100;
    else
        k = k - 1;  
    end
    
    k = max(k,1);
    fprintf('k: %d\n',k)
    draw();
    
elseif strcmp(eventData.Key,'l')
    disp(['Loading data in ' data_file])
    load(data_file)
    disp('loaded')
    draw();
    warndlg(data_file,'Loaded data')
    
elseif strcmp(eventData.Key,'s')
    %Save data
    
    disp(['Saving data to ' data_file])
    save(data_file,'tags','t','connections')
    disp('saved')
    warndlg(data_file,'Data Saved')
elseif strcmp(eventData.Key,'f')
    
    %Change camera focus point
    
    %Get the selected point
    h = findobj(gca,'Tag','pt'); % try to find the old point
    
    if ~isempty(h) %Found
%         camlookat(h)
        point(1) = get(h,'XData');
        point(2) = get(h,'YData');
        point(3) = get(h,'ZData');
        
        
%         set(gca,'CameraTargetMode','manual')
        set(gca,'CameraTarget',point)
        
    end
    
elseif strcmp(eventData.Key,'p')
    
    if isempty(auto_play_timer)
        auto_play_timer = timer('StartDelay', 0.1, 'Period', 0.5,'ExecutionMode', 'fixedSpacing');
        auto_play_timer.TimerFcn = @(x,y)increment(1);
    end
    
    is_running = strcmp(get(auto_play_timer,'Running'),'on');
    
    if is_running
        stop(auto_play_timer);
        
    else
        start(auto_play_timer);
    end

elseif strcmp(eventData.Key,'delete')
    
    h = findobj(gca,'Tag','pt'); % try to find the old point
    
    if isempty(h)
        warndlg('No point selected');
        return;
    end
    
    old_label = get(h,'UserData');
    
    choice = questdlg(['Are you sure you want to delete: ' old_label],'Delete tag','Yes','No','No');
    if strcmp(choice,'No')
        return
    end

%     warndlg(old_label,'Deleting')
    
    %delete this label
    for ki=k:-1:1
        eval(sprintf('original = %s(:,%d);',old_label,ki))
        if isValid(original)
            %Replace with nan
            eval(sprintf('%s(:,%d) = NaN;',old_label,ki));
            fprintf('Deleted %s in %d\n',old_label,ki)
        else
            break
        end
    end

    for ki=k+1:1:trial_length
        
        eval(sprintf('original = %s(:,%d);',old_label,ki))
        if isValid(original)
            %Replace with nan
            eval(sprintf('%s(:,%d) = NaN;',old_label,ki));
            fprintf('Deleted %s in %d\n',old_label,ki)
        else
            break
        end
    end
    
    draw();
    
elseif strcmp(eventData.Key,'u')
    set(gca, 'CameraUpVector', [0 0 1]);
end

end

function valid = isValid(point)
    if isempty(point)
        valid = false;
    else
        valid = ~any(isnan(point));
    end
end
    
function sucess = overWrite(old_label,new_label,k_current,k_next)
    global t
    persistent previous
    
    eval(sprintf('original = %s(:,%d);',old_label,k_current))
    eval(sprintf('next = %s(:,%d);',old_label,k_next))
%     eval(sprintf('previous = %s(:,%d);',old_label,k_previous));
    
    eval(sprintf('current = %s(:,%d);',new_label,k_current));
    
    
    if isValid(original)
        %Original point is valid
        %Check if we will overwrite an existing point
        if isValid(current)
            warndlg('Cannot overwrite existing valid label');
            return
        end

        %The point is valid and the mask is also valid
        eval(sprintf('%s(:,%d) = original;',new_label,k_current))
        
        %Save the old valid in the previous variable
        eval(sprintf('previous = %s(:,%d);',old_label,k_current));
        eval(sprintf('%s(:,%d) = NaN;',old_label,k_current));
        
        sucess = true;
        return;
        
    elseif ~isValid(original) && isValid(next)
        %Check distance from previous to next
        
        fprintf('Found gap at iteration: %d\n',k_current);

        if isValid(previous) && isValid(next)
            distance = norm(previous-next);
            
            if distance > 0.1
                fprintf('Gap distance is too large: %f.\n',distance);
                fprintf('Label lost at iteration: %d\n',k_current);
                sucess = false;
                return
            else
                fprintf('Gap is not set, but search is continuing\n');
                %Don't copy value because it is invalid but dont stop
                %search
                sucess = true;
                return;
            end
        end
        
        %Cannot do any more changes
        sucess = false;
        return
        
    elseif ~isValid(original) && ~isValid(next)
        fprintf('Label lost at iteration: %d\n',k_current);
        
        sucess = false;
        return;
    end
end

function increment(increment)
global k t tags
eval(sprintf('trial_length = size(%s,2);',tags{1}));
k = k + increment;
k = min(k,trial_length);
k = max(k,1);
draw();
end

function draw()
    global tags k t h colors connections

    hl = findobj(gca,'Tag','pt'); % try to find the old point
    if ~isempty(hl)
        delete(hl)
    end
    
%     keyboard
    person=zeros(3,length(tags));
    
    for i=1:length(tags)
        eval(sprintf('person(1,%d) = %s(1,%d);',i,char(tags{i}),k));
        eval(sprintf('person(2,%d) = %s(2,%d);',i,char(tags{i}),k));
        eval(sprintf('person(3,%d) = %s(3,%d);',i,char(tags{i}),k));
    end

    h = plotPerson(gca,person,connections,tags,colors);
    
    ht = findobj(gca,'Tag','frame_number');
    if ~isempty(ht)
        delete(ht)
    end
    
    text(0,0,0.2,sprintf('k %d',k),'color',[1 1 1],'Tag','frame_number')
end