function [evalStruct, resultsAll] = evalRuling(varargin)
% function [evalStruct, resultsAll] = evalRuling(params)
% 
% INPUT:
%  params               a struct with at least two paths
%  params.gtPath        the folder containing all GT images
%  params.resultPath    the folder containing all result images
%  params.tag           optional, a tag which is added to distinguish
%                       between resulting images and gt images (e.g.
%                       201-mask1-removed-00.tif) in this case the tag
%                       should be -removed. if more than one output image
%                       exists, the last counter can be increased (e.g. for
%                       parameter evaluation
%
% OUTPUT:
% evalStruct            a struct containg the evaluation for each result
%                       image
% evalStruct.tp         number of true positive pixel per image
% evalStruct.fp         number of false positive pixel per image
% evalStruct.fn         number of false negative pixel per image
% evalStruct.p          precision per image
% evalStruct.r          recall per image
% evalStruct.f          f-score per image
% evalStruct.n          total number of pixel
% evalStruct.filename   cell array with all filenames that have the same GT
%                       image
%
% resultsAll            summary of all results
% resultsAll.tp         total number of true positive pixel
% resultsAll.fp         total number of false positive pixel
% resultsAll.fn         total number of false negative pixel
% resultsAll.p          mean precision
% resultsAll.r          mean recall
% resultsAll.f          mean f-score
% 
% Here is a minimal example:
% p.gtPath      = fullfile('C:', 'database', 'ruling');
% p.resultPath  = fullfile('C:', 'database', 'ruling', 'results');
% [eval, all] = evalRuling(p);

p = parseInputs(varargin{:});

d = dir(p.gtPath);
dr = dir(p.resultPath);

% tell user what he is doing...
fprintf('Info: -----------------------------------------------\n');
fprintf('GT images loaded from:     %s\n', p.gtPath);
fprintf('result images loaded from: %s\n', p.resultPath);
fprintf('Processing %g files\n', length(d));
fprintf('-----------------------------------------------------\n\n');

if ~isdir(p.gtPath)
   error([p.gtPath ' does not exist, please specify a valid GT path']); 
end

if ~isdir(p.resultPath)
   error([p.resultPath ' does not exist, please specify a valid result path']); 
end


tic;
structIdx = 1;

for i = 1:length(d)
    
    
    [baseName, ext] = delimgext(d(i).name, '\.tif$');
    
    if isempty(ext)
        continue;
    end
    
    matches = find(cellfun(@(x)~isempty(strfind(x,[baseName p.tag])), {dr.name}));
    if isempty(matches)
        disp([baseName ' is missing... skipping']);
        continue;
    end
    
    img = imread(fullfile(p.gtPath, d(i).name));
    
    for mIdx = 1:length(matches)
            
        imgp = imread(fullfile(p.resultPath, dr(matches(mIdx)).name)) > 0;

        linImg = img == 155;
        txtImg = img < 150;

        tp = sum(sum(imgp & linImg & ~txtImg));
        fp = sum(sum(imgp & txtImg));
        fn = sum(sum(~imgp & ~txtImg & linImg));
        
        cp = tp/(tp+fp);
        cr = tp/(tp+fn);
        cf = (2*cp*cr)/(cp+cr);
        
        evalStruct(structIdx).tp(mIdx) = tp;
        evalStruct(structIdx).fp(mIdx) = fp;
        evalStruct(structIdx).fn(mIdx) = fn;
        evalStruct(structIdx).p(mIdx) = cp;
        evalStruct(structIdx).r(mIdx) = cr;
        evalStruct(structIdx).f(mIdx) = cf;
        evalStruct(structIdx).n(mIdx) = sum(sum(img ~= 255));
        evalStruct(structIdx).filename{mIdx} = dr(matches(mIdx)).name;
    end
    
    fprintf('%s precision: %.3f\n', baseName, evalStruct(structIdx).tp/(evalStruct(structIdx).tp+evalStruct(structIdx).fp));
    structIdx = structIdx+1;

end

if structIdx == 1
    % no matching files found
   error('Sorry, I could not find any matches...');
end

tpa = sum([evalStruct.tp]);
fpa = sum([evalStruct.fp]);
fna = sum([evalStruct.fn]);

p = tpa/(tpa+fpa);
r = tpa/(tpa+fna);
f = (2*p*r)/(p+r);

% tell user what he is doing...
fprintf('Info: -----------------------------------------------\n');
fprintf('precision: %.3f, recall: %.3f\n', p, r);
fprintf('f-score:   %.3f\n', f);
fprintf('images:    %g on pixels: %g tp: %g\n', length(evalStruct), tpa+fpa+fna, tpa);
fprintf('-----------------------------------------------------\n\n');

disp(['I have finished processing: ' num2str(toc) ' sec']);

resultsAll.tp = tpa;
resultsAll.fp = fpa;
resultsAll.fn = fna;
resultsAll.p = p;
resultsAll.r = r;
resultsAll.f = f;

%--------------------------------------------------------
% Subfunction: Parse Inputs
%--------------------------------------------------------
function p = parseInputs(varargin)


if nargin < 1
    p = [];
else
    p = varargin{1};
end

% input params
defaultP.display                = 1;
defaultP.gtPath                 = fullfile('D:', 'databases', 'cvl-ruling', 'db2');
defaultP.resultPath             = fullfile('D:', 'databases', 'cvl-ruling', 'db2', 'results-test');
defaultP.tag                    = '';

p = merge_structs(p, defaultP);