function [c2FeaTotal,c2Label] = build_c2_layer(s2Database,smDatabase,param)
% This function is to extract final feature representation with multi-scale
% max pooling on the saliency maps.
% Input:  s2Database -- the database of object level sparse feature maps
%         smDatabase -- the database of saliency maps
%         param      -- see the default settings below
% Output: c2FeaTotal -- the feature matrix, each column represents one
%                       feature vector of image
%         c2Label    -- the class label of each image
% Written by Jimei Yang
% Oct. 28, 2009
if ~isfield(param,'poolingS2')
    param.poolingS2 = [1,2,4];
end
if ~isfield(param,'weightsC2')
    param.weightsC2 = [1,1,1];
end

nSmp = length(s2Database.path);
% total bins
pBins = param.poolingS2.^2;
tBins = sum( pBins );
c2FeaTotal = sparse(tBins*param.nBasesS2,nSmp);
c2Label = zeros(nSmp,1);
for i = 1:nSmp
    fprintf('--extract the c2 feature...');
    tic;
    fpath = s2Database.path{i};
    load(fpath);
    [bSize,nFea] = size(s2Fea.feaData);
    mpath = smDatabase.path{i};
    load(mpath);
    smap = smap(:);
    weightedFea = abs(s2Fea.feaData) .* repmat( smap', bSize, 1 );
    % extract c2 features
    tBeta = zeros( tBins*bSize, 1 );
    for p = 1 : length( param.poolingS2 )
        nBins = pBins(p);
        feaData = zeros(bSize,nBins);
        wUnit = s2Fea.width / param.poolingS2(p);
        hUnit = s2Fea.height / param.poolingS2(p);

        % find to which block (bin) each feature belongs
        xBin = ceil(s2Fea.x / wUnit);
        yBin = ceil(s2Fea.y / hUnit);
        idxBin = (yBin - 1)*param.poolingS2(p) + xBin;

        for k = 1:nBins
            sidxBin = find(idxBin == k);
            if isempty(sidxBin)
                continue;
            end
            % max pooling of absolute value
            sub_weights = weightedFea(:, sidxBin);
            [m,idx] = max( sub_weights, [], 2 );
            sub_fea = abs(s2Fea.feaData(:, sidxBin));
            for b = 1:bSize
                feaData(b,k) = sub_fea(b,idx(b));
            end
%             feaData(:,k) = max(abs(s2Fea.feaData(:, sidxBin)), [], 2);
        end

        beta = feaData(:);
        beta = beta./sqrt(sum(beta.^2));
        tBeta(sum(pBins(1:p-1))*bSize + (1:nBins*bSize)) = beta*param.weights(p);
    end
    c2FeaTotal(:,i) = tBeta;
    c2Label(i) = s2Database.label(i);
    disp([num2str(i),' in ',num2str(toc),' seconds;']);
end