function initial_TU_Codes=get_valid_code_for_maxi_base(base,NBposition)

% This function retrieves the optimum code from the existing set of codes that
% can be used as initial solution to find the exact codes for the requested
% configuration (M,N).

% Copyright 2015 Abdelmounaime Safia
% Last Revision January, 4, 2015


if (base>2) && (rem(base,2)==0)||(base<2)
    fprintf('\n _________________________________________________________________________________________________________________');
    fprintf('\n \n The spectral resolution ''base'' should be equal to 2 or anny odd natural digit higher than 2');
    fprintf('\n _________________________________________________________________________________________________________________\n');
    initial_TU_Codes=NaN;
    return;
end

%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% Initialisation
CTU_Codes_Loaded=loadexistingcodes();
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% Check if an exact code exists
Curent_CTU_code=get_exact_code(base,NBposition);
if isstruct(Curent_CTU_code)
    fprintf('\n__________________________________________________________');
    fprintf('\n\n Exact CTU codes already exists in your database\n');
    disp(Curent_CTU_code);
    fprintf('__________________________________________________________\n');
    initial_TU_Codes=Curent_CTU_code;
else % An intial code should be found
    [~, nb_spec_res]=size(CTU_Codes_Loaded);
    k=1;
    i=1;
    StrauctPosition_spec_spat_res=zeros(nb_spec_res,3);
    
    
    %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    % Search in the code database for codes corresponding to the same spatial
    % resolution than the target spectral resolution.
    while i<=nb_spec_res
        if CTU_Codes_Loaded(i).SpectralRes==2
            StrauctPosition_spec_spat_res(k,1)=i;
            StrauctPosition_spec_spat_res(k,2)=2;
            StrauctPosition_spec_spat_res(k,3)=-1;
            k=k+1;
            i=i+1;
        end
        [~, temp_pos]=find(CTU_Codes_Loaded(i).SpatialRes==NBposition);
        if ~isempty (temp_pos)
            StrauctPosition_spec_spat_res(k,1)=i;
            StrauctPosition_spec_spat_res(k,2)= CTU_Codes_Loaded(i).SpectralRes;
            StrauctPosition_spec_spat_res(k,3)=temp_pos;
            k=k+1;
        end
        i=i+1;
    end
    
    % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    % At this level, 'StrauctPosition_spec_spat_res' contains information about
    % potential codes which have the same spatial resolution as the requested
    % one(NBposition). The next step will be the selection of the closest
    % spectral resolution to the requested one (base).
    StrauctPosition_spec_spat_res=StrauctPosition_spec_spat_res(1:k-1,:);
    % Selecting the initial codes to be used to speed up the search of the exact code.
    [nn,~]=size(StrauctPosition_spec_spat_res);
    if nn==1 && StrauctPosition_spec_spat_res(1,2)==2
        initial_TU_Codes.valid=0;
        initial_TU_Codes.SpectralRes=2;
        initial_TU_Codes.SpatialRes=NBposition;
        initial_TU_Codes.HistResol=tu_and_ctu_histogram_resolution(2,NBposition,2);
        initial_TU_Codes.code=[1 2];
    else
        % Delete codes corresponding to those with higher base than the target
        % base
        [temp_pos1,~ ]=find(StrauctPosition_spec_spat_res(:,2)<base);
        StrauctPosition_spec_spat_res=StrauctPosition_spec_spat_res(temp_pos1,:);
        
        % Select the highest base
        [~, intial_record] = sort(StrauctPosition_spec_spat_res(:,2), 'descend');
        temp_pos1=intial_record(1);
        
        % position in the structure of the initial spectral resolution
        t1= StrauctPosition_spec_spat_res(temp_pos1,1);
        
        % position in the structure of the initial histogram size which is also
        % the position the spatial resoltion and CTU codes
        t2=StrauctPosition_spec_spat_res(temp_pos1,3);
        
        initial_TU_Codes.valid=0;
        initial_TU_Codes.SpectralRes=CTU_Codes_Loaded(t1).SpectralRes;
        initial_TU_Codes.SpatialRes=CTU_Codes_Loaded(t1).SpatialRes(t2);
        initial_TU_Codes.HistResol=CTU_Codes_Loaded(t1).HistResol(t2);
        initial_TU_Codes.code=CTU_Codes_Loaded(t1).Codes(t2,:);
    end
end
end