function [ima_fil,ima_fil_int,IDX_fil,IDX_int]=NL_PCA(ima_nse_poiss,...
                       Patch_width,nb_axis,nb_clusters,func_thresholding...
                       ,func_recontruction,func_denoising_patches,...
                       func_clustering,double_iteration,newton,parallel)

% NL_PCA computes the denoising  of a noisy image. It is the main fucntion
% in the entiere NL-PCA process.
%                 
%   INPUT:
%     ima_nse_poiss          : noisy image 
%     Patch_width            : width of the square patches to consider
%  	  nb_axis		         : number of axis/components choosen 
%  	  nb_clusters		     : number of clusters choosen
%     func_thresholding      : only no thresholding is yet supported
%  	  func_recontruction     : build the representaion of the patches
%                              thanks to the model used (gausiann or 
%                              poisson are handle)
%                              (current is the litekmeans)
%     func_denoising_patches : choice of the denoising perform 
%                                (gausiann or poisson are handle)
%     func_clustering	     : method to cluster the patches 
%     double_iteration       : either do the whole process one time (0)
%                              or use the denoised image to improve the 
%                              clustering (1)
%
%   OUTPUT:
%     ima_fil                : final denoised estimate 
%     ima_fil_int            : intermediate denoised estimate (when 
%                              double_iteration=0), otherwise = ima_fil
%     IDX_fil                : final clustering of the patches 
%     IDX_int                : intermediate clustering of the patches (when 
%                              double_iteration=0), otherwise = IDX_fil
%
% [ima_fil,ima_fil_int,IDX_fil,IDX_int]=NL_PCA(ima_nse_poiss,...
%                      Patch_width,nb_axis,nb_clusters,func_thresholding...
%                      ,func_recontruction,func_denoising_patches,...
%                      func_clustering,double_iteration)
%   Produce the denoised image ima_fil from the noisy input ima_nse_poiss
%   using the NL-PCA approach. Intermediate result is given when the
%   process is performed with two iterations. Moreover the indexes IDX_fil
%   ,IDX_int are provided mainly for visualiszing  the clustering 
%   performance.
%
%   Copyright (C) 2012 NL-PCA project
%   Joseph Salmon, Charles-Alban Deledalle, Rebecca Willet, Zachary Harmany
%
%   See The GNU Public License (GPL)

%---------------------------------------------------------------------
%
%   This file is part of NL-PCA.
%
%   NL-PCA is free software: you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as
%   published by the Free Software Foundation, either version 3 of
%   the License, or (at your option) any later version.
%
%   NL-PCA is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public
%   License along with NL-PCA.  If not, see
%   <http://www.gnu.org/licenses/>.
%   Joseph Salmon, Charles-Alban Deledalle, Rebecca Willet, Zachary Harmany
%
%   See The GNU Public License (GPL)


[m,n]=size(ima_nse_poiss);	
ima_patchs = spatial_patchization(ima_nse_poiss , Patch_width);
[ima_patchs_vect,IDX_int]=func_clustering(ima_patchs);
ima_fil_int=denoise_clusters(ima_patchs_vect,func_denoising_patches,func_thresholding,func_recontruction,IDX_int,Patch_width,nb_axis,nb_clusters,m,n,newton,parallel);

% Second iteration when needed
if double_iteration==1       
    ima_patchs2 = spatial_patchization(ima_fil_int, Patch_width);
    [~,IDX_fil]=func_clustering(ima_patchs2);
    ima_fil=denoise_clusters(ima_patchs_vect,func_denoising_patches,func_thresholding,func_recontruction,IDX_fil,Patch_width,nb_axis,nb_clusters,m,n,newton,parallel);
else
    ima_fil=ima_fil_int;
    IDX_fil=IDX_int;    
end
