function [sesInfo] = icatb_runAnalysis(sesInfo, groupICAStep)
%% Run analysis consists of the following options:
% 1. 'All***' - Run all the steps involved in group ICA
% 2. 'Initialize Parameters' - Parameters are intialized after the setup
% ICA analysis
% 3. 'Group Data Reduction' - fMRI data is reduced using the data reduction
% step
% 4. 'Calculate ICA' - Involves calculating ICA - Several Algorithms are
% available
% 5. 'Back Reconstruct' - Performs back reconstruction step
% 6. 'Calibrate Components' - Calibrates the arbitrary parameters to
% percent signal changes
% 7. 'Group Stats' - Perform stats for a group of subjects. For one subject
% one session stats are not performed.

% Inputs:
% 1. sesInfo - structure containing all parameters for analysis
% 2. groupICAStep - Option number like 1 for running all the steps in group
% ICA.

try
    % defaults
    icatb_defaults;
    
    %Screen Color Defaults
    global BG_COLOR;
    global FONT_COLOR;
    global AXES_COLOR;
    global PARAMETER_INFO_MAT_FILE;
    global ZIP_IMAGE_FILES;
    global OPEN_DISPLAY_GUI;
    global SPM_STATS_WRITE_TAL;
    global SPM_STATS_AVG_RUNS;
    
    % Return modality type
    modalityType = icatb_get_modality;
    
    if strcmpi(modalityType, 'fmri')
        helpLabel = 'GIFT-Help';
        htmlFile = 'icatb_run_analysis.htm';
    else
        helpLabel = 'EEGIFT-Help';
        htmlFile = 'icatb_eeg_run_analysis.htm';
    end
    
    % analysis options
    str = str2mat('All***', 'Initialize Parameters', 'Group Data Reduction', 'Calculate ICA', ...
        'Back Reconstruct', 'Calibrate Components', 'Group Stats');
    
    % load parameters file
    filterP = ['*', PARAMETER_INFO_MAT_FILE, '*.mat'];
    
    analysisType = 'batch';
    
    % load valid parameter file
    if ~exist('sesInfo', 'var')
        % show directions about run ica
        [P] = icatb_selectEntry('typeEntity', 'file', 'title', 'Select Parameter File', 'filter', filterP);
        if isempty(P)
            error('Parameter file is not selected for analysis');
        end
        [pathstr, file] = fileparts(P);
        outputDir = pathstr; % output directory
        cd(pathstr);
        load(P);
        if ~exist('sesInfo', 'var')
            error('Not a valid parameter file');
        else
            disp('Parameters file succesfully loaded');
        end
        %% output directory
        sesInfo.outputDir = outputDir; % set the output directory
    else
        outputDir = sesInfo.userInput.pwd;
    end
    
    if isfield(sesInfo.userInput, 'modality')
        if ~strcmpi(modalityType, sesInfo.userInput.modality)
            if strcmpi(sesInfo.userInput.modality, 'fmri')
                error('Use GIFT toolbox to run the analysis on MRI data.');
            else
                error('Use EEGIFT toolbox to run the analysis on EEG data.');
            end
        end
    else
        sesInfo.userInput.modality = modalityType;
    end
    
    sesInfo.outputDir = outputDir;
    
    % choose which steps to preform for group ica
    if ~exist('groupICAStep', 'var')
        InputHandle = icatb_getGraphics('Run Analysis', 'normal', 'Run Analysis'); % figure handle
        set(InputHandle, 'menubar', 'none');
        menu1H = uimenu('parent', InputHandle, 'label', helpLabel); % create a help menu
        menu2H = uimenu(menu1H, 'label', 'Run Analysis', 'callback', ['icatb_openHTMLHelpFile(''', htmlFile, ''');']);
        groupICAStep = icatb_promptUI('popup', 'Which part of analysis do you want to run', str, ...
            'numeric', InputHandle);
        close(InputHandle);
        analysisType = 'GUI';
    end
    
    
    % check the user input
    if isfield(sesInfo, 'userInput')
        if groupICAStep == 1
            userInput = sesInfo.userInput;
            outputDir = sesInfo.outputDir;
            sesInfo = [];
            sesInfo.userInput = userInput;
            sesInfo.outputDir = outputDir;
            clear userInput;
        elseif groupICAStep == 2
            if isfield(sesInfo, 'reduction')
                sesInfo = rmfield(sesInfo, 'reduction');
            end
        end
    else
        error('Please set up parameters for the analysis');
    end
    
    
    sesInfo.modality = sesInfo.userInput.modality;
    
    % performing batch analysis
    output_LogFile = fullfile(sesInfo.outputDir, [sesInfo.userInput.prefix, '_results.log']);
    
    % Print output to a file
    diary(output_LogFile);
    
    % Use tic and toc instead of cputime
    tic;
    
    % Use GUI
    if strcmpi(analysisType, 'gui')
        
        % Include a status bar that shows what percentage of analysis is
        % completed
        titleFig = 'System busy. Please wait...'; perCompleted = 0;
        waitbarTag = [sesInfo.userInput.prefix, 'waitbar'];
        statusHandle = waitbar(perCompleted, titleFig, 'name', [num2str(perCompleted*100), '% analysis done'], ...
            'DefaultTextColor', FONT_COLOR, 'DefaultAxesColor', AXES_COLOR, 'color', BG_COLOR, 'tag', waitbarTag);
        
        % Number of calls per function where most of the time is spent in
        % analysis
        numberOfCalls_function = 3;
        
        % Unit Percentage of analysis completed
        if groupICAStep ~=1
            % display waitbar
            unitPerCompleted = 1 / (numberOfCalls_function);
        else
            unitPerCompleted = 1 / (numberOfCalls_function*(size(str, 1) - 1));
        end
        
        statusData.unitPerCompleted = unitPerCompleted;
        statusData.perCompleted = 0;
        
        set(statusHandle, 'userdata', statusData);
        
    else
        statusHandle = [];
        disp('Starting Analysis ');
        fprintf('\n');
    end
    
    % parameter initialization
    if(groupICAStep == 1 || groupICAStep == 2)
        [sesInfo] = icatb_parameterInitialization(sesInfo, statusHandle);
    end
    
    % Data reduction
    if(groupICAStep == 1 || groupICAStep == 3)
        [sesInfo] = icatb_dataReduction(sesInfo, statusHandle);
    end
    
    % Calculate ICA
    if(groupICAStep == 1 || groupICAStep == 4)
        [sesInfo] = icatb_calculateICA(sesInfo, statusHandle);
    end
    
    % Back Reconstruction
    if(groupICAStep == 1 || groupICAStep == 5)
        [sesInfo] = icatb_backReconstruct(sesInfo, statusHandle);
    end
    
    % Calibrate Components
    if(groupICAStep == 1 || groupICAStep == 6)
        [sesInfo] = icatb_calibrateComponents(sesInfo, statusHandle);
    end
    
    % Group Stats
    if(groupICAStep == 1 || groupICAStep == 7)
        [sesInfo] = icatb_groupStats(sesInfo, statusHandle);
    end
    
    if strcmpi(analysisType, 'gui')
        % Analysis is complete
        waitbar(1, statusHandle, 'Analysis Complete.');
        close(statusHandle);
    end
    
    % Use tic and toc instead of cputime
    t_end = toc;
    
    % Suspend diary
    diary('off');
    
    disp(['Time taken to run the analysis is ', num2str(t_end), ' seconds']);
    
    disp(['All the analysis information is stored in the file ', output_LogFile]);
    
    disp('Finished with Analysis');
    fprintf('\n');
    
    % save the parameter file
    parameter_file = fullfile(sesInfo.outputDir, [sesInfo.param_file, '.mat']);
    icatb_save(parameter_file, 'sesInfo');
    
    % DO SPM STATS
    if sesInfo.numOfSub*sesInfo.numOfSess > 1
        if (groupICAStep == 1 || groupICAStep == 7)
            if strcmpi(modalityType, 'fmri')
                if (SPM_STATS_WRITE_TAL)
                    % Average runs
                    icatb_spm_avg_runs(parameter_file);
                    disp('Running one sample t-test on subject component maps ...');
                    fprintf('\n');
                    
                    if SPM_STATS_AVG_RUNS
                        group = (1:sesInfo.numOfSub);
                    else
                        group = (1:sesInfo.numOfSub*sesInfo.numOfSess);
                    end
                    
                    % Compute one sample t-test on subject maps using SPM
                    icatb_spm_stats(parameter_file, 1, 'Group 1', group, [], [], ...
                        (1:sesInfo.numComp), SPM_STATS_WRITE_TAL, SPM_STATS_AVG_RUNS);
                    fprintf('\n');
                    disp('Done running one sample t-test on subject component maps');
                    fprintf('\n');
                end
            end
        end
    end
    % END FOR DOING SPM STATS
    
    if OPEN_DISPLAY_GUI
        if(groupICAStep == 1 || groupICAStep == 7)
            if strcmpi(modalityType, 'fmri')
                % Open fMRI GUI
                icatb_displayGUI(parameter_file);
            else
                % Open EEG display GUI
                icatb_eeg_displayGUI(parameter_file);
            end
            
        end
    end
    
catch
    
    if exist('sesInfo', 'var')
        % display information to the user
        diary('off');
        if ~strcmpi(analysisType, 'batch')
            % close the status bar
            if ishandle(statusHandle)
                delete(statusHandle);
            end
        end
    end
    
    % Display error message
    icatb_displayErrorMsg;
    
end