function [ codebook, index_vector, im_height, im_width ] = encoder( im, bsl, cluster_num )
% Encoder function 
%     ? should realize the compression itself 
%     ? parameters: 
%         ? input1: image matrix 
%         ? input2: block side length (eg. 8 in the case of blocks 8x8) 
%         ? input3: cluster number 
%         ? output1: computed codebook (centers matrix returned by vl_kmeans) 
%         ? output2: index vector (assignment vector returned by vl_kmeans) 
%         ? output3: number of rows of the coded image (the cropped one) 
%         ? output4: number of columns of the coded image (the cropped one) 
%     ? things to place here: 
%         cropping the image to the appropriate size; 
%         defining blocks on the image (please read the blocks in row-wise order), 
%         from which you can build your datamatrix to be clusterized; 
%         calling vl_kmeans

if size(im, 3) ~= 1
    error 'Not a grayscale image!'
end

im = mat2gray(im);

[ X, Y ] = size(im);
ver_blocks = floor(X/bsl);
hor_blocks = floor(Y/bsl);

% Vectorize blocks and put them to variable 'block_vector' as column vectors
block_vectors = zeros(bsl^2, ver_blocks*hor_blocks);

for i = 0:ver_blocks-1
    for j = 0:hor_blocks-1
        block = im(i*bsl+1:(i+1)*bsl,j*bsl+1:(j+1)*bsl); 
        block_vectors(:,i*hor_blocks+j+1) = block(:);
    end
end

im_width  = hor_blocks * bsl;
im_height = ver_blocks * bsl;

% Megspórolhatnám ezt a dupla ciklust, ha nem sorfolytonosan kéne... >:(
% im = im(1:im_height,1:im_width);
% block_vectors = im2col(im, [bsl, bsl], 'distinct');

% Complete kmean clustering ( = assign same index for similar blocks in that case)
[codebook, index_vector] = vl_kmeans(double(block_vectors), cluster_num);

end

