% clear all;
% close all;

% filtersSelection_codebook is for outputing the matching pursuit version of template, Frame version of template, and the deformed templates for each
% training images


function [template, templateMP] = filtersSelection_codebookV2(I, FiltersInfomation, numScale, numDoG, numOrient, numSketch, locationShiftLimit, orientShiftLimit, sx, sy, LocalNormOrNot,scaleFactor,thresholdFactor,savingFolder)

%% set parameters 
epsilon = .1; 
Upperbound = 6.; 
SHUTUP = 0.; 

numImg = length(I);


%% read filters bank information for filters selection
allFilterR = FiltersInfomation.allFilterR;
allFilterI = FiltersInfomation.allFilterI;
allSymbol = FiltersInfomation.allSymbol;
Crr = FiltersInfomation.Crr;
Cri = FiltersInfomation.Cri;
Cir = FiltersInfomation.Cir;
Cii = FiltersInfomation.Cii;
half = FiltersInfomation.half;

% allFiltered=cell(numImg,numFilter);
% for iImg=1:numImg
%     for iFilter=1:numFilter
%        allFiltered{iImg,iFilter} = (allFilteredR{iImg,iFilter}.^2 + allFilteredI{iImg,iFilter}.^2)/2;       
%     end
% end


tic;
[allFilteredR, allFilteredI, allFiltered] = ApplyFilter(I, allFilterR, allFilterI);
disp(['finished images filtering: ' num2str(toc) ' seconds']);


% local normalization
if LocalNormOrNot
    % 
    
    for iI = 1 : numImg
      for iScale=1:numScale  
        h = half(1+(iScale-1)*numOrient); 
        
        [allFilteredR(iI, 1+(iScale-1)*numOrient : numOrient+(iScale-1)*numOrient)]...
            = LocalNormalize(allFilteredR(iI, 1+(iScale-1)*numOrient : numOrient+(iScale-1)*numOrient),[],h,round(scaleFactor*h),round(scaleFactor*h),thresholdFactor);    
        
        [allFilteredI(iI, 1+(iScale-1)*numOrient : numOrient+(iScale-1)*numOrient)]...
            = LocalNormalize(allFilteredI(iI, 1+(iScale-1)*numOrient : numOrient+(iScale-1)*numOrient),[],h,round(scaleFactor*h),round(scaleFactor*h),thresholdFactor);
      end
    
      % for DoG
      for iScale=1:numDoG  
        ind  = numOrient*numScale+iScale;
        h = half(ind);       
        [allFilteredR(iI, ind)]=LocalNormalize(allFilteredR(iI, ind),[],h,round(scaleFactor*h),round(scaleFactor*h),thresholdFactor);                
      end
    end
    
    for iI = 1 : numImg
        for iF = 1 : numOrient*numScale+numDoG
             allFiltered{iI,iF}=(allFilteredR{iI,iF}.^2 + allFilteredI{iI,iF}.^2)/2;
        end
    end
 
end


%% prepare for storing experimental results
% multiple-scaled Gobar template
syma = single(zeros(sx, sy)); 
syma_top = zeros(sx, sy); 
if numDoG>0
    numDoGTemplate=1;
else
    numDoGTemplate=0;
end
  
sym = cell(1, numScale + numDoGTemplate); 
for (i = 1 : numScale + numDoGTemplate)
   sym{i} = single(zeros(sx, sy)); 
end
    
% recontructed images
Asym = cell(1, numImg); 
for (i = 1 : numImg)
    Asym{i} = single(zeros(sx, sy)); 
end

% deformed Gabor templates
Asyma = cell(1, numImg); 
for (i = 1 : numImg)
    Asyma{i} = single(zeros(sx, sy)); 
end

% deformed Gabor templates visualized by only a few of top features
Asyma_top = cell(1, numImg); 
for (i = 1 : numImg)
    Asyma_top{i} = single(zeros(sx, sy)); 
end

% deformed DoG templates
Asym0 = cell(1, numImg*(numScale+1));
for (i = 1 : numImg*(numScale+1))
    Asym0{i} = single(zeros(sx, sy));  
end

filterSelected = single(zeros(1, numSketch));
xSelected = single(zeros(1, numSketch));
ySelected = single(zeros(1, numSketch));


%% do matching pursuit
tic;
numSketchSelected = SharedMatchingPursuit(single(numImg), single(numOrient*numScale+numDoG), single(numOrient), single(numDoG), allFilteredR,...
                allFilteredI, allFiltered, Crr, Cri, Cir, Cii, single(half), single(sx), single(sy),...
                allFilterR(1, :), allFilterI(1, :), allSymbol(1, :), syma, sym,...
                Asym, Asym0, Asyma, single(locationShiftLimit), single(orientShiftLimit), single(numSketch),...
                single(epsilon), single(Upperbound), single(SHUTUP), filterSelected, xSelected, ySelected);
 
disp(['finished Matching Pursuit: ' num2str(toc) ' seconds']);
  
 
 %% deformed template for every training image          
 filterSelected = filterSelected(1:numSketchSelected); 
 xSelected = xSelected(1:numSketchSelected);
 ySelected = ySelected(1:numSketchSelected);
 
 
 %% store the matching pursuit version of template
 templateMP=struct('selectedFilter',single(filterSelected),'selectedRow',single(xSelected),'selectedCol',single(ySelected), 'numSelected',single(numSketchSelected),'sym',-syma);
 %%
   

 %[indEliminated, numSelectedFeatures]= createMask(filterSelected,xSelected,ySelected, sx, sy, numOrient, numScale, numDoG);
 [filterSelected, xSelected,ySelected, numSelectedFeatures]= indexTtransformationV2(filterSelected, xSelected, ySelected, sx, sy, numOrient, numScale, numDoG,false);
                                                            
 %% store the Frame version of template
 template=struct('selectedFilter',single(filterSelected),'selectedRow',single(xSelected),'selectedCol',single(ySelected), 'numSelected',single(numSelectedFeatures));

  
 
%% show and save experimental results
tic;
ShowAndSaveResults;
disp(['saving the filter selection results: ' num2str(toc) ' seconds']);

%% generate html to show filter selection experimental results
GenerateHtmlForFilterSelection;




