%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%LOCAL_procinput
%
%auxiliary function used to take varargin input and distribute 
%it to the parameter structure. If a structure is given as input, it
%is first expanded as a { 'param_name', param_value } list and added at the
%beginning of the remaining list of parameters optionally given in varargin
%
%NB: this function could be external (i.e. not local)
%
%NB II: also deals with sub-structures and structure arrays

function param_struct = local_procinput( param_struct, param_list )

    if isempty( param_list ),
        return
    end
           
    %Special structure input
    if isstruct( param_list{1} ),

        %a structure has been given.
        %Standard situation: simple structure that must be expanded to
        %   fill the parameter values.
        %Special situation: the structure is an array. In this case, 
        %   param_struct is filled as an array of the corresponding size.

        %store structure        
        in_struct = param_list{1}; %input structure
        
        if length( in_struct ) > 1
        
            %structure array given (see comment above)
            %Recursive (and iterative) call
            
            %use original ps as input to avoid fake default generation when
            %a structure array is given as input to fill an empty field
            orig_ps = param_struct(1); 
            
            for ii = 1 : length( in_struct )
            
                param_struct( ii ) = local_procinput( orig_ps, ...
                                        { in_struct( ii ), param_list{ 2 : end } } );
            end
            
            return
            
        end
        
        %as the input structure might be incomplete with respect to param_struct,
        %only update the given fields by expanding the structure
        
        %store structure and field names
        in_fields = fieldnames( in_struct ); %fields of the structure
        
        %remove the structure from the argument list
        param_list(1) = [];
    
        %add the parameters to the BEGINNING of the param list
        tmp = cell( 1, 2 * length( in_fields ) ); %init an empty list
        tmp( 1 : 2 : end - 1 ) = in_fields; %add the 'param_name'
        tmp( 2 : 2 : end ) = struct2cell( in_struct ); %add the param_value
        param_list = [ tmp, param_list ]; %combine with remaining params
    
    end

    %fill param_struct with input

    %Comprehensive list of parameters
    param_names = fieldnames( param_struct );

    %check the fieldnames and fill the structure
    
    for j = 1 : 2 : length( param_list ) - 1,
    
        %loop on user-defined parameters
        
        if any( strcmp( param_names, param_list{j} ) ),
        
            %The user-defined parameter has been recognized.
            %Replace the default value by the user-defined one.
            
            if isstruct( param_struct.( param_list{j} ) )
            
                %a structure is expected as input. Use a recursive call
                %to deal with the filling of this structure. Go down one
                %level in input handling.
                
                %pre-process: make sure the input is in a cell
                if ~iscell( param_list{ j+1 } ), param_list{ j+1 } = param_list( j+1 ); end
                
                %recursive call
                param_struct.( param_list{j} ) = ...
                    local_procinput( param_struct.( param_list{j} ), param_list{ j+1 } );
                    
            else
            
                %standard situation: just fill the field with the user-defined value
                param_struct.( param_list{j} ) = param_list{ j+1 };
                
            end
        
        else
            
            %The user has given an unauthorized parameter.
            error( [ param_list{j}, ' is not an allowed parameter!' ] );
        
        end
        
    end

return