function [difficulty, cluster, numTasks, networkDir] = pctdemo_helper_getDefaults()
%PCTDEMO_HELPER_GETDEFAULTS Process the settings in PARALLELDEMOCONFIG.
%   PCTDEMO_HELPER_GETDEFAULTS reads the profile from
%   parallel.defaultClusterProfile and other settings from
%   PARALLELDEMOCONFIG, fills in default values and performs error
%   checking.
%   
%   difficulty = pctdemo_helper_getDefaults() returns the default example  
%   difficulty level.
%   
%   [difficulty, cluster] = pctdemo_helper_getDefaults()
%   uses the default profile with PARCLUSTER to return a cluster object in
%   addition to the example difficulty level.
%   
%   [difficulty, cluster, numTasks] = pctdemo_helper_getDefaults() also 
%   makes sure we have a sensible value for the number of tasks. 
%   
%   [difficulty, cluster, numTasks, networkDir] = pctdemo_helper_getDefaults()
%   also returns the network directory for reading/saving temporary files.
%   
%   See also parallel.defaultClusterProfile, PARALLELDEMOCONFIG, PARCLUSTER

%   Copyright 2007-2012 The MathWorks, Inc.

    config = paralleldemoconfig();

    % Get the example difficulty level.
    difficulty = config.Difficulty;
    
    if (nargout <= 1)
        % If we are not asked to return a cluster object, return now.  This
        % allows the users to run the sequential examples even when there is no 
        % cluster available to us.
        return;
    end
    
    % Get the cluster object.
    try
        cluster = iGetCluster();
    catch err
        rethrow(err);
    end
    % We now have a valid cluster object.
    
    numTasks = config.NumTasks;
    % Get the shared network directory.
    networkDir = config.NetworkDir;
end % End of pctdemo_helper_getDefaults.


function cluster = iGetCluster()
% Tries to return a cluster object.  Errors in case of failure.
    try
        cluster = parcluster;
    catch err
        errorDesc = sprintf(['An error occurred when using the ', ...
            'PARCLUSTER command.  The error message\n', ...
            'received from PARCLUSTER was:\n%s\n'], ...
            err.message);
        iParClusterError(errorDesc);
    end

    % Validates that number of workers is > 0 and the state is running.
   iValidateIfMJS(cluster); 
end % End of iGetCluster.

function iParClusterError(errorMessage)
% Throws an error with a detailed message if we can't find a cluster or if
% the MJS does not have any workers attached to it.
    
    error('pctexample:NoCluster', ...
          ['Could not find an appropriate cluster for the following reason:\n' ...
           '\n' ...
           '%s\n' ...
           '\n' ...
           'See the section "Programming with User Profiles" in the documentation\n' ...
           'for how to set the default profile and modify its values.'], ...
          errorMessage);
end % End of iParClusterError.
    
function iValidateIfMJS(cluster)
%If given an MJS: Throws an error if it does not have at least one worker
%attached to it and is not in the running state.
    if ~isequal(cluster.Type, 'MJS')
        return;
    end
    if ~strcmpi(cluster.State, 'running')
        errorDesc = sprintf(['The MJS cluster ''%s'' is not in the running ', ...
            'state.'], manager.Name);
        iParClusterError(errorDesc);
    end
    if (cluster.NumWorkers == 0)
        errorDesc = sprintf(['The MJS cluster ''%s'' does not have any ', ...
            'workers attached to it.'], cluster.Name);
        iParClusterError(errorDesc);
    end
end % End of iValidateIfMJS.
