% POP_CLUSTEDIT - graphic user interface (GUI)-based function with editing and plotting 
%                options for visualizing and manipulating an input STUDY structure. 
%                Only component measures (e.g., dipole locations, scalp maps, spectra, 
%                ERPs, ERSPs, ITCs) that have been computed and saved in the study EEG 
%                datasets can be visualized. These can be computed during pre-clustering 
%                using the GUI-based function POP_PRECLUST or the equivalent command
%                line functions STD_PRECLUST. To use dipole locations for clustering, 
%                they must first be stored in the EEG dataset structures using DIPFIT. 
%                Supported cluster editing functions include new cluster creation, cluster 
%                merging, outlier rejection, and cluster renaming. Components can also be 
%                moved from one cluster to another or to the outlier cluster. 
% Usage:    
%                >> STUDY = pop_clustedit(STUDY, ALLEEG, clusters, addui, addgeom);   
% Inputs:
%   ALLEEG     - Top-level EEGLAB vector of loaded EEG structures for the dataset(s) 
%                in the STUDY. ALLEEG for a STUDY set is typically loaded using 
%                POP_LOADSTUDY, or in creating a new STUDY, using POP_CREATESTUDY.  
%   STUDY      - EEGLAB STUDY set comprising some or all of the EEG datasets in ALLEEG.
%
% Optional inputs:
%   clusters   - [integer vector] of cluster numbers. These clusters will be visualized 
%                and manipulated in the POP_CLUSTEDIT graphic interface. There are 
%                restrictions on which clusters can be loaded together. The clusters must 
%                either originate from the same clustering (same PRE_CLUSTERING and 
%                subsequent POP_CLUST execution), or they must all be leaf clusters 
%                (i.e., clusters with no child clusters) {default: all leaf clusters}.
%   addui      - [struct] additional uicontrols entries for the graphic
%                interface. Must contains the fields "uilist", "geometry".
%
% Outputs:
%   STUDY      - The input STUDY set structure modified according to specified user edits,
%                if any. Plotted cluster measure means (maps, ERSPs, etc.) are added to 
%                the STUDY structure after they are first plotted to allow quick replotting.  
%
% Graphic interface buttons:
%  "Select cluster to plot" - [list box] Displays available clusters to plot (format is
%                'cluster name (number of components)'). The presented clusters depend 
%                on the optional input variable 'clusters'. Selecting (clicking on) a 
%                cluster from the list will display the selected cluster components in the 
%                "Select component(s) to plot" list box. Use the plotting buttons below 
%                to plot selected measures of the selected cluster. Additional editing 
%                options (renaming the cluster, rejecting outliers, moving components to 
%                another cluster) are also available. The option 'All N cluster centroids' 
%                at the top of the list displays all the clusters in the list except the 
%                'Notcluster', 'Outlier' and 'ParentCluster' clusters. Selecting this option 
%                will plot the cluster centroids (i.e. ERP, ERSP, ...) in a single figure.
%  "Select component(s) to plot" - [list box] Displays the ICA components of the currently 
%                selected cluster (in the "Select cluster to plot" list box). Each component 
%                has the format: 'subject name, component index'. Multiple components can be 
%                selected from the list. Use the plotting buttons below to plot different 
%                measures of the selected components on different figures. Selecting the 
%                "All components" option is  equivalent to using the cluster plotting buttons. 
%                Additional editing options are reassigning the selected components to 
%                another cluster or moving them to the outlier cluster.
%  "Plot Cluster properties" - [button] Displays in one figure all the mean cluster measures
%                (e.g., dipole locations, scalp maps, spectra, etc.) that were calculated
%                and saved in the EEG datasets. If there is more than one condition, the ERP 
%                and the spectrum will have different colors for each condition. The ERSP 
%                and ITC plots will show only the first condition; clicking on the subplot 
%                will open a new figure with the different conditions displayed together. 
%                Uses the command line function STD_PROPPLOT.
%  "Plot scalp maps"  - [button] Displays the scalp maps of cluster components.
%                If applied to a cluster, scalp maps of the cluster components
%                are plotted along with the cluster mean scalp map in one figure. 
%                If "All # cluster centroids" option is selected, all cluster scalp map
%                means are plotted in the same figure. If applied to components, displays
%                the scalp maps of the specified cluster components in separate figures.
%                Uses the command line functions STD_TOPOPLOT.
%  "Plot ERSPs" - [button] Displays the cluster component ERSPs. 
%                If applied to a cluster, component ERSPs are plotted in one figure  
%                (per condition) with the cluster mean ERSP. If "All # cluster centroids" 
%                option is selected, plots all average ERSPs of the clusters in one figure 
%                per condition. If applied to components, display the ERSP images of specified 
%                cluster components in separate figures, using one figure for all conditions.
%                Uses the command line functions STD_ERSPPLOT.
%  "Plot ITCs" - [button] Same as  "Plot ERSPs" but with ITC.
%                Uses the command line functions STD_ITCPLOT.
%  "Plot dipoles" - [button] Displays the dipoles of the cluster components.
%                If applied to a cluster, plots the cluster component dipoles (in blue) 
%                plus the average cluster dipole (in red). If "All # cluster centroids" option 
%                is selected, all cluster plots are displayed in one figure each cluster in 
%                a separate subplot. If applied to components, displays the ERSP images of the
%                specified cluster. For specific components displays components dipole (in blue) 
%                plus the average cluster dipole (in Red) in separate figures. 
%                Uses the command line functions STD_DIPPLOT.
%  "Plot spectra" - [button] Displays the cluster component spectra.   
%                If applied to a cluster, displays component spectra plus the average cluster 
%                spectrum in bold. For a specific cluster, displays the cluster component 
%                spectra plus the average cluster spectrum (in bold) in one figure per condition.
%                If the "All # cluster centroids" option is selected, displays the average 
%                spectrum of all clusters in the same figure, with spectrum for different 
%                conditions (if any) plotted in different colors.  
%                If applied to components, displays the spectrum of specified cluster 
%                components in separate figures using one figure for all conditions.  
%                Uses the command line functions STD_SPECPLOT.
%  "Plot ERPs" - [button] Same as "Plot spectra" but for ERPs.
%                Uses the command line functions STD_ERPPLOT.
%  "Plot ERPimage" - [button] Same as "Plot ERP" but for ERPimave.
%                Uses the command line functions STD_ERPIMPLOT.
%  "Create new cluster" - [button] Creates a new empty cluster.
%                Opens a popup window in which a name for the new cluster can be entered.
%                If no name is given the default name is 'Cls #', where '#' is the next
%                available cluster number. For changes to take place, press the popup 
%                window 'OK' button, else press the 'Cancel' button. After the empty 
%                cluster is created, components can be moved into it using, 
%                'Reassign selected component(s)' (see below). Uses the command line 
%                function STD_CREATECLUST.
%  "Rename selected cluster" - [button] Renames a cluster using the selected (mnemonic) name. 
%                Opens a popup window in which a new name for the selected cluster can be 
%                entered. For changes to take place, press the popup window 'OK' button, 
%                else press the 'Cancel' button. Uses the command line function STD_RENAMECLUST.
%  "Reject outlier components" - [button] rejects outlier components to an outlier cluster.
%                Opens a popup window to specify the outlier threshold. Move outlier 
%                components that are more than x standard deviations devs from the 
%                cluster centroid to an outlier cluster. For changes to take place, 
%                press the popup window 'OK' button, else press the 'Cancel' button. 
%                Uses the command line function STD_REJECTOUTLIERS.
%  "Merge clusters" - [button] Merges several clusters into one cluster.
%                Opens a popup window in which the clusters to merge may be specified 
%                An optional name can be given to the merged cluster. If no name is given, 
%                the default name is 'Cls #', where '#' is the next available cluster number.   
%                For changes to take place, press the popup window 'OK' button, else press
%                the 'Cancel' button. Uses the command line function STD_MERGECLUST.
%  "Remove selected outlier component(s)" - [button] Moves selected component(s) to the 
%                outlier cluster. The components that will be moved are the ones selected 
%                in the "Select component(s) to plot" list box. Opens a popup window in which 
%                a list of the selected component(s) is presented. For changes to take place,
%                press the popup window 'OK' button, else press the 'Cancel' button. 
%                Uses the command line function STD_MOVEOUTLIER.
%  "Reassign selected component(s)" - [button] Moves selected component(s) from one cluster 
%                to another. The components that will reassign are the ones selected in the
%                "Select component(s) to plot" list box. Opens a popup window in which 
%                a list of possible clusters to which to move the selected component(s) is 
%                presented. For changes to take place, press the popup window 'OK' button, 
%                else press the 'Cancel' button. Uses the command line function STD_MOVECOMP.
%  "Save STUDY set to disk" - [check box] Saves the STUDY set structure modified according 
%                to specified user edits to the disk. If no file name is entered will
%                overwrite the current STUDY set file. 
%
% See also:  POP_PRECLUST, POP_CLUST.         
%
% Authors: Arnaud Delorme, Hilit Serby, Scott Makeig, SCCN/INC/UCSD, October 11, 2004

% Copyright (C) Hilit Serby, SCCN, INC, UCSD, October 11, 2004, hilit@sccn.ucsd.edu
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

function [STUDY, com] = pop_clustedit(varargin)
icadefs;

if nargin < 2
    help pop_clustedit;
    return;
end

if ~ischar(varargin{1})
    STUDY  = varargin{1};
    STUDY.etc.erpparams.topotime    = NaN; % [] for channels and NaN for components
    STUDY.etc.specparams.topofreq   = NaN; % NaN -> GUI disabled
    STUDY.etc.erspparams.topotime   = NaN;
    STUDY.etc.erspparams.topofreq   = NaN;
    STUDY.etc.erpimparams.topotime  = NaN;
    STUDY.etc.erpimparams.topotrial = NaN;
    STUDY.tmphist = '';
    ALLEEG = varargin{2};
    clus_comps = 0; % the number of clustered components
    if nargin > 2 && ~isempty(varargin{3}) % load specific clusters
        cls = varargin{3}; %cluster numbers
        N = length(cls); %number of clusters
        
        % Check clusters are either from the same level (same parents) or are
        % all leaf clusters.
        % Check all input clusters have the same parent
        
        sameparent = 1;
        for k = 1: N
            % Assess the number of clustered components
            if (~strncmpi('Notclust',STUDY.cluster(cls(k)).name,8))  && (~strncmpi('ParentCluster',STUDY.cluster(cls(k)).name,13))
                clus_comps = clus_comps + length(STUDY.cluster(cls(k)).comps);
            end
            if k == 1
                parent = STUDY.cluster(cls(k)).parent;
            else
                if isempty(parent) % if the first cluster was the parent cluster
                    parent = STUDY.cluster(cls(k)).parent;
                end
                % For any other case verify that all clusters have the same parents
                if ~(sum(strcmp(STUDY.cluster(cls(k)).parent, parent)) == length(parent)) % different parent
                    if ~strcmp(STUDY.cluster(cls(k)).parent,'manual') && ~strcmp(parent, 'manual') 
                        % if neither is an empty cluster (which was created manually)
                        sameparent = 0; % then the clusters have different parents
                    end
                end
            end
        end
        
        % If not same parent check if all leaf clusters 
        % ---------------------------------------------
        if ~sameparent
            for k = 1: N %check if all leaves
                 if ~isempty(STUDY.cluster(cls(k)).child) 
                     error([ 'pop_clustedit(): All clusters must be from the same level \n' ...
                             '         (i.e., have the same parents or not be child clusters)' ]);
                 end
            end
        end

        % plotting text etc ...
        % --------------------
        num_cls = 0;
        for k = 1:N
            show_options{k+1} = [STUDY.cluster(cls(k)).name ' (' num2str(length(STUDY.cluster(cls(k)).comps))  ' ICs)'];
            if (~strncmpi('Notclust',STUDY.cluster(cls(k)).name,8)) && (~strncmpi('Outliers',STUDY.cluster(cls(k)).name,8))  && ...
                    (~strncmpi('ParentCluster',STUDY.cluster(cls(k)).name,13))
                num_cls = num_cls + 1;
            end
        end
        show_options{1} = ['All ' num2str(num_cls) ' cluster centroids'];
        
    else   % load leaf clusters
        
        sameparent = 1;
        cls = [];
        for k = 2:length(STUDY.cluster)
            if isempty(STUDY.cluster(k).child) 
                if isempty(cls)
                    parent = STUDY.cluster(k).parent;
                elseif ~isempty(STUDY.cluster(k).parent)  || ~isempty(parent) % if not both empty                          
                    % Check if all parents are the same
                    if ~(sum(strcmp(STUDY.cluster(k).parent, parent)) == length(parent)) % different parent
                        if ~strcmp(STUDY.cluster(k).parent,'manual') && ~strcmp(parent, 'manual') 
                            sameparent = 0;
                        end
                    end
                end
                cls = [ cls k];
                if ~strncmpi('Notclust',STUDY.cluster(k).name,8)
                     clus_comps = clus_comps + length(STUDY.cluster(k).comps);
                 end
            end
        end
        
    
        % Plot clusters hierarchically
        % ----------------------------
        num_cls = 0;
        cls = 1:length(STUDY.cluster);
        N = length(cls); %number of clusters
        
        show_options{1} = [STUDY.cluster(1).name ' (' num2str(length(STUDY.cluster(1).comps))  ' ICs)'];
        cls(1) = 1;
        count = 2;
        for index1 = 1:length(STUDY.cluster(1).child)
            
            indclust1 = strmatch( STUDY.cluster(1).child(index1), { STUDY.cluster.name }, 'exact');
            show_options{count} = ['   ' STUDY.cluster(indclust1).name ' (' num2str(length(STUDY.cluster(indclust1).comps))  ' ICs)'];
            cls(count) = indclust1;
            count = count+1;
            
            for index2 = 1:length( STUDY.cluster(indclust1).child )
                indclust2 = strmatch( STUDY.cluster(indclust1).child(index2), { STUDY.cluster.name }, 'exact');
                show_options{count} = ['      ' STUDY.cluster(indclust2).name ' (' num2str(length(STUDY.cluster(indclust2).comps))  ' ICs)'];
                cls(count) = indclust2;
                count = count+1;
                    
                for index3 = 1:length( STUDY.cluster(indclust2).child )
                    indclust3 = strmatch( STUDY.cluster(indclust2).child(index3), { STUDY.cluster.name }, 'exact');
                    show_options{count} = ['         ' STUDY.cluster(indclust3).name ' (' num2str(length(STUDY.cluster(indclust3).comps))  ' ICs)'];
                    cls(count) = indclust3;
                    count = count+1;
                end
            end
        end
        show_options = { ['All cluster centroids'] show_options{:} }; 
    end
    all_comps = length(STUDY.cluster(1).comps);
    
    show_clust_gcf  = [ 'pop_clustedit(''showclust'',gcf);'];
    show_clust      = [ 'pop_clustedit(''showclust'',gcbf);'];
    show_comps      = [ 'pop_clustedit(''showcomplist'',gcbf);'];
	plot_clus_maps  = [ 'pop_clustedit(''topoplot'',gcbf); ']; 
    plot_comp_maps  = [ 'pop_clustedit(''plotcomptopo'',gcbf); ']; 
    plot_clus_ersps = ['pop_clustedit(''erspplot'',gcbf); '];
    plot_comp_ersps = ['pop_clustedit(''plotcompersp'',gcbf); '];
    plot_clus_itcs  = ['pop_clustedit(''itcplot'',gcbf); '];
    plot_comp_itcs  = ['pop_clustedit(''plotcompitc'',gcbf); '];
    plot_clus_erpim = ['pop_clustedit(''erpimageplot'',gcbf); '];
    plot_comp_erpim = ['pop_clustedit(''plotcomperpimage'',gcbf); '];
    plot_clus_spectra = ['pop_clustedit(''specplot'',gcbf); '];
    plot_comp_spectra = ['pop_clustedit(''plotcompspec'',gcbf); '];
    plot_clus_erp = ['pop_clustedit(''erpplot'',gcbf); '];
    plot_comp_erp = ['pop_clustedit(''plotcomperp'',gcbf); '];
    plot_clus_dip = ['pop_clustedit(''dipplot'',gcbf); '];
    plot_comp_dip = ['pop_clustedit(''plotcompdip'',gcbf); '];
    plot_clus_sum = ['pop_clustedit(''plotsum'',gcbf); '];
    plot_comp_sum = ['pop_clustedit(''plotcompsum'',gcbf); '];
    rename_clust  = ['pop_clustedit(''renameclust'',gcbf);']; 
    move_comp     = ['pop_clustedit(''movecomp'',gcbf);'];
    move_outlier  = ['pop_clustedit(''moveoutlier'',gcbf);'];
    create_clus   = ['pop_clustedit(''createclust'',gcbf);'];
    reject_outliers = ['pop_clustedit(''rejectoutliers'',gcbf);'];
    merge_clusters = ['pop_clustedit(''mergeclusters'',gcbf);'];
    dip_opt        = ['pop_clustedit(''dip_opt'',gcbf);'];
    erp_opt        = ['pop_clustedit(''erp_opt'',gcbf);'];
    spec_opt       = ['pop_clustedit(''spec_opt'',gcbf);'];
    ersp_opt       = ['pop_clustedit(''ersp_opt'',gcbf);'];
    erpim_opt      = ['pop_clustedit(''erpim_opt'',gcbf);'];
    stat_opt       = ['pop_clustedit(''stat_opt'',gcbf);'];
    saveSTUDY      = [ 'set(findobj(''parent'', gcbf, ''userdata'', ''save''), ''enable'', fastif(get(gcbo, ''value'')==1, ''on'', ''off''));' ];
    browsesave     = [ '[filename, filepath] = uiputfile2(''*.study'', ''Save STUDY with .study extension -- pop_clust()''); ' ... 
                      'set(findobj(''parent'', gcbf, ''tag'', ''studyfile''), ''string'', [filepath filename]);' ];
    
    % Create default ERSP / ITC time/freq. parameters 
    % ----------------------------------------------
    if isempty(ALLEEG)
        error('STUDY contains no datasets');
    end

    % enable buttons
    % --------------
    filename = fullfile(STUDY.datasetinfo(1).filepath, STUDY.datasetinfo(1).subject);
    if ~isempty(dir([filename '*.icaspec'])),   spec_enable = 'on'; else spec_enable  = 'off'; end
    if ~isempty(dir([filename '*.icaerp'] )) ,   erp_enable = 'on'; else erp_enable   = 'off'; end
    if ~isempty(dir([filename '*.icaerpim'] )), erpim_enable = 'on'; else erpim_enable = 'off'; end
    if ~isempty(dir([filename '*.icatimef'])) ,   ersp_enable = 'on'; else ersp_enable  = 'off'; end
    filename = fullfile( ALLEEG(1).filepath, ALLEEG(1).filename(1:end-4));
    if ~isempty(dir([filename '*.icatopo'])), scalp_enable = 'on'; else scalp_enable = 'off'; end
    
    if isfield(ALLEEG(1).dipfit, 'model'), dip_enable   = 'on'; else dip_enable   = 'off'; end
    
    % userdata below
    % --------------
    fig_arg{1}{1} = ALLEEG;
    fig_arg{1}{2} = STUDY;
    fig_arg{1}{3} = cls;
    fig_arg{2}    = N;
        
    str_name       = sprintf('STUDY ''%s'' - ''%s'' component clusters', STUDY.name, STUDY.design(STUDY.currentdesign).name);
    if length(str_name) > 80, str_name = [ str_name(1:80) '...''' ]; end
    if length(cls) > 1, vallist = 1; else vallist = 2; end
    geomline = [1 0.35 1];
    geometry = { [0.8 3] [1] geomline geomline geomline geomline geomline geomline geomline geomline ...
                 geomline [1] geomline geomline }; %geomline };
    geomvert = [ 1 .5 1 3 1 1 1 1 1 1 1 1 1 1 ]; %1];
    uilist   = { ...
        {'style' 'text'       'string' 'Select design:' 'FontWeight' 'Bold' 'HorizontalAlignment' 'center'} ...
        {'style' 'popupmenu'  'string' { STUDY.design.name } 'FontWeight' 'Bold' 'tag' 'design' 'value' STUDY.currentdesign  } ...
        { } ...
        {'style' 'text'       'string' 'Select cluster to plot' 'FontWeight' 'Bold' } {} ...
        {'style' 'text'       'string' 'Select component to plot        ' 'FontWeight' 'Bold'} ...
        {'style' 'listbox'    'string' show_options 'value' vallist 'tag' 'clus_list' 'Callback' show_clust } ...
        {'style' 'pushbutton' 'enable'   'on'       'string' 'STATS' 'Callback' stat_opt }  ...
        {'style' 'listbox'    'string' '' 'tag' 'clust_comp' 'max' 2 'min' 1 'callback'    show_comps } ... 
        {'style' 'pushbutton' 'enable' scalp_enable 'string' 'Plot scalp maps' 'Callback' plot_clus_maps} {} ...
        {'style' 'pushbutton' 'enable' scalp_enable 'string' 'Plot scalp map(s)' 'Callback' plot_comp_maps}...
        {'style' 'pushbutton' 'enable'   dip_enable 'string' 'Plot dipoles' 'Callback' plot_clus_dip}  ...
        {'style' 'pushbutton' 'enable'   dip_enable 'string' 'Params' 'Callback' dip_opt }  ...
        {'style' 'pushbutton' 'enable'   dip_enable 'string' 'Plot dipole(s)' 'Callback' plot_comp_dip}...
        {'style' 'pushbutton' 'enable'   erp_enable 'string' 'Plot ERPs' 'Callback' plot_clus_erp} ...
        {'style' 'pushbutton' 'enable'   erp_enable 'string' 'Params' 'Callback' erp_opt }  ...
        {'style' 'pushbutton' 'enable'   erp_enable 'string' 'Plot ERP(s)' 'Callback' plot_comp_erp} ...
        {'style' 'pushbutton' 'enable'  spec_enable 'string' 'Plot spectra' 'Callback' plot_clus_spectra} ...
        {'style' 'pushbutton' 'enable'  spec_enable 'string' 'Params' 'Callback' spec_opt } ...
        {'style' 'pushbutton' 'enable'  spec_enable 'string' 'Plot spectra' 'Callback' plot_comp_spectra} ...
        {'style' 'pushbutton' 'enable' erpim_enable 'string' 'Plot ERPimage' 'Callback' plot_clus_erpim} ...
        {'style' 'pushbutton' 'enable' erpim_enable 'string' 'Params' 'Callback' erpim_opt } ...
        {'style' 'pushbutton' 'enable' erpim_enable 'string' 'Plot ERPimage(s)' 'Callback' plot_comp_erpim} ...
        {'style' 'pushbutton' 'enable'  ersp_enable 'string' 'Plot ERSPs' 'Callback' plot_clus_ersps} ...
        {'vertexpand' 2.1 'style' 'pushbutton' 'enable'  ersp_enable 'string' 'Params' 'Callback' ersp_opt } ...
        {'style' 'pushbutton' 'enable'  ersp_enable 'string' 'Plot ERSP(s)' 'Callback' plot_comp_ersps} ...
        {'style' 'pushbutton' 'enable'  ersp_enable 'string' 'Plot ITCs' 'Callback' plot_clus_itcs} { } ...
        {'style' 'pushbutton' 'enable'  ersp_enable 'string' 'Plot ITC(s)' 'Callback' plot_comp_itcs} ...
        ... % {} {}... %{'style' 'pushbutton' 'string' 'Plot cluster properties' 'Callback' plot_clus_sum 'enable' 'off'} {} ... 
        ... % {'style' 'pushbutton' 'string' 'Plot component properties' 'Callback' plot_comp_sum 'enable' 'on'} ... % nima, was off
        {} ...
        {'style' 'pushbutton' 'string' 'Create new cluster' 'Callback'  create_clus} {} ...
        {'style' 'pushbutton' 'string' 'Reassign selected component(s)' 'Callback' move_comp} ...
        {'style' 'pushbutton' 'string' 'Rename selected cluster' 'Callback' rename_clust } {} ...
        {'style' 'pushbutton' 'string' 'Remove selected outlier comps.' 'Callback' move_outlier} };
%        {'style' 'pushbutton' 'string' 'Merge clusters' 'Callback' merge_clusters } {} ...
%        {'style' 'pushbutton' 'string' 'Auto-reject outlier components' 'Callback' reject_outliers } };
   
   % additional UI given on the command line
   % ---------------------------------------
   if nargin > 3
       addui = varargin{4};
       if ~isfield(addui, 'uilist')
           error('Additional GUI definition (argument 4) requires the field "uilist"');
       end
       if ~isfield(addui, 'geometry')
           addui.geometry = mat2cell(ones(1,length(addui.uilist)));
       end
       uilist = { uilist{:}, addui.uilist{:} };
       geometry = { geometry{:} addui.geometry{:} };
       geomvert = [ geomvert ones(1,length(addui.geometry)) ];
   end
   
   [out_param, userdat] = inputgui( 'geometry' , geometry, 'uilist', uilist, ...
                                   'helpcom', 'pophelp(''pop_clustedit'')', ...
                                   'title', 'View and edit current component clusters -- pop_clustedit()' , 'userdata', fig_arg, ...
                                   'geomvert', geomvert, 'eval', show_clust_gcf );
	
   if ~isempty(userdat)
       ALLEEG = userdat{1}{1};
       STUDY = userdat{1}{2};
   end
   
   % history
   % -------
   com = STUDY.tmphist;
   STUDY = rmfield(STUDY, 'tmphist');
 
else
    hdl = varargin{2};  %figure handle
    userdat = get(varargin{2}, 'userdat');    
    ALLEEG  = userdat{1}{1};
    STUDY   = userdat{1}{2};
    cls     = userdat{1}{3};
    design  = get(findobj('parent', hdl, 'tag', 'design')      , 'value');
	if ~std_checkdesign(STUDY, design)
        return;
    end
    
    clus     = get(findobj('parent', hdl, 'tag', 'clus_list'), 'value');
    comp_ind = get(findobj('parent', hdl, 'tag', 'clust_comp'), 'Value'); 
    if clus == 1 && length(cls) == 1
        warndlg2('No cluster', 'No cluster');
        return;
    end
    
    try
        switch  varargin{1}

            case {'plotcomptopo', 'plotcompersp','plotcompitc','plotcompspec', 'plotcomperp', 'plotcompdip', 'plotcomperpimage'}
                plotting_option = varargin{1};
                plotting_option = [ plotting_option(9:end) 'plot' ];
                if (clus ~= 1 ) %specific cluster
                    if comp_ind(1) ~= 1  % check that not all comps in cluster are requested
                        subject = STUDY.datasetinfo( STUDY.cluster(cls(clus-1)).sets(1,comp_ind-1)).subject;
                        a = ['STUDY = std_' plotting_option '(STUDY,ALLEEG,''clusters'','  num2str(cls(clus-1)) ', ''comps'', ' num2str(comp_ind-1) ', ''design'', ' int2str(design) ' );' ];
                        eval(a); STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);  
                     else
                        a = ['STUDY = std_' plotting_option '(STUDY,ALLEEG,''clusters'','  num2str(cls(clus-1)) ', ''design'', ' int2str(design) ', ''plotsubjects'', ''on'' );' ];
                        eval(a); STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);  
                    end
                else
                   comp_list = get(findobj('parent', hdl, 'tag', 'clust_comp'), 'String');
                   comp_name = comp_list(comp_ind);
                   for ci = 1:length(comp_name)
                       num_comps = 0;
                       tmp = strfind(comp_name{ci},'''');
                       clust_name = comp_name{ci}(tmp(1)+1:tmp(end)-1);
                       for k = 1:length(cls)
                           if ~strncmpi('Notclust',STUDY.cluster(cls(k)).name,8) && ~strncmpi('Outliers',STUDY.cluster(cls(k)).name,8) && ...
                                (~strncmpi('ParentCluster',STUDY.cluster(cls(k)).name,13)) 
                               if strcmpi(STUDY.cluster(cls(k)).name, clust_name)
                                   cind = comp_ind(ci) - num_comps; % component index in the cluster
                                   subject = STUDY.datasetinfo( STUDY.cluster(cls(k)).sets(1,cind)).subject;
                                   a = ['STUDY = std_' plotting_option '(STUDY,ALLEEG,''clusters'','  num2str(cls(k)) ', ''design'', ' int2str(design) ', ''comps'',' num2str(cind) ' );' ];
                                   eval(a); STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);  
                                   break;
                               else
                                   num_comps = num_comps + length(STUDY.cluster(cls(k)).comps);
                               end
                           end                       
                       end
                   end
                end
                userdat{1}{2} = STUDY;
                set(hdl, 'userdat',userdat); 

            case {'topoplot', 'erspplot', 'itcplot', 'specplot', 'erpplot', 'dipplot', 'erpimageplot' }
                plotting_option = varargin{1};
                plotting_option = [ plotting_option(1:end-4) 'plot' ];
                if (clus ~= 1 ) % specific cluster option
                    if ~isempty(STUDY.cluster(cls(clus-1)).comps)
                        a = ['STUDY = std_' plotting_option '(STUDY,ALLEEG,''clusters'','  num2str(cls(clus-1)) ', ''design'', ' int2str(design) ');' ];
                        eval(a); STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);  
                    end
                else % all clusters
                    % All clusters does not include 'Notclust' 'ParentCluster' and 'Outliers' clusters. 
                    tmpcls = [];
                    for k = 1:length(cls) 
                        if ~strncmpi(STUDY.cluster(cls(k)).name,'Notclust',8) && ~strncmpi(STUDY.cluster(cls(k)).name,'Outliers',8) && ...
                                (~strncmpi('ParentCluster',STUDY.cluster(cls(k)).name,13)) && ~isempty(STUDY.cluster(cls(k)).comps)
                            tmpcls = [ tmpcls cls(k)];
                        end
                    end
                    a = ['STUDY = std_' plotting_option '(STUDY,ALLEEG,''clusters'',['  num2str(tmpcls) '], ''design'', ' int2str(design) ');' ];
                    %if strcmpi(plotting_option, 'dipplot'), a = [a(1:end-2) ',''mode'', ''together'');' ]; end
                    eval(a); STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);  
                end
                userdat{1}{2} = STUDY;
                set(hdl, 'userdat',userdat); 

            case 'dip_opt' % save the list of selected chaners
                [STUDY, com] = pop_dipparams(STUDY);
                if ~isempty(com)
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, com);
                end
                userdat{1}{2} = STUDY;
                set(hdl, 'userdat',userdat); %update information (STUDY)     

            case 'erp_opt' % save the list of selected chaners
                [STUDY, com] = pop_erpparams(STUDY);
                if ~isempty(com)
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, com);
                end
                userdat{1}{2} = STUDY;
                set(hdl, 'userdat',userdat); %update information (STUDY)     

            case 'stat_opt' % save the list of selected chaners
                [STUDY, com] = pop_statparams(STUDY);
                if ~isempty(com)
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, com);
                end
                userdat{1}{2} = STUDY;
                set(hdl, 'userdat',userdat); %update information (STUDY)     

            case 'spec_opt' % save the list of selected channels
                [STUDY, com] = pop_specparams(STUDY);
                if ~isempty(com)
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, com);
                end
                userdat{1}{2} = STUDY;
                set(hdl, 'userdat',userdat); %update information (STUDY)     

            case 'erpim_opt' % save the list of selected channels
                [STUDY, com] = pop_erpimparams(STUDY);
                if ~isempty(com)
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, com);
                end
                userdat{1}{2} = STUDY;
                set(hdl, 'userdat',userdat); %update information (STUDY)     

            case 'ersp_opt' % save the list of selected channels
                [STUDY, com] = pop_erspparams(STUDY);
                if ~isempty(com)
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, com);
                end
                userdat{1}{2} = STUDY;
                set(hdl, 'userdat',userdat); %update information (STUDY)     

           case 'showcomplist' % save the list of selected clusters
                clust = get(findobj('parent', hdl, 'tag', 'clus_list') , 'value');
                comp  = get(findobj('parent', hdl, 'tag', 'clust_comp'), 'value');
                N = userdat{2};
                count = 1;
                if clust ~= 1 %specific cluster
                    STUDY.cluster(cls(clust-1)).selected = comp;
                end
                userdat{1}{2} = STUDY;
                set(hdl, 'userdat',userdat); %update information (STUDY)     

           case 'showclust'
                cind = get(findobj('parent', hdl, 'tag', 'clus_list'), 'value');
                N = userdat{2};
                count = 1;
                selected = get(findobj('parent', hdl, 'tag', 'clust_comp'), 'value');
                if cind ~= 1 %specific cluster
                    len = length(STUDY.cluster(cls(cind-1)).comps);
                    compid = cell(len+1,1);
                    compid{1} = 'All components';
                    % Convert from components numbering to the indexing form 'setXcomY'
                    for l = 1:len % go over the components of the cluster 
                        if ~isnan(STUDY.cluster(cls(cind-1)).sets(1,l))
                            subject = STUDY.datasetinfo(STUDY.cluster(cls(cind-1)).sets(1,l)).subject;
                            compid{l+1} = [  subject ' IC' num2str(STUDY.cluster(cls(cind-1)).comps(1,l)) ];
                        end
                    end
                    if isfield(STUDY.cluster, 'selected')
                        if ~isempty(STUDY.cluster(cls(cind-1)).selected)
                            selected = min(STUDY.cluster(cls(cind-1)).selected, 1+length(STUDY.cluster(cls(cind-1)).comps(1,:)));
                            STUDY.cluster(cls(cind-1)).selected = selected;
                        end
                    end

                else % All clusters accept 'Notclust' and 'Outliers'
                    count = 1;
                    for k = 1: length(cls)
                        if ~strncmpi('Notclust',STUDY.cluster(cls(k)).name,8) && ~strncmpi('Outliers',STUDY.cluster(cls(k)).name,8) && ...
                                (~strncmpi('ParentCluster',STUDY.cluster(cls(k)).name,13)) 
                            for l = 1: length(STUDY.cluster(cls(k)).comps)
                                if ~isnan(STUDY.cluster(cls(k)).sets(1,l))
                                    subject = STUDY.datasetinfo(STUDY.cluster(cls(k)).sets(1,l)).subject;   % This line chokes on NaNs. TF 2007.05.31
                                    compid{count} = [ '''' STUDY.cluster(cls(k)).name ''' comp. ' ...
                                        num2str(l) ' (' subject  ' IC' num2str(STUDY.cluster(cls(k)).comps(l)) ')'];
                                    count = count +1;
                                end
                            end
                        end
                    end
                end
                if selected > length(compid), selected = 1; end
                set(findobj('parent', hdl, 'tag', 'clust_comp'), 'value', selected, 'String', compid);

            case 'plotsum'
                if clus ~= 1 % specific cluster option
                    [STUDY] = std_propplot(STUDY, ALLEEG, 'cluster', cls(clus-1));
                    % update Study history
                    a = ['STUDY = std_propplot(STUDY, ALLEEG, ''cluster'', '  num2str(cls(clus-1)) ' );'  ];
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);  
                else % all clusters
                    % All clusters does not include 'Notclust' and 'Outliers' clusters. 
                    tmpcls = [];
                    for k = 1:length(cls) 
                        if ~strncmpi(STUDY.cluster(cls(k)).name,'Notclust',8) && ~strncmpi(STUDY.cluster(cls(k)).name,'Outliers',8) && ...
                                (~strncmpi('ParentCluster',STUDY.cluster(cls(k)).name,13)) 
                            tmpcls = [tmpcls cls(k)];
                        end
                    end
                    [STUDY] = std_propplot(STUDY, ALLEEG, 'cluster', tmpcls);
                    % update Study history
                    a = ['STUDY = std_propplot(STUDY, ALLEEG, ''cluster'', ['  num2str(tmpcls) '] );'  ];
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);  
                end
               userdat{1}{2} = STUDY;
               set(hdl, 'userdat',userdat);    

            case 'plotcompsum'
                for ci = 1 : length(comp_ind)
                    % place holder for component properties % nima
                end

            case 'renameclust'
                STUDY.saved = 'no';
                clus_name_list = get(findobj('parent', hdl, 'tag', 'clus_list'), 'String');
                clus_num = get(findobj('parent', hdl, 'tag', 'clus_list'), 'Value') -1;
                if clus_num == 0  % 'all clusters' option 
                    return;
                end
                % Don't rename 'Notclust' and 'Outliers'  clusters.
                if strncmpi('Notclust',STUDY.cluster(cls(clus_num)).name,8) || strncmpi('Outliers',STUDY.cluster(cls(clus_num)).name,8) || ...
                        strncmpi('ParentCluster',STUDY.cluster(cls(clus_num)).name,13)
                    warndlg2('The ParentCluster, Outliers, and Notclust clusters cannot be renamed');
                    return;
                end
                old_name = STUDY.cluster(cls(clus_num)).name;
                rename_param  = inputgui( { [1] [1] [1]}, ...
                    { {'style' 'text' 'string' ['Rename ' old_name] 'FontWeight' 'Bold'} {'style' 'edit' 'string' '' 'tag' 'clus_rename' } {} }, ...
                '', 'Rename cluster - from pop_clustedit()' );
                if ~isempty(rename_param) %if not canceled
                    new_name = rename_param{1};
                    STUDY = std_renameclust(STUDY, ALLEEG, cls(clus_num), new_name);
                    % update Study history
                    a = ['STUDY = std_renameclust(STUDY, ALLEEG, ' num2str(cls(clus_num)) ', ' STUDY.cluster(cls(clus_num)).name  ');'];
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);  
                    % Renaming cluster in list
                    new_name = [ STUDY.cluster(cls(clus_num)).name ' (' num2str(length(STUDY.cluster(cls(clus_num)).comps))  ' ICs)'];
                    clus_name_list{clus_num+1} = renameclust( clus_name_list{clus_num+1}, new_name);
                    % Renaming Outlier cluster if exist
                    outlier_clust = std_findoutlierclust(STUDY,cls(clus_num));
                    if outlier_clust ~= 0
                        new_outliername = [ STUDY.cluster(cls(outlier_clust)).name ' (' num2str(length(STUDY.cluster(cls(outlier_clust)).comps))  ' ICs)'];
                        clus_name_list{outlier_clust+1} = renameclust( clus_name_list{outlier_clust+1}, new_outliername);
                    end
                    set(findobj('parent', hdl, 'tag', 'clus_list'), 'String', clus_name_list);
                    set(findobj('parent', hdl, 'tag', 'clus_rename'), 'String', '');
                    userdat{1}{2} = STUDY;
                    set(hdl, 'userdat',userdat); %update STUDY
                end

            case 'movecomp'
                STUDY.saved = 'no';
                old_clus = get(findobj('parent', hdl, 'tag', 'clus_list'), 'value') -1;
                comp_ind = get(findobj('parent', hdl, 'tag', 'clust_comp'), 'Value'); 
                if old_clus == 0 % 'all clusters' option 
                    return;
                end
                % Don't reassign components of 'Notclust' or the 'ParentCluster'.
                if strncmpi('ParentCluster',STUDY.cluster(cls(old_clus)).name,13)  
                    warndlg2('Cannot reassign components of ''ParentCluster''.');
                    return;
                end
                old_name = STUDY.cluster(cls(old_clus)).name;
                ncomp = length(comp_ind); % number of selected components
                optionalcls =[];
                for k = 1:length(cls)
                    if (~strncmpi('ParentCluster',STUDY.cluster(cls(k)).name,13))  && (k~= old_clus)
                        optionalcls = [optionalcls cls(k)];
                    end
                end                    
                reassign_param  = inputgui( { [1] [1] [1]}, ...
                    { {'style' 'text' 'string' strvcat(['Reassign ' fastif(ncomp >1, [num2str(length(comp_ind)) ' currently selected components'], ...
                                                                  'currently selected component') ], ...
                                [' from ' old_name ' to the cluster selected below']) 'FontWeight' 'Bold'} ...
                      {'style' 'listbox' 'string' {STUDY.cluster(optionalcls).name} 'tag' 'new_clus'} {} }, ...
                      '', 'Reassign cluster - from pop_clustedit()' ,[] , 'normal', [2 3 1] );
                if ~isempty(reassign_param) %if not canceled
                    new_clus = reassign_param{1};
                    comp_to_disp = get(findobj('parent', hdl, 'tag', 'clust_comp'), 'String');      
                    if strcmp(comp_to_disp{comp_ind(1)},'All components')
                        warndlg2('Cannot move all the components of the cluster - abort move components', 'Aborting move components');
                        return;
                    end
                    STUDY = std_movecomp(STUDY, ALLEEG,  cls(old_clus), optionalcls(new_clus), comp_ind - 1);                
                    % update Study history
                    a = ['STUDY = std_movecomp(STUDY, ALLEEG, ' num2str(cls(old_clus)) ', ' num2str(optionalcls(new_clus)) ', [' num2str(comp_ind - 1) ']);'];
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);
                    newind = find(cls == optionalcls(new_clus));

                    % update GUI
                    % ----------
                    clus_name_list = get(findobj('parent', hdl, 'tag', 'clus_list'), 'String');     
                    newname = [STUDY.cluster(optionalcls(new_clus)).name ' (' num2str(length(STUDY.cluster(optionalcls(new_clus)).comps))  ' ICs)'];
                    clus_name_list{newind+1} = renameclust( clus_name_list{newind+1}, newname);
                    newname = [STUDY.cluster(cls(old_clus)).name ' (' num2str(length(STUDY.cluster(cls(old_clus)).comps))  ' ICs)'];
                    clus_name_list{old_clus+1} = renameclust( clus_name_list{old_clus+1}, newname);
                    set( findobj('parent', hdl, 'tag', 'clus_list'), 'String', clus_name_list);
                    STUDY.cache = [];
                    userdat{1}{2} = STUDY;
                    set(hdl, 'userdat',userdat); 
                    pop_clustedit('showclust',hdl);
                end          

            case 'moveoutlier'
                STUDY.saved = 'no';
                old_clus = get(findobj('parent', hdl, 'tag', 'clus_list'), 'value') -1;
                comp_ind = get(findobj('parent', hdl, 'tag', 'clust_comp'), 'Value'); 
                if ~isempty(find(comp_ind ==1))
                    warndlg2('Cannot remove all the cluster components');
                    return;
                end
                if old_clus == 0 % 'all clusters' option 
                    return;
                end
                if strncmpi('Notclust',STUDY.cluster(cls(old_clus)).name,8) || strncmpi('ParentCluster',STUDY.cluster(cls(old_clus)).name,13)    % There are no outliers to 'Notclust'
                    warndlg2('Cannot reassign components of ''Notclust'' or ''ParentCluster''.');
                    return;
                end
                comp_list = get(findobj('parent', hdl, 'tag', 'clust_comp'), 'String'); 
                ncomp = length(comp_ind);
                old_name = STUDY.cluster(cls(old_clus)).name;            
                if strncmpi('Outliers',STUDY.cluster(cls(old_clus)).name,8)  % There are no outliers of 'Outliers'
                    warndlg2('Cannot use ''Outliers'' clusters for this option.');
                    return;
                end
                reassign_param  = inputgui( { [1] [1] [1]}, ...
                    { {'style' 'text' 'string' ['Remove ' fastif(ncomp >1, [num2str(length(comp_ind)) ' currently selected components below '], 'currently selected component below ') ...
                                'from ' old_name ' to its outlier cluster?'] 'FontWeight' 'Bold'} ...
                      {'style' 'listbox' 'string' {comp_list{comp_ind}} 'tag' 'new_clus'} {} }, ...
                      '', 'Remove outliers - from pop_clustedit()' ,[] , 'normal', [1 3 1] );
                if ~isempty(reassign_param) %if not canceled
                    STUDY = std_moveoutlier(STUDY, ALLEEG,  cls(old_clus), comp_ind - 1);
                    clus_name_list = get(findobj('parent', hdl, 'tag', 'clus_list'), 'String');
                    outlier_clust = std_findoutlierclust(STUDY,cls(old_clus)); %find the outlier cluster for this cluster
                    oind = find(cls == outlier_clust); % the outlier clust index (if already exist) in the cluster list GUI
                    if ~isempty(oind) % the outlier clust is already presented in the cluster list GUI
                        newname = [STUDY.cluster(outlier_clust).name ' (' num2str(length(STUDY.cluster(outlier_clust).comps))  ' ICs)'];
                        clus_name_list{oind+1} = renameclust( clus_name_list{oind+1}, newname);
                    elseif outlier_clust == length(STUDY.cluster) % update the list with the Outlier cluster (if didn't exist before)
                        clus_name_list{end+1} = [STUDY.cluster(outlier_clust).name ' (' num2str(length(STUDY.cluster(outlier_clust).comps))  ' ICs)'];
                        userdat{2} = userdat{2} + 1; % update N, number of clusters in edit window 
                        cls(end +1) = length(STUDY.cluster); % update the GUI clusters list with the outlier cluster
                        userdat{1}{3} = cls;  % update cls, the cluster indices in edit window
                    end
                    newname = [STUDY.cluster(cls(old_clus)).name ' (' num2str(length(STUDY.cluster(cls(old_clus)).comps))  ' ICs)'];
                    clus_name_list{old_clus+1} = renameclust(clus_name_list{old_clus+1}, newname);
                    set(findobj('parent', hdl, 'tag', 'clus_list'), 'String', clus_name_list);
                    % update Study history
                    a = ['STUDY = std_moveoutlier(STUDY, ALLEEG, ' num2str(cls(old_clus)) ', [' num2str(comp_ind - 1) ']);'];
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);
                    STUDY.cache = [];
                    userdat{1}{2} = STUDY;
                    set(hdl, 'userdat',userdat); 
                    pop_clustedit('showclust',hdl);    
                end

            case 'rejectoutliers'
                STUDY.saved = 'no';
                clus = get(findobj('parent', hdl, 'tag', 'clus_list'), 'Value') -1;
                if clus
                    std_name = STUDY.cluster(cls(clus)).name;
                    % Cannot reject outliers from 'Notclust', 'ParentCluster' and 'Outlier' clusters
                    if strncmpi('Notclust',std_name,8) || strncmpi('ParentCluster', std_name,13) || ...
                            strncmpi('Outliers',std_name,8)
                        warndlg2('Cannot reject outliers of ''Notclust'' or ''Outliers'' or ''ParentCluster'' clusters.');
                        return;
                    end
                    clusters = cls(clus);
                else
                    std_name = 'All clusters';
                    clusters = [];
                    for k = 1:length(cls)
                         if ~strncmpi('Notclust',STUDY.cluster(cls(k)).name,8) && ~strncmpi('Outliers',STUDY.cluster(cls(k)).name,8) && ...
                                 ~strncmpi('ParentCluster',STUDY.cluster(cls(k)).name,13)  
                            clusters = [ clusters cls(k)];
                        end
                    end
                end
                reject_param  = inputgui( { [1] [1] [4 1 2] [1]}, ...
                    { {'style' 'text' 'string' ['Reject "' std_name  '" outliers ' ] 'FontWeight' 'Bold'} {} ...
                       {'style' 'text' 'string' 'Move outlier components that are more than'} {'style' 'edit' 'string' '3' 'tag' 'outliers_std' } ...
                      {'style' 'text' 'string' 'standard deviations' } ...
                      {'style' 'text' 'string' [ 'from the "' std_name  '" centroid to an outlier cluster.']} }, ...
                      '', 'Reject outliers - from pop_clustedit()' );
                if ~isempty(reject_param) %if not canceled
                    ostd = reject_param{1}; % the requested outlier std
                    [STUDY] = std_rejectoutliers(STUDY, ALLEEG, clusters, str2num(ostd));  
                    % update Study history
                    a = ['STUDY = std_rejectoutliers(STUDY, ALLEEG, [ ' num2str(clusters) ' ], ' ostd ');'];
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);
                    clus_name_list = get(findobj('parent', hdl, 'tag', 'clus_list'), 'String');
                    for k = 1:length(clusters)
                        outlier_clust = std_findoutlierclust(STUDY,clusters(k)); %find the outlier cluster for this cluster
                        oind = find(cls == outlier_clust); % the outlier clust index (if already exist) in the cluster list GUI
                        if ~isempty(oind) % the outlier clust is already presented in the cluster list GUI
                            newname = [STUDY.cluster(outlier_clust).name ' (' num2str(length(STUDY.cluster(outlier_clust).comps))  ' ICs)'];
                            clus_name_list{oind+1} = renameclust( clus_name_list{oind+1}, newname);
                        else % update the list with the outlier cluster 
                            clus_name_list{end+1} = [STUDY.cluster(outlier_clust).name ' (' num2str(length(STUDY.cluster(outlier_clust).comps))  ' ICs)'];
                            userdat{2} = userdat{2} + 1; % update N, number of clusters in edit window 
                            cls(end +1) = outlier_clust; % update the GUI clusters list with the outlier cluster
                            userdat{1}{3} = cls;  % update cls, the cluster indices in edit window
                        end
                        clsind = find(cls == clusters(k));
                        newname = [STUDY.cluster(clusters(k)).name ' (' num2str(length(STUDY.cluster(clusters(k)).comps))  ' ICs)'];
                        clus_name_list{clsind+1} = renameclust( clus_name_list{clsind+1}, newname);
                        set(findobj('parent', hdl, 'tag', 'clus_list'), 'String', clus_name_list);
                    end
                    % If outlier cluster doesn't exist in the GUI window add it 
                    STUDY.cache = [];
                    userdat{1}{2} = STUDY;
                    set(hdl, 'userdat',userdat); 
                    pop_clustedit('showclust',hdl);
                end

            case 'createclust'
                STUDY.saved = 'no';
                create_param  = inputgui( { [1] [1 1] [1]}, ...
                    { {'style' 'text' 'string' 'Create new empty cluster' 'FontWeight' 'Bold'} ...
                       {'style' 'text' 'string' 'Enter cluster name:'} {'style' 'edit' 'string' '' } {} }, ...
                      '', 'Create new empty cluster - from pop_clustedit()' );
                if ~isempty(create_param) %if not canceled
                    clus_name = create_param{1}; % the name of the new cluster
                    [STUDY] = std_createclust(STUDY, ALLEEG, 'name', clus_name); 
                    % Update cluster list
                    clus_name_list = get(findobj('parent', hdl, 'tag', 'clus_list'), 'String');
                    clus_name_list{end+1} = [STUDY.cluster(end).name ' (0 ICs)']; %update the cluster list with the new cluster
                    % update the first option on the GUI list : 'All 10 cluster centroids'
                    % with the new number of cluster centroids
                    ti = strfind(clus_name_list{1},'cluster'); %get the number of clusters centroid 
                    cent = num2str(str2num(clus_name_list{1}(5:ti-2))+1); % new number of centroids
                    clus_name_list{1} = [clus_name_list{1}(1:4) cent clus_name_list{1}(ti-1:end)]; %update list
                    set(findobj('parent', hdl, 'tag', 'clus_list'), 'String', clus_name_list);
                    % update Study history
                    if isempty(clus_name)
                        a = ['STUDY = std_createclust(STUDY, ALLEEG);'];
                    else
                        a = ['STUDY = std_createclust(STUDY, ALLEEG, ''name'', ' clus_name ');'];
                    end                
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);
                    STUDY.cache = [];
                    userdat{1}{2} = STUDY;
                    userdat{2} = userdat{2} + 1; % update N, the number of cluster options in edit window 
                    cls(end +1) = length(STUDY.cluster); % update the GUI clusters list with the new cluster
                    userdat{1}{3} = cls;  % update cls, the cluster indices in edit window
                    set(hdl, 'userdat',userdat); %update STUDY, cls and N
                end

            case 'mergeclusters'
                STUDY.saved = 'no';
                clus_names = get(findobj('parent', hdl, 'tag', 'clus_list'), 'string') ;
                optionalcls =[];
                for k = 2:length(clus_names)
                    if (~strncmpi('Notclust',clus_names{k},8)) && (~strncmpi('Outliers',clus_names{k},8)) && ...
                            (~strncmpi('ParentCluster',clus_names{k},13))
                        optionalcls = [optionalcls k];
                    end
                end           
                reassign_param  = inputgui( { [1] [1] [1] [2 1] [1]}, ...
                    { {'style' 'text' 'string' 'Select clusters to Merge' 'FontWeight' 'Bold'} ...
                      {'style' 'listbox' 'string' clus_names(optionalcls) 'tag' 'new_clus' 'max' 3 'min' 1} {} ...
                      {'style' 'text' 'string' 'Optional, enter a name for the merged cluster:' 'FontWeight' 'Bold'} ...
                      {'style' 'edit' 'string' ''} {} }, ...
                      '', 'Merge clusters - from pop_clustedit()' ,[] , 'normal', [1 3 1 1 1] );
                if ~isempty(reassign_param)
                    std_mrg = cls(optionalcls(reassign_param{1})-1);
                    name = reassign_param{2};
                    allleaves = 1;
                    N = userdat{2};
                    for k = 1: N %check if all leaves
                        if ~isempty(STUDY.cluster(cls(k)).child)
                            allleaves = 0;
                        end
                    end
                    [STUDY] = std_mergeclust(STUDY, ALLEEG, std_mrg, name);
                    %
                    % update Study history
                    %
                    if isempty(name)
                        a = ['STUDY = std_mergeclust(STUDY, ALLEEG, [' num2str(std_mrg) ']);'];
                    else
                        a = ['STUDY = std_mergeclust(STUDY, ALLEEG, [' num2str(std_mrg) '], ' name ');'];
                    end
                    STUDY.tmphist =  sprintf('%s\n%s',  STUDY.tmphist, a);
                    STUDY.cache = [];
                    userdat{1}{2} = STUDY;
                    %
                    % Replace the merged clusters with the one new merged cluster
                    % in the GUI if all clusters are leaves
                    %
                    if allleaves
                        %
                        % Update cluster list
                        %
                        clus_names{end+1} = [STUDY.cluster(end).name ' (' num2str(length(STUDY.cluster(end).comps))  ' ICs)'];
                        %
                        % update the cluster list with the new cluster
                        %
                        clus_names([optionalcls(reassign_param{1})]) = [];
                        cls = setdiff_bc(cls, std_mrg); % remove from the GUI clusters list the merged clusters
                        cls(end+1) = length(STUDY.cluster); % update the GUI clusters list with the new cluster
                        N  = length(cls);
                        %
                        % update the first option on the GUI list : 'All 10 cluster centroids'
                        % with the new number of cluster centroids
                        %
                        ti = strfind(clus_names{1},'cluster'); %get the number of clusters centroid
                        cent = num2str(str2num(clus_names{1}(5:ti-2))+1- length(std_mrg)); % new number of centroids
                        clus_names{1} = [clus_names{1}(1:4) cent clus_names{1}(ti-1:end)]; %update list
                        set(findobj('parent', hdl, 'tag', 'clus_list'), 'String', clus_names);
                        %
                        % update Study history
                        %
                        userdat{2} = N; % update N, the number of cluster options in edit window
                        userdat{1}{3} = cls;  % update cls, the cluster indices in edit window
                    end
                    set(hdl, 'userdat',userdat); %update information (STUDY)
                    pop_clustedit('showclust',hdl);
                end
        end
    catch
        eeglab_error;
    end       
end

function newname = renameclust(oldname, newname)
    
    tmpname = deblank(oldname(end:-1:1));
    strpos  = strfind(oldname, tmpname(end:-1:1));
    
    newname = [ oldname(1:strpos-1) newname ];

    
