% -------------------------------------------------------------------------
% MSc Project - MSc in Communications and Signal Processing
% Department of Electrical and Electronic Engineering
% Imperial College London, 2011
%
% Supervisor  : Dr Pier Luigi Dragotti
% Contributor : Andriy Gelman
% Author      : Jon Onativia Bravo
%
% File       : compute_tree_statistics.m
% -------------------------------------------------------------------------


clear all
close all


% MATLAB data files
% files = {'animal_farm.mat', 'cones.mat', 'teddy.mat', 'tsukuba_extracted4.mat'};
files = {'tsukuba_extracted4.mat'};

% Tree parameters
% max_distances = [ 3  2 1];
% max_offsets   = [31 15 7];

% max_distances = [10  5 2];
% max_offsets   = [31 15 7];

% max_distances = [20 15 10];
% max_offsets   = [31 15 7];

% max_distances_vec = [1.5 2.5 3 3.5 4.5];
max_distances_vec = [60];
max_offsets   = [127];

max_depth     = length(max_offsets);
    
colors = [1 0 0; 0 0 1; 0 1 0; 0 1 1];

dx_x_min = Inf * ones(max_depth,1);
dx_x_max = -Inf * ones(max_depth,1);
dx_y_min = Inf * ones(max_depth,1);
dx_y_max = -Inf * ones(max_depth,1);
dy_x_min = Inf * ones(max_depth,1);
dy_x_max = -Inf * ones(max_depth,1);
dy_y_min = Inf * ones(max_depth,1);
dy_y_max = -Inf * ones(max_depth,1);
err_x_min = Inf * ones(max_depth,1);
err_x_max = -Inf * ones(max_depth,1);
err_y_min = Inf * ones(max_depth,1);
err_y_max = -Inf * ones(max_depth,1);
seg_len_x_min = Inf * ones(max_depth,1);
seg_len_x_max = -Inf * ones(max_depth,1);
seg_len_y_min = Inf * ones(max_depth,1);
seg_len_y_max = -Inf * ones(max_depth,1);

% fig_hdl = figure;

% Loop over all files
ith_file = 1;
for file_name_cell = files
    
    file_name         = file_name_cell{1};
    [~, data_name, ~] = fileparts(file_name);
    
    disp(' ')
    disp(['File : ' file_name])
    
    % Load data

    % Disparity vector
    load(file_name, 'D');
    % Images array
    load(file_name, 'in');
    % Labels array
    load(file_name, 'label');

    % Size of the data
    [r, c, num_images] = size(in);

    % Obtain the stack of labels
    layers_stack = generate_layer_stack(label, D);
    
    % Labels parameters
    [height, width, num_layers] = size(layers_stack);
    approx_layers               = zeros(height, width, num_layers-1);
    
    % Start printing statistics
    

    %% Construct a lossless version
    lossless_cont = cell(num_layers-1, 1);
    for l = 1 : num_layers-1
        lossless_cont{l}     = estimate_contours_vertices(layers_stack(:,:,l), 0, 1);
    end
    
    %%
    for max_distances = max_distances_vec
    
    
    %% Construct the contours tree
    label_verts_tree = cell(num_layers-1, 1);
    for l = 1 : num_layers-1
        label_verts_tree{l} = estimate_contours_tree(layers_stack(:,:,l), max_distances, max_offsets);
    end % end of l = 1 : num_layers

    %% Compress the bitstream
    [bitstream, layer_limits] = tree2bitstream_v3(label_verts_tree, max_offsets, width, height);
    field_bits = log2(max_offsets + 1) + 1;
    [substreams] = arithm_enc_stream(bitstream, layer_limits, field_bits);
    
    %% Recontruct the layers
    distortions     = zeros(1, max_depth);
    compressed_bits = 0;
    for depth = 1 : max_depth
        for l = 1 : num_layers-1
            verts                = tree2contour(label_verts_tree{l}, depth);
            approx_layers(:,:,l) = contour2shape(verts, width, height);
        end
        distortions(depth) = get_distortion(layers_stack(:,:,1:num_layers-1), approx_layers);
        
        compressed_bits = compressed_bits + length(substreams{depth})*8;
        
        disp([' - error      : ' num2str(max_distances)])
        disp([' - bits       : ' num2str(compressed_bits)])
        disp([' - distortion : ' num2str(distortions(depth))])
        
    end
    
    %% Get the tree statistics
%     [delta_x, delta_y, delta_xy, error, seg_lengths] = get_tree_statistics(label_verts_tree, max_offsets, lossless_cont);
    
    %% Plot the statistics
%     for ith_level = 1 : max_depth
%         subplot(4, max_depth, ith_level)
%         hold on
%         plot(delta_x{ith_level}(:,1), delta_x{ith_level}(:,2), 'Color', colors(ith_file,:))
%         title('\Deltax distribution', 'FontSize', 10)
%         x_min  = delta_x{ith_level}(1,1) - 1;
%         x_max  = delta_x{ith_level}(end,1) + 1;
%         height = max(delta_x{ith_level}(:,2));
%         y_min  = - 0.1 * height;
%         y_max  = 1.1 * height;
%         dx_x_min(ith_level) = min([dx_x_min(ith_level) x_min]);
%         dx_x_max(ith_level) = max([dx_x_max(ith_level) x_max]);
%         dx_y_min(ith_level) = min([dx_y_min(ith_level) y_min]);
%         dx_y_max(ith_level) = max([dx_y_max(ith_level) y_max]);
%         axis([dx_x_min(ith_level) dx_x_max(ith_level) dx_y_min(ith_level) dx_y_max(ith_level)])
%         xlabel('\Deltax - pixels', 'FontSize', 8)
%         grid on
%         
%         subplot(4, max_depth, ith_level+max_depth)
%         hold on
%         plot(delta_y{ith_level}(:,1), delta_y{ith_level}(:,2), 'Color', colors(ith_file,:))
%         title('\Deltay distribution', 'FontSize', 10)
%         x_min  = delta_y{ith_level}(1,1) - 1;
%         x_max  = delta_y{ith_level}(end,1) + 1;
%         y_min  = - 0.1 * height;
%         y_max  = 1.1 * height;
%         dy_x_min(ith_level) = min([dy_x_min(ith_level) x_min]);
%         dy_x_max(ith_level) = max([dy_x_max(ith_level) x_max]);
%         dy_y_min(ith_level) = min([dy_y_min(ith_level) y_min]);
%         dy_y_max(ith_level) = max([dy_y_max(ith_level) y_max]);
%         axis([dy_x_min(ith_level) dy_x_max(ith_level) dy_y_min(ith_level) dy_y_max(ith_level)])
%         xlabel('\Deltay - pixels', 'FontSize', 8)
%         grid on
%         
%         subplot(4, max_depth, ith_level+2*max_depth)
%         hold on
%         bins       = linspace(0, max_distances(ith_level), 20);
%         error_hist = histc(error{ith_level}, bins);
%         stairs(bins, error_hist, 'Color', colors(ith_file,:))
%         title('Max. error per segment', 'FontSize', 10)
%         hold on
%         x_min = 0;
%         x_max = max_distances(ith_level);
%         y_min = 0;
%         y_max = max(error_hist) * 1.1;
%         err_x_min(ith_level) = min([err_x_min(ith_level) x_min]);
%         err_x_max(ith_level) = max([err_x_max(ith_level) x_max]);
%         err_y_min(ith_level) = min([err_y_min(ith_level) y_min]);
%         err_y_max(ith_level) = max([err_y_max(ith_level) y_max]);
%         axis([err_x_min(ith_level) err_x_max(ith_level) err_y_min(ith_level) err_y_max(ith_level)])
%         xlabel('Error - pixels', 'FontSize', 8)
%         grid on
%         
%         subplot(4, max_depth, ith_level+max_depth*3)
%         hold on
%         plot(seg_lengths{ith_level}, 'Color', colors(ith_file,:))
%         title('Segment lengths distribution', 'FontSize', 10)
%         x_min  = 0;
%         x_max  = length(seg_lengths{ith_level});
%         height = max(seg_lengths{ith_level}) - min(seg_lengths{ith_level});
%         y_min  = min(seg_lengths{ith_level}) - 0.1 * height;
%         y_max  = max(seg_lengths{ith_level}) + 0.1 * height;
%         seg_len_x_min(ith_level) = min([seg_len_x_min(ith_level) x_min]);
%         seg_len_x_max(ith_level) = max([seg_len_x_max(ith_level) x_max]);
%         seg_len_y_min(ith_level) = min([seg_len_y_min(ith_level) y_min]);
%         seg_len_y_max(ith_level) = max([seg_len_y_max(ith_level) y_max]);
%         axis([seg_len_x_min(ith_level) seg_len_x_max(ith_level) seg_len_y_min(ith_level) seg_len_y_max(ith_level)])
%         xlabel('Segment length - vertices', 'FontSize', 8)
%         grid on
%     end

    end
    
    ith_file = ith_file + 1;
end % end of file_name_cell = files

%%
% set(fig_hdl, 'Position', [500 20 900 1000])

%% Play a sound when finished
fs = 8000;
Ts = 1 / 8000;
t  = 0:Ts:2;
fo = 220;
so = sin(2*pi*fo*t);

soundsc(so, fs)
