function [X_Center , Y_Center] =fGenerateParameterSubsetPatches(methodROI,NPatches, PatchesSize,ImTrimmedSize,Param )
% The purpose of this function is to generate Random position for NPacthes,
% the output of this function can be used as an argument for fPickPatches.
% % % % % % % % % % % % % % % % % % % 
%       INPUTs
% % % % % % % % % % % % % % % % % % 
% methodROI                 <string> {'Upper', 'Lower', 'Left', 'Right','Eccentricity', 'Manual'} ROI selection mode. All options except 'Manual' are EXPERIMENTAL.
% NPatches                  [1] Number of Generated Patches
% PatchesSize               [2] Size of extracted patches in pixels [X Y]
% ImTrimmedSize.Ang         [2] Size of the Trimmed Image in visual angle
% ImTrimmedSize.Pix         [2] Size of the Trimmed Image in pixels
% Param                     <optional>
% Param.Eccentricity.Min    [1] <Used only if ROI = Eccentricity>; Exemple for select eccentricity between 0 and 2 degreee use :  Param.Eccentricity.Min = 0 & Param.Eccentricity.Max =2;
% Param.Eccentricity.Max    [1] <Used only if ROI = Eccentricity>;
% Param.AvailablePosition   <boolean> [ImTrimmedSize.Pix] Same size than the Trimmed Image, put true for available patches's centers positions
% 
% % % % % % % % % % % % % % % % 
%       OUTPUTs
% % % % % % % % % % % % % % % % 
% X_Center                  [Npatches]
% Y_Center                  [Npatches]
% 
%% Convert position in visual angle cartesian and polar coordinates

PPA  = ImTrimmedSize.Pix ./ ImTrimmedSize.Ang; 
HalfPatchAng = PatchesSize./(2*PPA) ;

% Compute eccentricity for each pixel ( note that this excludes pixels near edges ... )
[XX, YY] = meshgrid( linspace( - ImTrimmedSize.Ang(1)/2 + HalfPatchAng(1), ImTrimmedSize.Ang(1)/2 - HalfPatchAng(1), ImTrimmedSize.Pix(1) - PatchesSize(1) ) , linspace( - ImTrimmedSize.Ang(2)/2 + HalfPatchAng(2), ImTrimmedSize.Ang(2)/2 - HalfPatchAng(2), ImTrimmedSize.Pix(2) - PatchesSize(2)  ) ) ;
YY = flipud(YY);

XX = XX(:); 
YY = YY(:);

Eccentricity  = (XX .^2 + YY .^2).^(1/2);

%% Pick centers of Patches from the subset of available positions

switch lower(methodROI)
    case lower('Upper')
      X_Center = round(randi([ ceil(PatchesSize(1)./2)  ceil(ImTrimmedSize.Pix(1)-PatchesSize(1)./2)], NPatches ,1 ));
      Y_Center = round(randi([ceil(ImTrimmedSize.Pix(2)/2) ImTrimmedSize.Pix(2)], NPatches ,1 ));
      
    case lower('Lower')
      X_Center = round(randi([ ceil(PatchesSize(1)./2)  ceil(ImTrimmedSize.Pix(1)-PatchesSize(1)./2)], NPatches ,1 ));          
      Y_Center = round(randi([0 ceil(ImTrimmedSize.Pix(2)/2)], NPatches ,1 ));
      
    case lower('Left')
      X_Center = round(randi([ceil(PatchesSize(1)./2) ceil(ImTrimmedSize.Pix(1)/2)], NPatches ,1 ));
      Y_Center = round(randi([0  ImTrimmedSize.Pix(2)], NPatches ,1 ));
      
    case lower('Right')
      X_Center = round(randi([ceil(ImTrimmedSize.Pix(1)/2)  ceil(ImTrimmedSize.Pix(1)-PatchesSize(1)./2)], NPatches ,1 ));
      Y_Center = round(randi([0  ImTrimmedSize.Pix(2)], NPatches ,1 ));
      
    case lower('Eccentricity')
      if( exist('Param', 'var') == 0)
          disp(' Error from fSelectPatches: You used "Eccentricity" mode without the associated "Param" ');      
      end
      if (~ isfield(Param, 'Eccentricity')) 
          disp(' Error from fSelectPatches: You used "Eccentricity" mode but without "Param.Eccentricity" ');  
      end
      if ( ( ~ isfield(Param.Eccentricity, 'Min') ) || ( ~ isfield(Param.Eccentricity, 'Max') ) ) 
          disp(' Error from fSelectPatches: You used "Eccentricity" mode without "Param.Eccentricity.Min" & "Param.Eccentricity.Max" ');  
      end

      idxAvailable = find(Eccentricity >= Param.Eccentricity.Min & Eccentricity <= Param.Eccentricity.Max) ;     
      idx = idxAvailable( randi(length(idxAvailable), NPatches,1) ) ; % Pick NPatches random positions from available positions

      [X_Center , Y_Center] = ind2sub([(ImTrimmedSize.Pix(1) - PatchesSize(1)) (ImTrimmedSize.Pix(2) - PatchesSize(2))], idx) ;
      X_Center = X_Center + floor( PatchesSize(1)/2 );
      Y_Center = Y_Center + floor( PatchesSize(2)/2 );
      
    case lower('Manual')
      if( exist('Param', 'var') == 0)
          disp(' Error from fSelectPatches: You used "Manual" mode but without the associated "Param" ');
      end
      if (~ isfield(Param, 'AvailablePosition')) 
          disp(' Error from fSelectPatches: You used "Manual" mode without "Param.AvailablePosition" ');  
      end
      if( (size(Param.AvailablePosition, 2) ~= ImTrimmedSize.Pix(1) ) || (size(Param.AvailablePosition, 1) ~= ImTrimmedSize.Pix(2) ))
          disp(' Error from fSelectPatches: size of "Param.AvailablePosition" should be the same as "ImTrimmedSize.Pix" ') ; 
      end
      
     idxAvailable = find(Param.AvailablePosition);
     idx = idxAvailable( randi(length(idxAvailable), NPatches,1) ) ;
     [X_Center , Y_Center] = ind2sub([ImTrimmedSize.Pix(2) ImTrimmedSize.Pix(1)], idx) ;
      
    otherwise   
    disp('Error from fSelectPatches: The ROI selection mode is invalid. See help for available modes.');
    
end