% Copyright (c) 2015 The Johns Hopkins University/
% Applied Physics Laboratory. (JHU/APL)
% 
% This material was developed by JHU/APL under U.S. Government contract.
% The U.S. Government has Unlimited Rights in this material per
% DFARS 252.227-7013/7014, as appropriate.
% 
% For any other permission, please contact the Legal Office at JHU/APL.
function [metrics2D,  metrics3D, metrics3Ds] = pipeline25D_run(inputFilenames, params)

    if ~exist('lasdata', 'file')
        addpath(fullfile(fileparts(which('pipeline25D_run')), '..', '3rdParty'))
    end


    % inputFilenames struct:  (all required)
    %  .refDSMFilename  
    %  .refDTMFilename
    %  .refMaskFilename
    %  .testModelFilename
    %  .testMaskFilename
    %  .testOffsetFilename


 
    % Default parameters
    DSM_FILL_VALUE_REF     = -10000;
    DTM_FILL_VALUE_REF     = -10000;
    BUILDING_VALUE_REF  = 6;  
    
    BUILDING_VALUE_TEST = 240;  

    % Apply registration offsets
    APPLY_OFFSETS_TEST_MASK = true;
    APPLY_OFFSETS_TEST_MODEL = true;

    % Used if test model is GEOTIFF DSM
    MODEL_FILL_VALUE    = -10000;
    % Used if test model is LAS point cloud
    MODEL_DSM_METHOD    = 1%1;  %  1:MAX, 2:MIN, 3:MEAN

    QUANTIZE = false;
    
    MODEL_NAME = 'test model';

    DO_PLOTS   = true;
    SAVE_PLOTS = false;
    SAVE_FIGS  = false;
    SAVE_DIR   = '.';

    RESULTS_FILE = '';
    
    % Deal parameter overrides
    if exist('params', 'var') &&  ~isempty(params)
        fn = fieldnames(params);
        for p = 1:numel(fn)
            if exist(fn{p}, 'var')  || ~isempty(params.(fn{p}))
                eval(sprintf('%s = params.(fn{p});', fn{p}) );
            end
        end
    end

    %%
    
    
    fprintf('\nReference DSM GEOTIFF file:\n')
    refDSMFilename = getFilenameParam(inputFilenames, 'refDSMFilename', true);
  
   
    fprintf('\nReference DTM GEOTIFF file:\n')
    refDTMFilename = getFilenameParam(inputFilenames, 'refDTMFilename', true);

    fprintf('\nReference footprint GEOTIFF file:\n')
    refMaskFilename = getFilenameParam(inputFilenames, 'refMaskFilename', true);

    fprintf('\nTest dense LAS point cloud model:\n')
    testModelFilename = getFilenameParam(inputFilenames, 'testModelFilename', true);

    fprintf('\nTest footprint GEOTIFF file:\n')
    testMaskFilename = getFilenameParam(inputFilenames, 'testMaskFilename', true);
    
    fprintf('\nTest model registration file file:\n')
    testOffsetFilename = getFilenameParam(inputFilenames, 'testOffsetFilename', false);
    if isempty(testOffsetFilename)
        fprintf('''testOffsetFilename'' either unspecified or file not found\n')
        fprintf('No registration offsets will be applied to test model\n')
        APPLY_OFFSETS_TEST_MASK = false;
        APPLY_OFFSETS_TEST_MODEL = false; 
    end


    %%
    % ----- Load Reference Data -------------------------------------------
    fprintf('\nSTART Loading Reference Data...'); refftic = tic;

    if DO_PLOTS > 0
        DO_PLOTS = 200;
    end

    params = [];
    params.QUANTIZE        = QUANTIZE;
    params.DSM_FILL_VALUE  = DSM_FILL_VALUE_REF;
    params.DTM_FILL_VALUE  = DTM_FILL_VALUE_REF;
    params.MASK_TRUE       = BUILDING_VALUE_REF;
    params.DO_PLOTS        = DO_PLOTS;
    params.SAVE_PLOTS      = SAVE_PLOTS;
    params.SAVE_FIGS       = SAVE_FIGS;
    params.SAVE_DIR        = SAVE_DIR;
    params.REF_IMAGE       = REF_IMAGE;
    [refObj, refMask, refDTM, refInfo] = loadReferenceData(refDSMFilename, refDTMFilename, refMaskFilename, params);


    tRefPrepTime = toc(refftic);
    fprintf('END Loading Reference Data...     (%0.3f)\n', tRefPrepTime);


    %%
    % ----- Load Test Data -------------------------------------------
    fprintf('START Loading Test Data...\n'); testtic = tic;

    if DO_PLOTS > 0
        DO_PLOTS = 300;
    end

    params = [];
    params.QUANTIZE        = QUANTIZE;
    params.DSM_FILL_VALUE  = MODEL_FILL_VALUE;
    params.MASK_TRUE       = BUILDING_VALUE_TEST;     
    params.MODEL_APPLY_OFFSETS = APPLY_OFFSETS_TEST_MODEL;
    params.MASK_APPLY_OFFSETS  = APPLY_OFFSETS_TEST_MASK;
    params.DO_PLOTS        = DO_PLOTS;
    params.SAVE_PLOTS      = SAVE_PLOTS;
    params.SAVE_FIGS       = SAVE_FIGS;
    params.SAVE_DIR        = SAVE_DIR;
    params.MODEL_NAME      = MODEL_NAME;
    params.DSM_METHOD      = MODEL_DSM_METHOD;    

    offsets = [0 0 0];
   
    if ~isempty(testOffsetFilename)
   
        offsets = parseOffsetFile( testOffsetFilename );
        
        fprintf('Test registration offsets (easting, northing, height):\t')
        fprintf('%g, ', offsets);
        fprintf('\b\b\n');
    end

    [testObj, testMask, testRaster] = loadTestData(testModelFilename, testMaskFilename, refInfo, refDTM, offsets, params);


    tTestPrepTime = toc(testtic);
    fprintf('END Loading Test Data...     (%0.3f)\n', tTestPrepTime);


    %% Compute Metrics


    % ----- Load Performer Data -------------------------------------------
    fprintf('START Metric Computation...\n'); metrictic = tic;

    if DO_PLOTS > 0
        DO_PLOTS = 400;
    end    

    params = [];
    params.DO_PLOTS        = DO_PLOTS;
    params.SAVE_PLOTS      = SAVE_PLOTS;
    params.SAVE_FIGS       = SAVE_FIGS;
    params.SAVE_DIR        = SAVE_DIR;
    params.MODEL_NAME      = MODEL_NAME;
    params.RESULTS_FILE    = RESULTS_FILE;
    [metrics2D,  metrics3D,  metrics3Ds] = compute25DMetrics( testMask, testObj, refMask, refObj, refInfo, params);


    tMetricTime = toc(metrictic);
    fprintf('END Metric Computation...     (%0.3f)\n', tMetricTime);


    fprintf('DONE (%0.3f)\n', tRefPrepTime+tTestPrepTime+tMetricTime);



end


function filename = getFilenameParam(params, fieldname, required)
    
    if ~exist('required', 'var') || isempty(required)
        required = false;
    end
    
    filename = [];
    if isfield(params, fieldname) 
        if ~ischar(params.(fieldname))
            if required
                error('Field %s must be a string', fieldname);
            end
            return  
        end
        
        if exist(params.(fieldname), 'file')
            filename = params.(fieldname);
            fprintf('%s = \t%s\n', fieldname, filename)
        else
            if required
                error('File not found: %s', filename);
            end
            return
        end
    else
        if required
            error('Missing input field: %s', fieldname);
        end
        return
    end
end
