% part c
% function that matches the blocks of the current image (IC) to the previous image (IP)
% the boundary blocks are not matched and assumed to have 0 motion. nxn is the blocksize.

function [ MotionVectorsX,MotionVectorsY,MotionVectorsT,IPredicted ]  = BlockMatching(IC,IP,Block_Size_x,Block_Size_y,Block_Size_t,Support_XY_begin,Support_XY_end,Support_t_begin);

%Get the size of the input images
sizex = size(IC,1);
sizey = size(IC,2);

MotionVectorsX = zeros(sizex/Block_Size_x,sizey/Block_Size_y);
MotionVectorsY = zeros(sizex/Block_Size_x,sizey/Block_Size_y);
MotionVectorsT = zeros(sizex/Block_Size_x,sizey/Block_Size_y);


% the borders were not calculated, so copy them directly to the predicted image from the current image.
for i= [1:(Support_XY_end/Block_Size_x+1) (sizex/Block_Size_x-(Support_XY_end/Block_Size_x)+1):(sizex/Block_Size_x)],
    for j= 1:(sizey/Block_Size_y)
        IPredicted((i-1)*Block_Size_x+1:i*Block_Size_x,(j-1)*Block_Size_y+1:j*Block_Size_y,:)=IC((i-1)*Block_Size_x+1:i*Block_Size_x,(j-1)*Block_Size_y+1:j*Block_Size_y,:);
    end
end

for i= 1:(sizex/Block_Size_x)
    for j= [ 1:(Support_XY_end/Block_Size_y) (sizey/Block_Size_y-(Support_XY_end/Block_Size_y)+1):(sizey/Block_Size_y)]
        IPredicted((i-1)*Block_Size_x+1:i*Block_Size_x,(j-1)*Block_Size_y+1:j*Block_Size_y,:)=IC((i-1)*Block_Size_x+1:i*Block_Size_x,(j-1)*Block_Size_y+1:j*Block_Size_y,:);
    end
end

% the motion vectors are calculated inside.
for i=Support_XY_end/Block_Size_x+1:(sizex/Block_Size_x-Support_XY_end/Block_Size_x)
    for j=Support_XY_end/Block_Size_y+1:(sizey/Block_Size_y-Support_XY_end/Block_Size_y)
        MinDiff = inf;
        for k=Support_XY_begin:Support_XY_end
            for m=Support_XY_begin:Support_XY_end
                 for t= Support_t_begin:0  
                    %keyboard
                 %if (i==12)&(j==12)
                 %    keyboard;
                 %end
                 %keyboard;
                 %Diff = mean(mean(mean(abs(IC((i-1)*Block_Size_x+1:i*Block_Size_x,(j-1)*Block_Size_y+1:j*Block_Size_y,:)-IP((i-1)*Block_Size_x+1+k:i*Block_Size_x+k,(j-1)*Block_Size_y+1+m:j*Block_Size_y+m,t-Support_t_begin+1:t-Support_t_begin+Block_Size_t)))));
                 %Diff = std(IC((i-1)*Block_Size_x+1:i*Block_Size_x,(j-1)*Block_Size_y+1:j*Block_Size_y,:)-IP((i-1)*Block_Size_x+1+k:i*Block_Size_x+k,(j-1)*Block_Size_y+1+m:j*Block_Size_y+m,t-Support_t_begin+1:t-Support_t_begin+Block_Size_t)))));
                 Diff_Block = IC((i-1)*Block_Size_x+1:i*Block_Size_x,(j-1)*Block_Size_y+1:j*Block_Size_y,:)-IP((i-1)*Block_Size_x+1+k:i*Block_Size_x+k,(j-1)*Block_Size_y+1+m:j*Block_Size_y+m,t-Support_t_begin+1:t-Support_t_begin+Block_Size_t);
                 Diff = std(Diff_Block(:));
                 %DCT_block = DCT3(Diff_Block);
                 %DCT_block(1) = 0;
                 %Diff = mean(mean(mean(abs(DCT_block))));
                 
                  if (Diff<MinDiff)
                      %i
                      %j
                      MinDiff=Diff;
                      Minx = k;
                      Miny = m;
                      Mint = t;
                  end
                 end
            end
        end
        MotionVectorsX(i,j) = Minx;
        MotionVectorsY(i,j) = Miny;
        MotionVectorsT(i,j) = Mint;
        IPredicted((i-1)*Block_Size_x+1:i*Block_Size_x,(j-1)*Block_Size_y+1:j*Block_Size_y,1:Block_Size_t)=IP((i-1)*Block_Size_x+1+Minx:i*Block_Size_x+Minx,(j-1)*Block_Size_y+1+Miny:j*Block_Size_y+Miny,Mint-Support_t_begin+1:Mint-Support_t_begin+Block_Size_t);
    end
end


return
%for i=1:Block_Size_t
%     imagesc(IPredicted(:,:,i),[0 255]);
%     colormap(gray);
%     keyboard;     
%end


%figure(9);
%[x,y] = meshgrid(1:n:sizey,1:n:sizex)
%imagesc(Y2);
%colormap(gray);
%hold on;
%quiver ((x+MotionVectorsY),(y+MotionVectorsX),-MotionVectorsY,-MotionVectorsX);  

