function timeseries_plotcontrol(op, varargin)

% Multi-function function collecting callbacks for 
% the timeseries analysis application.
% -------------------------------------------------
% Jeff Cooper, Jan. 2003


% Default values
% ------------------
window_length = 32;  % default window length in seconds

%spm_defaults;


if nargin == 0
    error('timeseries_plotcontrol requires an operation string.  See timeseries_plotcontrol.m for details');
end


if strcmp(op,'newpos')
    %fprintf('/n********************/nGot to newpos/n********************/n');
    newY = [];
    VY = get(findobj('Tag', 'IntensityAxes'), 'UserData');
    cache = get(findobj('Tag', 'IntensityCheckBox'), 'UserData');
    bgvol = get(findobj('Tag', 'RightImageControlFrame'), 'UserData');
    bgmat = bgvol.mat;
    func_invmat = inv(VY(1).mat);
    roi_found_flag = 0;

    % First, check if we're in single-voxel or ROI-mean mode
    if (get(findobj('Tag', 'SingleVoxModeButton'), 'Value'))==1
        % We're in single-vox mode, so find our location and sample.
        newx_vox = round(str2num(get(findobj('Tag', 'postext_x_vox'), 'String')));
        newy_vox = round(str2num(get(findobj('Tag', 'postext_y_vox'), 'String')));
        newz_vox = round(str2num(get(findobj('Tag', 'postext_z_vox'), 'String')));
        if isempty(cache.v{newx_vox, newy_vox, newz_vox})
            % This is a new location, so we cache the sampled intensities.
                % - first convert new location into functional space
            newpos_vox = [newx_vox; newy_vox; newz_vox; 1];
            newpos_mm = bgmat*newpos_vox;
            newpos_func_vox = round(func_invmat*newpos_mm);
            set(findobj('Tag', 'Image Window'), 'Pointer', 'watch');
            set(findobj('Tag', 'plotfig'), 'Pointer', 'watch');
            for i = 1:length(VY)
                newY(i, 1) = spm_sample_vol(VY(i), ...
                    newpos_func_vox(1), newpos_func_vox(2), newpos_func_vox(3), 1);
            end
            set(findobj('Tag', 'Image Window'), 'Pointer', 'arrow');
            set(findobj('Tag', 'plotfig'), 'Pointer', 'arrow');
            %fprintf('\nSampled from %g x, %g y, %g z in functional space.\n', ...
            %    newpos_func_vox(1), newpos_func_vox(2), newpos_func_vox(3));
            %fprintf('Which was %g x, %g y, %g z in anatomical space.\n', ...
            %    newx_vox, newy_vox, newz_vox);
            cache.v{newx_vox, newy_vox, newz_vox} = newY;
        else
            % We've been to this location before and have cleverly cached the intensity timecourse.
            newY = cache.v{newx_vox, newy_vox, newz_vox};
        end
    else
        % We're in ROI-mean mode.
        % First check to make sure we're actually in an ROI.
        disp_string = get(findobj('Tag', 'DisplayingText'), 'String');
        if strcmp(disp_string, 'Nothing')
            % We're not in an ROI.  So let's just turn those plots off, okay?
            newY = zeros(length(VY),1);
        else       
            % Time to find out which ROI we're in and find out if it's cached.
            rois = get(findobj('Tag', 'ROIListBox'), 'UserData');
            for i = size(rois,1):-1:1
                curr = rois{i};
                vinv_roi = inv(curr.mat);
                currx = str2num(get(findobj('Tag', 'postext_x_mm'), 'String'));
                curry = str2num(get(findobj('Tag', 'postext_y_mm'), 'String'));
                currz = str2num(get(findobj('Tag', 'postext_z_mm'), 'String'));
                currpos = [currx; curry; currz];
                currpos_vox = vinv_roi(1:3,:)*[currpos; 1]; 
                if spm_sample_vol(curr, currpos_vox(1), currpos_vox(2), currpos_vox(3), 1) > 0
                    % i.e., we've found our location in the current ROI
                    roi_found_flag = 1;
                    if ~(isempty(cache.r{i}))
                        % We've cleverly cached this ROI
                        newY = cache.r{i};
                    else
                        set(findobj('Tag', 'Image Window'), 'Pointer', 'watch');
                        set(findobj('Tag', 'plotfig'), 'Pointer', 'watch');

                        % Extract data from ROI - can take a while.

                        fprintf('\nExtracting %g voxels from %g images\n',size(curr.XYZ,2),length(VY))
                        newYmatrix = [];
                        xyz_vox = func_invmat(1:3,:)*[curr.XYZ; ones(1, size(curr.XYZ,2))];
                        for j = 1:length(VY)
                           if rem(j,100)==0
                            fprintf('\nGot to image %g\n',j)
                           end
                           newYmatrix(j,:) = spm_sample_vol(VY(j), xyz_vox(1,:), xyz_vox(2,:), xyz_vox(3,:),1);
                        end
                        fprintf('\nDone!\n');
                        newY = mean(newYmatrix, 2);
                        cache.r{i} = newY;
                        set(findobj('Tag', 'Image Window'), 'Pointer', 'arrow');
                        set(findobj('Tag', 'plotfig'), 'Pointer', 'arrow');

                    end
                    break;
                end
            end
            if roi_found_flag==0
                error('Couldn''t find current location in a listed ROI.');
            end
        end
    end

    set(findobj('Tag', 'IntensityCheckBox'), 'UserData', cache);
    set(findobj('Tag', 'IntensityPlot'), 'YData', newY);
    set(findobj('Tag', 'ZScorePlot'), 'YData', abs(zscore(newY)));

    timeseries_plotcontrol('percentify');
    % This resets both percent and peristim plots.    

    return;
end


if strcmp(op,'intensitycheckpush')
    val = get(findobj('Tag', 'IntensityCheckBox'), 'Value');
    if val==0
        %i.e., we're turning plot off
        set(findobj('Tag', 'IntensityPlot'), 'Visible', 'off');
    else
        set(findobj('Tag', 'IntensityPlot'), 'Visible', 'on');
    end

    return;
end


if strcmp(op,'globalintensitycheckpush')
    val = get(findobj('Tag', 'GlobalIntensityCheckBox'), 'Value');
    if val==0
        %i.e., we're turning plot off
        set(findobj('Tag', 'GlobalIntensityPlot'), 'Visible', 'off');
    else
        set(findobj('Tag', 'GlobalIntensityPlot'), 'Visible', 'on');
    end

    return;
end

if strcmp(op,'zscorecheckpush')
    val = get(findobj('Tag', 'ZScoreCheckBox'), 'Value');
    if val==0
        %i.e., we're turning plot off
        set(findobj('Tag', 'ZScorePlot'), 'Visible', 'off');
    else
        set(findobj('Tag', 'ZScorePlot'), 'Visible', 'on');
    end

    return;
end

if strcmp(op,'globalzscorecheckpush')
    val = get(findobj('Tag', 'GlobalZScoreCheckBox'), 'Value');
    if val==0
        %i.e., we're turning plot off
        set(findobj('Tag', 'GlobalZScorePlot'), 'Visible', 'off');
    else
        set(findobj('Tag', 'GlobalZScorePlot'), 'Visible', 'on');
    end

    return;
end


if strcmp(op,'highpasspush')
    val = get(findobj('Tag', 'HPFilterCheckBox'), 'Value');
    if val==0
        %i.e., we're turning plot off
        set(findobj('Tag', 'HPFilterText'), 'Enable', 'off');
    else
        set(findobj('Tag', 'HPFilterText'), 'Enable', 'on');
    end

    timeseries_plotcontrol('percentify');
    return;
end

if strcmp(op,'lowpasspush')
    % Note that the low-pass checkbox should only enabled if
    % we're running SPM99, since the SPM2 spm_filter doesn't
    % have low-pass filtering.  That disabling is taken care
    % of in timeseries.m
    val = get(findobj('Tag', 'LPFilterCheckBox'), 'Value');
    if val==0
        %i.e., we're turning plot off
        set(findobj('Tag', 'LPFilterText'), 'Enable', 'off');
    else
        set(findobj('Tag', 'LPFilterText'), 'Enable', 'on');
    end

    timeseries_plotcontrol('percentify');
    return;
end


if strcmp(op, 'percentify')

    Y = (get(findobj('Tag', 'IntensityPlot'), 'YData'))';
    iS = get(findobj('Tag', 'PercentAxes'), 'UserData');
    nsess = max(iS);
    RT = get(findobj('Tag', 'PercentControlFrame'), 'UserData');
    detrend_flag = get(findobj('Tag', 'DetrendCheckBox'), 'Value');
    trim_flag = get(findobj('Tag', 'TrimCheckBox'), 'Value');
    hp_flag = get(findobj('Tag', 'HPFilterCheckBox'), 'Value');
    lp_flag = get(findobj('Tag', 'LPFilterCheckBox'), 'Value');
    
    % conveniently, spm decided to change the syntax of
    % spm_filter between SPM99 and SPM2.  Backwards
    % compatibility is for weaklings!
    filter_ver = which('spm_filter');
    if ~isempty(strfind(filter_ver, '99'));
        %i.e., we're in SPM99 right now
        run_spm2_flag = 0;             
    else
        run_spm2_flag = 1;
        lp_flag = 0;  % can't low-pass filter with SPM2's spm_filter
    end

    %
    % -------------------------------------------------------------------
    % Temporal preprocessing
    % -------------------------------------------------------------------
    %
    

    % ---------------------------------------------
    % Trim outliers by replacing abs(zscore)>2.5 with 
    % the session specific trimmed mean (10%).  
    % --------------------------------------------
    if trim_flag==1
    % ---------------------------------------------
	    trimcut = 5; % for the trimmean cut off 10% (5% on each side)
	    prev_idx = 0;
	    for s = 1:nsess
		    sess_idx = find(iS==s);
		    out_idx = find(abs(zscore(Y(sess_idx))) > 2.5);
		    trM	  = trimmean(Y(sess_idx),trimcut);
		    Y(prev_idx+out_idx) = trM;
		    prev_idx = sess_idx(end);
	    end
    end
  

      
    % -----------------------------------------------
    % Convert to per cent signal change
    % -----------------------------------------------
 
    Y_mean_overall = mean(Y);
    if ~(Y_mean_overall==0)
        Y = Y / Y_mean_overall;
        Y = Y*100;
        Y = Y-100;
    end
 
    % --------------------------------------------------------------
    % Detrend by removing linear trend - separately for each session
    % --------------------------------------------------------------
    if detrend_flag==1
    % --------------------------------------------------------------
	     for s = 1:nsess
	    	sess_idx = find(iS==s);
	    	Y(sess_idx) = detrend(Y(sess_idx));
	     end
    end
	 
    % ----------------------------------------------------------------
    % Filtering - SPM-style filtering 
    % ----------------------------------------------------------------
    if lp_flag | hp_flag
    % ----------------------------------------------------------------
        if hp_flag
            HChoice = 'specify';
            HParam = str2num(get(findobj('Tag', 'HPFilterText'), 'String'));
        else
            HChoice = 'none';
            HParam = [];
        end
        if lp_flag
            if strcmp(lower(get(findobj('Tag', 'LPFilterText'), 'String')), 'hrf')
                LChoice = 'hrf';
                LParam = [];
            elseif isempty(deblank(get(findobj('Tag', 'LPFilterText'), 'String')))
                LChoice = 'none';
                LParam = [];
            else
                LChoice = 'Gaussian';
                LParam = str2num(get(findobj('Tag', 'LPFilterText'), 'String'));
                LParam = LParam/sqrt(8*log(2));
            end
        else
            LChoice = 'none';
            LParam = [];
        end
        if ~run_spm2_flag
            %i.e., running SPM99's spm_filter
            for s = 1:nsess
        	    row{s} = find(iS==s);
                K{s} = struct(	'HChoice',	HChoice,...
    	    		'HParam',	HParam,...
	         		'LChoice',	LChoice,...
	    		    'LParam',	LParam,...
	    		    'row',		row{s},...
    	    		'RT',		RT);
            end
            K = spm_filter('set',K); 
        else
            %i.e., running SPM2's spm_filter
            for s = 1:nsess
        	    row{s} = find(iS==s);
                K(s) = struct(	'HChoice',	HChoice,...
    	    		'HParam',	HParam,...
	    		    'row',		row{s},...
    	    		'RT',		RT);
            end
            K = spm_filter(K);
        end            
        if lp_flag
            % this means we can't be running SPM2's
            % spm_filter
            Y = spm_filter('low',K,Y);
        end
        if hp_flag
            if ~run_spm2_flag
                Y = spm_filter('high',K,Y);
            else
                Y = spm_filter(K, Y);
            end
        end  
    end
   

    if isempty(findobj('Tag', 'PercentPlot'))
        hold on
        h = findobj('Tag', 'PercentAxes');
        axes(h);
        plot(Y, 'Tag', 'PercentPlot');
        set(h, 'XAxisLocation', 'top');
        set(h, 'YGrid', 'on');
        set(h, 'XGrid', 'on');
        %axis tight;
    else
        p = findobj('Tag', 'PercentPlot');
        set(p, 'YData', Y);
        %axes(findobj('Tag', 'PercentAxes'));
        %axis tight;
        
        for i = 1:5
            timeseries_plotcontrol('popuppush', i);
        end
    end


    return;
end


if strcmp(op, 'popuppush')
    num = varargin{1};
    plottag = findobj('Tag', ['ConditionPlot' num2str(num)]);
    Y = (get(findobj('Tag', 'PercentPlot'), 'YData'))';
    RT = get(findobj('Tag', 'PercentControlFrame'), 'UserData');
    menutag = findobj('Tag', ['ConditionPopup' num2str(num)]);
    menuchoice = get(menutag, 'Value');
    menu = get(menutag, 'String');
    string = menu{menuchoice};
    window_length = round(window_length / RT);

    if strcmp(string, '<None>')
        set(plottag, 'Visible', 'off');
    else
        Cond = get(findobj('Tag', 'PeristimAxes'), 'UserData');
        chosen = [];
        for i = 1:length(Cond)
            curr = Cond(i);
            if strcmp(string, curr.name{1})
                chosen = curr;
            end
        end
        if isempty(chosen)
            error('Could not find condition structure with that name.');
        end
        for i=1:window_length
	        nscans =  length(Y);
	  	    tmp_idx = chosen.onidx + (i-1);
		    tmp_idx = tmp_idx(find(tmp_idx<=nscans)); % if trials exceed exp end
            newY(i) = mean(Y(tmp_idx)); 
	    end
        set(plottag, 'YData', newY)  

        set(plottag, 'Visible', 'on');
    end


    return;
end


if strcmp(op, 'changedirpush')
    output_dir = spm_get(-1,'*', 'Select output directory');
    set(findobj('Tag', 'OutputDirText'), 'String', spm_str_manip(output_dir, 'a25'));
    set(findobj('Tag', 'OutputDirText'), 'UserData', output_dir);

    return;
end


if strcmp(op, 'savecheckpush_text')
    set(findobj('Tag', 'SaveCheckText'), 'Value', 1);
    set(findobj('Tag', 'SaveCheckMat'), 'Value', 0);

    return;
end


if strcmp(op, 'savecheckpush_mat')
    set(findobj('Tag', 'SaveCheckText'), 'Value', 0);
    set(findobj('Tag', 'SaveCheckMat'), 'Value', 1);

    return;
end

if strcmp(op, 'savetimepush')
    textflag = get(findobj('Tag', 'SaveCheckText'), 'Value');
    feedbacktag = findobj('Tag', 'FileSavedText');
    outdir = get(findobj('Tag', 'OutputDirText'), 'UserData');
    [dummy, fname] = fileparts(deblank(get(findobj('Tag', 'SaveTimeText'), 'String')));
    type_list = get(findobj('Tag', 'SaveTimePopup'), 'String');
    type_val = get(findobj('Tag', 'SaveTimePopup'), 'Value');
    type = type_list{type_val};
    Y = [];
    RT = get(findobj('Tag', 'PercentControlFrame'), 'UserData');
    window_length = round(window_length / RT);
    if strcmp(type, 'Intensity')
        Y = get(findobj('Tag', 'IntensityPlot'), 'YData')';
        fname = [fname '_intensity'];
        if textflag==1
            fname = [fname '.txt'];
            fname = fullfile(outdir, fname);
            fid = fopen(fname,'w');
	        if fid == -1, error(['Unable to create new file - please check permissions', ...
								  ' in current directory.']); 
		    end
            fprintf(fid,'%4.4f\n', Y);
            fclose(fid);
        else
            fname = [fname '.mat'];
            fname = fullfile(outdir, fname);
            save(fname, 'Y', '-mat');
        end
    set(feedbacktag, 'String', ['File saved!: ' spm_str_manip(fname, 'a35')]);
    elseif strcmp(type, '% Signal')
        Y = get(findobj('Tag', 'PercentPlot'), 'YData')';
        fname = [fname '_percent_signal'];
        if textflag==1
            fname = [fname '.txt'];
            fname = fullfile(outdir, fname);
            fid = fopen(fname,'w');
	        if fid == -1, error(['Unable to create new file - please check permissions', ...
								  ' in current directory.']); 
		    end
            fprintf(fid,'%4.4f\n', Y);
            fclose(fid);
        else
            fname = [fname '.mat'];
            fname = fullfile(outdir, fname);
            save(fname, 'Y', '-mat');
        end
    set(feedbacktag, 'String', ['File saved!: ' spm_str_manip(fname, 'a35')]);
    elseif strcmp(type, 'Conditions')
        Cond = get(findobj('Tag', 'PeristimAxes'), 'UserData');
        baseY = (get(findobj('Tag', 'PercentPlot'), 'YData'))';
        for i = 1:length(Cond)
            curr = Cond(i);
            for j=1:window_length
	            nscans =  length(baseY);
    	  	    tmp_idx = curr.onidx + (j-1);
    		    tmp_idx = tmp_idx(find(tmp_idx<=nscans)); % if trials exceed exp end
                Y(j,1) = mean(baseY(tmp_idx)); 
    	    end
            curr.Y = Y;
            cond_fname = [fname '_cond_' curr.name{1}];
            if textflag==1
                cond_fname = [cond_fname '.txt'];
                cond_fname = fullfile(outdir, cond_fname);
                fid = fopen(cond_fname,'w');
	            if fid == -1,  
                    %keyboard;
                    error(['Unable to create new file - please check permissions', ...
								  ' in current directory.']); 
    		    end
                fprintf(fid,'%4.4f\n', curr.Y);
                fclose(fid);
            else
                cond_fname = [cond_fname '.mat'];
                cond_fname = fullfile(outdir, cond_fname);
                save(cond_fname, 'Y', '-mat');
            end
        end
    feedbackext = cond_fname(end-3:end);
    feedbackname = [fname '_cond_*' feedbackext];
    feedbackname = fullfile(outdir, feedbackname);
    set(feedbacktag, 'String', ['File saved!:' spm_str_manip(feedbackname, 'a35')]);
    end
    
    set(findobj('Tag', 'FileSavedText'), 'Visible', 'on');
    pause(1);
    %keyboard;
    set(findobj('Tag', 'FileSavedText'), 'Visible', 'off');

    return;
end


if strcmp(op, 'savefigpush')

    outdir = get(findobj('Tag', 'OutputDirText'), 'UserData');
    [dummy, fname] = fileparts(deblank(get(findobj('Tag', 'SaveFigText'), 'String')));
    if isempty(fname)
        fname = 'default';
    end
    type_list = get(findobj('Tag', 'SaveFigPopup'), 'String');
    type_val = get(findobj('Tag', 'SaveFigPopup'), 'Value');
    type = type_list{type_val};
    
    if strcmp(type, 'JPEG')
        fname = [fname '.jpg'];
        fname = fullfile(outdir, fname);
        print(fname, '-djpeg', '-painters', '-loose');

    elseif strcmp(type, 'TIFF')
        fname = [fname '.tif'];
        fname = fullfile(outdir, fname);
        print(fname, '-dtiff', '-painters', '-loose');

    elseif strcmp(type, 'EPS')
        fname = [fname '.eps'];
        fname = fullfile(outdir, fname);
        print(fname, '-depsc2', '-painters', '-loose');

    elseif strcmp(type, 'PNG')    
        fname = [fname '.png'];
        fname = fullfile(outdir, fname);
        print(fname, '-dpng', '-painters', '-loose');

    end

    set(findobj('Tag', 'FigSavedText'), 'String', ['Figure saved!: ' spm_str_manip(fname, 'a35')]);
    set(findobj('Tag', 'FigSavedText'), 'Visible', 'on');
    pause(1);
    %keyboard;
    set(findobj('Tag', 'FigSavedText'), 'Visible', 'off');
    return;
end