% Input:
% transitiontotake: matrix (containing possible transitions to take)
% Ijump: containing row-wise lists of sets which intersect the guard of the
% correspondent transition from transitiontotake)
% results: matrix (evaluation results)
% omegas: cell array of function handles (sets of the flowpipe)
% elapsedtime: double (time elapsed before the current location)
% iteration: integer (maxRecDept from hybrid reachability analysis)
% qd: matrix (encoding all trdansitions starting at the current active
% location)
% strategy: integer (1: Manual choise, 2: Most intersections, 3: First
% detected, 4: Last detected, 5: All)
% continue_computation: integer (>1 if a computation is being continued, in
% that case continue_computation contains the id of the correspondent
% stored state to continue with)

% Output:
% Ijump: vector (containing a list of sets intersecting the transition with
% id in transitiontotake)
% transitiontotake: integer (id, = index of qq, of the transition to take)

% Description:
% Determines which transition has to be taken according to the strategy
% specified by the user.

function [Ijump,transitiontotake] = call_transitionpicker(transitiontotake,Ijump,results,omegas,elapsedtime,iteration,qd,strategy,continue_computation)
global stored_states;
global current_path;
global trace;

if size(transitiontotake,1) > 1 % choice needed
    
    % Manual choice
    if strategy == 1
        output = transitionpicker({transitiontotake,Ijump,results,omegas,elapsedtime,iteration,qd});
                if (output{2})    %proceed
                    % set transition choice
                    choice = output{3};
                    Ijump = Ijump(choice,Ijump(choice,:)>0);
                    transitiontotake = transitiontotake(choice);
                else
                    Ijump = [];
                    transitiontotake = [];
                end;
    end;
    
    % Most intersections
    if strategy == 2
        elements = zeros(size(Ijump,1),1);
        for i=1:size(Ijump,1)
            elements(i) = sum(Ijump(i,:)~=0);
        end;
        [~,choice] = max(elements);
        Ijump = Ijump(choice,Ijump(choice,:)>0);
        transitiontotake = transitiontotake(choice);
    end;
    
    % Take transition whose guards intersect the flowpipe first
    if strategy == 3
        Ijump(Ijump == 0) = Inf;
        [x,choice] = min(Ijump(:,1));
        if isinf(x)
            transitiontotake = [];
            Ijump = [];
        else
            Ijump = Ijump(choice,:);
            Ijump = Ijump(Ijump < Inf);
            transitiontotake = transitiontotake(choice);
        end;
    end;
    
    % Take transition whose guards intersect the flowpipe last
    if strategy == 4
        [x,choice] = max(Ijump(:,1));
        if x == 0
            transitiontotake = [];
            Ijump = [];
        else
            Ijump = Ijump(choice,Ijump(choice,:)>0);
            transitiontotake = transitiontotake(choice);
        end;
    end;
           
    % fully recursive. Identical to spaceEx
    if strategy == 5
        %error('Not yet supported');
        
        % store all (relevant) traversed computation states and which was
        % the last considered transition for this state. Chose next
        % transition from the list to proceed. If no choice left, delete
        % stored state
        
        % the computation is reinitiated from within the gui as long as
        % there are stored states left. This guarantees that all pathes are
        % considered
        
        %if ~continue_computation
        %    % this is the first run. The state is not yet stored
        %    newid = store_state(results,omegas,elapsedtime,iteration,Ijump,transitiontotake,qd);
        %    transitiontotake = qd(1);
        %    Ijump = Ijump(1,Ijump(1,:)>0);

        %    stored_states{newid}.lasttransition = 1;
        %else
            
        %    if stored_states{continue_computation}.lasttransition < size(Ijump,1)
        %        % there are transitions to take left
        %        transitiontotake = transitiontotake(stored_states{continue_computation}.lasttransition +1);
        %        stored_states{continue_computation}.lasttransition = stored_states{continue_computation}.lasttransition +1;
        %        Ijump = Ijump(stored_states{continue_computation}.lasttransition,Ijump(stored_states{continue_computation}.lasttransition,:)>0);
        %    else
        %        % no more unconsidered transitions for actual state
        %        % delete state
        %        delete_state(continue_computation);
        %        Ijump = [];
        %        transitiontotake = [];
        %    end;
        %    
        %end;
        
        
        if ~continue_computation
            % this is the first run. The state is not yet stored
             newid = store_state(results,omegas,elapsedtime,iteration,Ijump,transitiontotake,qd);
             transitiontotake = qd(1);
             Ijump = Ijump(1,Ijump(1,:)>0);

             stored_states{newid}.lasttransition = 1;
        else
            % decide based on stored trace which transition has to be taken
            
            
            if stored_states{continue_computation}.lasttransition < size(Ijump,1)
                 % there are transitions to take left
                 transitiontotake = transitiontotake(stored_states{continue_computation}.lasttransition +1);
                 
                 
                 stored_states{continue_computation}.lasttransition = stored_states{continue_computation}.lasttransition +1;
                 Ijump = Ijump(stored_states{continue_computation}.lasttransition,Ijump(stored_states{continue_computation}.lasttransition,:)>0);
            else
                 % remove stored state if its information is no longer relevant
                
                 % no more unconsidered transitions for actual state
                 % delete state
                 delete_state(continue_computation);
                 Ijump = [];
                 transitiontotake = [];
            end;
        
            
            
        end;
        
    end;  
           
else
    Ijump = Ijump(Ijump>0);
end;