%EUSIPCO 2012
%Imperial College London 
%Andriy Gelman, Jon Onativia and Pier Luigi Dragotti 

function [out, new_mask] = disparity_comp(input, mask, disparity, old_k, new_k)
%function out = disparity_comp(input, disparity, old_k, new_k)

input = double(input);
mask = double(mask);

if ((abs(disparity) > 0) && (abs(old_k - new_k) > 0))

[r,c,k] = size(input);
c = c+2; %As we will extend the columns by one on both sides 

%Pad Signal left and right by one
input = padarray(input, [0 1], 'both');
mask = padarray(mask, [0 1], 'both');

[left_edge, right_edge] = compute_edge_map_horizontal(mask);
%    if total_shift >0
%        edge_map = double(left_edge);
%    else
%        edge_map = double(right_edge);
%    end

%Pad left and right edges, so that intepolation does not introduce errors
%around teh edges
left_edge_map_values = left_edge.*input;
right_edge_map_values = right_edge.*input;
  
%left_edge = left_edge-1;
%right_edge = right_edge+1;
left_edge_map_values = circshift(left_edge_map_values, [0, -1]);
right_edge_map_values = circshift(right_edge_map_values, [0, 1]);
left_edge = circshift(left_edge, [0, -1]);
right_edge = circshift(right_edge, [0, 1]);

%input = input+left_edge_map_values+right_edge_map_values;
input(left_edge == 1) = left_edge_map_values(left_edge==1);
input(right_edge == 1) = right_edge_map_values(right_edge==1);

%edge_map = double(left_edge+right_edge);
    %Depending on the disparity, left or right edge have to be treated
    %differently.
%    edge_map_values = edge_map.*input;



%Deal with edges separately.. ie do not apply interolation 

%out = zeros(r,c,k);
%out = out -1000;
%for j = 1:k
%for i = 1:c
%    px_new = i - delta_Vx*(new_k - old_k)/Z;
%    buffer = input(:,i,j);
%    if ((px_new >= 1) && (px_new <= c))
%    out(:, round(px_new),j) = buffer;
%    end
%end
%end

%out(find(out == -1000)) = 0;


total_shift = (disparity*(new_k-old_k));

%total_integer_shift = ceil(abs(total_shift));

%non_integer_shift = sign(total_shift)*(abs(total_shift) - floor(abs(total_shift)));

[x,y] = meshgrid(1:c,1:r);
%[x_new,y] = meshgrid((1:c)+non_integer_shift,1:r);
[x_new,y] = meshgrid((1:c)+total_shift,1:r);
%out = interp2(x,y,input,x_new,y, 'spline');
out = interp2(x,y,input,x_new,y);

%out = integer_shift(out, -round(non_integer_shift));
%out  = integer_shift(input, disparity);
buffer= zeros(r,c);
buffer(abs(out)>0)=out(abs(out)>0);
out = buffer;

%if abs(total_shift - floor(total_shift))>0
    
%    [left_edge, right_edge] = compute_edge_map_horizontal(mask);
%    if total_shift >0
%        edge_map = double(left_edge);
%    else
%        edge_map = double(right_edge);
%    end

    %edge_map = double(left_edge+right_edge);
    %Depending on the disparity, left or right edge have to be treated
    %differently.
%    edge_map_values = edge_map.*input;
    %edge_map_values = disparity_comp(edge_map_values, [], sign(total_shift)*floor(abs(total_shift)), 1,2);
%    edge_map_values = integer_shift(edge_map_values, sign(total_shift)*ceil(abs(total_shift)));
    %edge_map = disparity_comp(edge_map, [], sign(total_shift)*floor(abs(total_shift)), 1,2);
%    edge_map = integer_shift(edge_map, sign(total_shift)*ceil(abs(total_shift)));
    
%    out(edge_map == 1) = edge_map_values(edge_map == 1);
    
    %new_mask = double(disparity_comp(mask, [], sign(total_shift)*floor(abs(total_shift)),1,2));
    %new_mask = integer_shift(mask, sign(total_shift)*floor(abs(total_shift)));
    %out = out.*new_mask;

%end
 
    new_mask = integer_shift(mask, sign(total_shift)*ceil(abs(total_shift)));
    new_mask(abs(new_mask) > 0 )=1;
    %out = out.*new_mask;

    buffer= zeros(r,c);
    buffer(abs(out)>0)=out(abs(out)>0);
    out = buffer;
    out = out(:,2:end-1);

    new_mask = new_mask(:,2:end-1);
    
else out = input;
end



end


function  out = integer_shift(input, total_shift)

if total_shift ~=0
    [r,c,k] = size(input);
    %Pad Signal

    sig_pad = zeros(r,c+2,k);
    sig_pad(:,2:end-1,:) = input;

    sig_pad = padarray(sig_pad, [0, abs(total_shift) - 1],'both');

    coords = [abs(total_shift) + 1, length(sig_pad(1,:,1)) - abs(total_shift)];

    sig_pad = circshift(sig_pad, [0, -total_shift]);

    out = sig_pad(:,coords(1):coords(2),:);

else 
    out = input;
end
end



        
