% This function should be used to evaluate your code for the project %
% Inputs: <order>: 1-D vector (integer) (length <= 100)
%                  CANNOT CONTAIN DUPLICATES
%         <orientation>: 1-D vector (boolean) (length same as <order>)
%         <matFile>: MAT file containing ground truth for this image
% Outputs: <score>, <longest>, <total>: (scalars, all out of max. 100)
% 
% Details:
%
% 1. <order(i)> stores the index of the input that maps to the ith output
% (left to right). Indices go from 1-100, NOT 0-99
% 
% 2. <orientation(i)> stores the rotation for the ith OUTPUT (from left)
% If the input mapped to the ith OUTPUT is used with 180-degree rotation,
% <orientation(i)> = 1, else 0. Note: Indices go from 1-100, NOT 0-99
%
% 3. <score> gives the number of correctly matched seams (99 seams between
% the hundred strips + seam at left and right end of the document is
% counted as 0.5 each. Thus, max. possible <score> is 99 + 0.5 * 2 = 100
%
% 4. <longest> gives the length of the longest continuous chunk (in terms
% of the number of strips) that is correctly stitched; max. 100
%
% 5. <total> gives the total length (in number of strips) or all correctly
% stitched segments (each with at least 2 strips); max. 100

function [score, total, longest]...
    = eval_order_v3(order, orientation, matFile)
    
    gt = load(matFile);
    
    [score_1, total_1, longest_1]...
        = eval_order_block(order, orientation, gt.order, gt.orientation);
    [score_2, total_2, longest_2]...
        = eval_order_block(order, orientation, fliplr(gt.order),...
        fliplr(1-gt.orientation));
    
    score = score_1 + score_2;
    total = total_1 + total_2;
    longest = max(longest_1, longest_2);
    
    fprintf('\nCorrect seams: %3d (of 100)', score);
    fprintf('\nLongest correct segment: %3d (of 100)', longest);
    fprintf('\nTotal length of correct segments: %3d (of 100)', total);
    fprintf('\n');
end

function [score, total, longest] = eval_order_block(order, orientation, gt_order, gt_orientation)

    n = length(order);
    N = length(gt_order);
    total = 0;
    longest = 0;
    score = 0;
    
    % Order and orientation vectors must have the same length %
    if length(orientation) ~= n
        disp('ERROR: The lengths of <order>, <orientation> must be equal');
        return
    end
    
    % Input sequence length must not be more than the total no. of shreds %
    if n > N
        disp('ERROR: The length of the input sequence cannot be larger')
        disp('than the total number of shreds');
        return
    end
    
    % The input sequence cannot have repeating indices %
    if length(unique(order)) ~= n
        disp('ERROR: The input sequence cannot have repeating indices');
        return
    end
    
    % Find correct assignments %
    i = 1;
    while i < n
        idx = find(gt_order == order(i), 1);
        if isempty(idx)
            i = i + 1;
            continue;
        end
        if orientation(i) ~= gt_orientation(idx)
            i = i + 1;
            continue;
        end
        L = 1; % Length of correct assignments, starting at i
        while (1)
            if (idx+L > N) || (i+L > n)
                break;
            end
            if (gt_order(idx+L) ~= order(i+L)) || (gt_orientation(idx+L) ~= orientation(i+L))
                break;
            end
            L = L + 1;
        end
        i = i + L;
        if L == 1
            L = 0;
        end
        longest = max(longest, L); % Longest correct assignments
        total = total + L; % Sum of the lengths of all correct assignments
        score = score + max(0, L - 1);
        
        if L > 1
            if (idx == 1)
                score = score + 0.5;
            end
            if (idx + L > N)
                score = score + 0.5;
            end
        end
        
    end
end