function varargout = set_sourceviewing_parameters(action,varargin)
%SET_SOURCEVIEWING_PARAMETERS - Application M-file for set_sourceviewing_parameters.fig
% function varargout = set_sourceviewing_parameters(action,varargin)

%<autobegin> ---------------------- 26-May-2004 11:34:22 -----------------------
% --------- Automatically Generated Comments Block Using AUTO_COMMENTS ---------
%
% CATEGORY: Visualization
%
% Alphabetical list of external functions (non-Matlab):
%   publictoolbox\othertools\view3d.m
%   toolbox\bst_color_scheme.m
%   toolbox\bst_imaging_display.m
%   toolbox\bst_layout.m
%   toolbox\bst_message_window.m
%   toolbox\makeuswait.m
%   toolbox\smooth_cortex.m
%   toolbox\tessellation_handler.m
%
% Subfunctions in this file, in order of occurrence in file:
%   hCurrPatch = get_current_patch
%
% Application data and their calls in this file:
%   'OriginalVertices'
%   'TessHandles'
%   'TileType'
%   
%   setappdata(ParamFig,'TileType','Tile')
%   setappdata(hParam.CurrentTessellation,'TessHandles',TessHandles)
%   setappdata(hPatch,'OriginalVertices',FV.vertices)
%   
%   TessHandles = getappdata(hFig.CurrentTessellation,'TessHandles')
%   set(hPatch,'Vertices',getappdata(hPatch,'OriginalVertices'))
%
% Figure Files opened by this function:
%   'set_sourceviewing_parameters.fig'
%
%   Format of strings below: Type:Style:Tag, "String", CallBack Type and Call
%   <automatic> callback is <Tag>_Callback by Matlab default
%
% Callbacks by figure set_sourceviewing_parameters.fig
%   uicontrol:edit:currDensityTruncateEdit "50" uses Callback for
%     set_sourceviewing_parameters currDensityTruncate
%   uicontrol:edit:editIterations "10" uses Callback for set_sourceviewing_parameters SmoothSurface
%   uicontrol:popupmenu:CurrentTessellation "<None available>" uses Callback for
%     set_sourceviewing_parameters CurrentTessellation
%   uicontrol:popupmenu:CutPlane "Top" uses Callback for set_sourceviewing_parameters CutPlane
%   uicontrol:popupmenu:Lighting "None" uses Callback for set_sourceviewing_parameters Lighting
%   uicontrol:pushbutton:pushbutton10 "Add" uses Callback for set_sourceviewing_parameters AddLight
%   uicontrol:pushbutton:pushbutton11 "Remove" uses Callback for
%     set_sourceviewing_parameters RemoveLight
%   uicontrol:pushbutton:pushbutton13 "Go" uses Callback for
%     set_sourceviewing_parameters SmoothSurface
%   uicontrol:pushbutton:Qpushbutton7 "Close" uses Callback for close(gcbf)
%   uicontrol:pushbutton:ResetSurface "Reset" uses Callback for
%     set_sourceviewing_parameters ResetSurface
%   uicontrol:pushbutton:togglebutton4 "Tessellation Handler" uses Callback for
%     set_sourceviewing_parameters CallTessellationHandler
%   uicontrol:slider:anatTransparency "" uses Callback for
%     set_sourceviewing_parameters anatTransparency
%   uicontrol:slider:currDensityTruncateSlider "" uses Callback for
%     set_sourceviewing_parameters currDensityTruncate
%   uicontrol:slider:CurvatureThresholdSlider "" uses Callback for
%     set_sourceviewing_parameters CurvatureThreshold
%   uicontrol:slider:SmoothSurface "" uses Callback for set_sourceviewing_parameters SmoothSurface
%   uicontrol:slider:SurfaceOpacity "" uses Callback for set_sourceviewing_parameters SurfaceOpacity
%   uicontrol:togglebutton:AddColorbar "Colorbar" uses Callback for
%     set_sourceviewing_parameters AddColorbar
%   uicontrol:togglebutton:OrthViews "Orth. Views" uses Callback for
%     set_sourceviewing_parameters OrthViews
%   uicontrol:togglebutton:ShowCurvature "Show" uses Callback for
%     set_sourceviewing_parameters MapCurvature
%   uicontrol:togglebutton:SurfaceColorPick "Color Pick" uses Callback for
%     set_sourceviewing_parameters('SurfaceColorPick')
%   uicontrol:togglebutton:togglebutton2 "Normalize" uses Callback for
%     set_sourceviewing_parameters NormalizeColorMap
%
% At Check-in: $Author: Mosher $  $Revision: 20 $  $Date: 5/26/04 10:02a $
%
% This software is part of BrainStorm Toolbox Version 2.0 (Alpha) 24-May-2004
% 
% Principal Investigators and Developers:
% ** Richard M. Leahy, PhD, Signal & Image Processing Institute,
%    University of Southern California, Los Angeles, CA
% ** John C. Mosher, PhD, Biophysics Group,
%    Los Alamos National Laboratory, Los Alamos, NM
% ** Sylvain Baillet, PhD, Cognitive Neuroscience & Brain Imaging Laboratory,
%    CNRS, Hopital de la Salpetriere, Paris, France
% 
% See BrainStorm website at http://neuroimage.usc.edu for further information.
% 
% Copyright (c) 2004 BrainStorm by the University of Southern California
% This software distributed  under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPL
% license can be found at http://www.gnu.org/copyleft/gpl.html .
% 
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%<autoend> ------------------------ 26-May-2004 11:34:22 -----------------------

% /---Script Authors-------------------------------------\
% |  *** Sylvain Baillet, Ph.D.                          |
% |  Cognitive Neuroscience & Brain Imaging Laboratory   |
% |  CNRS UPR640 - LENA                                  | 
% |  Hopital de la Salpetriere, Paris, France            |
% |  sylvain.baillet@chups.jussieu.fr                    |
% |                                                      |
% |  *** John C. Mosher, Ph.D.                           |
% |  Biophysics Group                                    |
% \------------------------------------------------------/
%  
% Date of creation: May 2002

% Script History -----------------------------------------
%---------------------------------------------------------


global data % Get informations from the main Viewer window

switch(action)
    
case 'create' % Create display-parameter window 
    
    ParamFig = openfig('set_sourceviewing_parameters.fig','reuse');
    setappdata(ParamFig,'TileType','Tile')
    bst_color_scheme(ParamFig);
    bst_layout('align',ParamFig,2,2,4);
    
    % Fill out pull-down menu with surface names
    TessName{1} = data.Results.Display.SurfaceName;
    % Associate handle to each entry of pull-down for fast access to object 
    TessHandles(1) = data.Results.Display.Handles.hPatch;
    try
        if ishandle(data.Results.Display.Handles.TopoPlot(1).surf{1}) % CHEAT - one modality, one dataset
            TessName{2} = data.Results.Display.Handles.TopoPlot(1).SurfaceName{1};
            TessHandles(2) = data.Results.Display.Handles.TopoPlot(1).surf{1};
        end
    catch
        % do nothing (error occurs when no scalp plot has been required)
    end
    
    hParam = guihandles(ParamFig);
    
    set(hParam.CurrentTessellation,'String',TessName)
    setappdata(hParam.CurrentTessellation,'TessHandles',TessHandles) % Store for future reference
    
    set(ParamFig,'Visible','on')
    
case 'SurfaceColorPick' % Pick 2 new colors for surface curvature
    
    OPTIONS = data.Results.Display.OPTIONS;
    OPTIONS.hPatch = data.Results.Display.Handles.hPatch;
    
    
    OPTIONS.CurvatureColor1 = uisetcolor(OPTIONS.CurvatureColor1, 'Pick first color for curvature mapping');
    OPTIONS.CurvatureColor2 = uisetcolor(OPTIONS.CurvatureColor2, 'Pick second color for curvature mapping');
    
    if ~ishandle(data.Results.Display.Handles.hPatch) % Is the patch surface still there ?
        return % no, do nothing
    end
    
    if ~isfield(OPTIONS,'Curvature') % Curvature was not computed yet
        [PlotHandles,OPTIONS] = ...
            bst_imaging_display(data.Results.Display.Figure,OPTIONS.ImageGrid,data.Results.ImageGridAmp,OPTIONS);
    else
        [tmp,OPTIONS] = bst_imaging_display(data.Results.ImageGridAmp,OPTIONS); clear tmp
        data.Results.Display.OPTIONS = OPTIONS;
    end
    
    
    
    
case 'AddLight' % Add a camlight to the surface display window
    figure(data.Results.Display.Handles.Figures.Surfaces)
    if isempty(data.Results.Display.Handles.Figures.Surfaces)
        return
    end
    h = camlight('headlight');
    set(h,'color','w'); % mute the intensity of the lights
    data.Results.Display.Handles.hLights = [data.Results.Display.Handles.hLights,h]; % Store last light object to list
    view3d rot;
    
    
case 'RemoveLight' % Remove last camlight
    
    figure(data.Results.Display.Handles.Figures.Surfaces)
    if isempty(data.Results.Display.Handles.Figures.Surfaces)
        return
    end
    if ~isempty(data.Results.Display.Handles.hLights) % Is there is still some light here ?
        if ishandle( data.Results.Display.Handles.hLights(end) ),
            delete(data.Results.Display.Handles.hLights(end));
        end
        if length( data.Results.Display.Handles.hLights ) > 1
            data.Results.Display.Handles.hLights =...
                [data.Results.Display.Handles.hLights(1:end-1)];
        else
            data.Results.Display.Handles.hLights = [];
        end
    end
    view3d rot;
     
case 'Lighting' % Alter lighting properties of the display
    
    figure(data.Results.Display.Handles.Figures.Surfaces)
    if isempty(data.Results.Display.Handles.Figures.Surfaces)
        return
    end
    fighandles = guihandles(gcbf);
    tmp = get(fighandles.Lighting,'String');
    
    try 
        set(findobj(data.Results.Display.Handles.Figures.Surfaces,'type','patch'),'edgelighting',tmp{get(fighandles.Lighting,'Value')},...
            'facelighting',tmp{get(fighandles.Lighting,'Value')})
        
    catch
        if ~isempty(findstr(tmp{get(fighandles.Lighting,'Value')},'Flat'))
            set(findobj(data.Results.Display.Handles.Figures.Surfaces,'type','patch'),...
                'facecolor','flat')
        else
            set(findobj(data.Results.Display.Handles.Figures.Surfaces,'type','patch'),...
                'facecolor','interp')
        end
        
    end
    
case 'ToggleButtonColor' % Turn bi-stable buttons in green when selected
    
    Green = [.66 1 .43]; % 'selected' color
    Dark = [.4 .4 .4]; % 'unselect' color
    
    if nargin == 1
        handle = get(gcbf,'CurrentObject');
    else
        handle = varargin{1};
    end
    
    if get(handle,'Value')
        set(handle,'Backgroundcolor',Green,'Foregroundcolor',Dark)
    else
        set(handle,'Backgroundcolor',Dark,'Foregroundcolor','w')
    end
    
case 'MapCurvature' % Map curvature of cortical surface on/off
    
    % Get current patch 
    hCurrPatch = get_current_patch;
    
    
    eval([mfilename,' ToggleButtonColor']) % Toggle selected button on/off
    if ~ishandle(data.Results.Display.Handles.hPatch) % Is the patch surface still there ?
        return % no, do nothing
    end
    
    OPTIONS = data.Results.Display.OPTIONS;
    OPTIONS.hPatch = data.Results.Display.Handles.hPatch;
    
    switch get(gcbo,'Value')
    case 1 % Turn curvature on
        OPTIONS.MapCurvature = 1;
        bst_message_window({...
                ' ',...
                'Surface Curvature: ON'})
    case 0
        OPTIONS.MapCurvature = 0;
        bst_message_window({...
                ' ',...
                'Surface Curvature: OFF'})
    end
    
    if ~isfield(OPTIONS,'Curvature') % Curvature was not computed yet
        [PlotHandles,OPTIONS] = ...
            bst_imaging_display(data.Results.Display.Figure,OPTIONS.ImageGrid,data.Results.ImageGridAmp,OPTIONS);
    else
        [tmp,OPTIONS] = bst_imaging_display(data.Results.ImageGridAmp,OPTIONS); clear tmp
        data.Results.Display.OPTIONS = OPTIONS;
    end
    
case 'anatTransparency' % Alter transparency properties of current map on top of anatomy 
    fighandles = guihandles(gcbf);
    transVal = get(fighandles.anatTransparency,'Value'); % Get value from slider
    % Alter transparency parameter
    data.Results.Display.OPTIONS.currDensityTransparency = transVal;
    makeuswait('start')
    [tmp,OPTIONS] = bst_imaging_display(data.Results.ImageGridAmp,data.Results.Display.OPTIONS); clear tmp
    makeuswait('stop')
    
case 'currDensityTruncate' % Truncate current density map in % of maximum amplitude
    
    makeuswait('start')
    fighandles = guihandles(gcbf);
    CDThreshold = get(fighandles.currDensityTruncateSlider,'Value'); % Get value from slider
    % Alter truncate parameter
    data.Results.Display.OPTIONS.CDThreshold = CDThreshold;
    set(fighandles.currDensityTruncateEdit,'String',CDThreshold*100)
    [tmp,OPTIONS] = bst_imaging_display(data.Results.ImageGridAmp,data.Results.Display.OPTIONS); clear tmp
    makeuswait('stop')
    
case 'NormalizeColorMap' % Switch from absolute and relative colormap
    
    makeuswait('start')
    eval([mfilename,' ToggleButtonColor']) % Toggle selected button on/off
    if ~ishandle(data.Results.Display.Handles.hPatch) % Is the patch surface still there ?
        return % no, do nothing
    end
     
    switch get(gcbo,'Value')
    case 1 % Normalize color scale
        bst_message_window({...
                ' ',...
                'Current density color mapping: Normalized'})
        
        data.Results.Display.OPTIONS.ColorMapping = 'normalized';
        [tmp, data.Results.Display.OPTIONS] = ...
            bst_imaging_display(data.Results.ImageGridAmp,data.Results.Display.OPTIONS); clear tmp
        
    case 0 % Absolute color mapping over entire time window
        
        OPTIONS.MapCurvature = 0;
        bst_message_window({...
                ' ',...
                'Current density color mapping: Relative'})

        data.Results.Display.OPTIONS.ColorMapping = 'relative';
        [tmp, data.Results.Display.OPTIONS] = ...
            bst_imaging_display(data.Results.ImageGridAmp,data.Results.Display.OPTIONS); clear tmp

    end
    
    makeuswait('stop')
    
    
case 'SurfaceOpacity' % Change transparency properties of current surface
    
    fighandles = guihandles(gcbf);
    alpha = get(fighandles.SurfaceOpacity,'Value'); % Alpha value to be applied to current surface
    
    hPatch = get_current_patch;%data.Results.Display.Handles.hPatch;
    
    makeuswait('start')
    set(hPatch,'FaceVertexAlpha',alpha,'facealpha','flat')
    data.Results.Display.OPTIONS.FaceVertexAlpha = alpha;
    makeuswait('stop')
    
case 'SmoothSurface' % Smooth selected tessellated surface using Pantazis routine
    
    fighandles = guihandles(gcbf);
    alpha = get(fighandles.SmoothSurface,'Value'); % Smoothing constant / Get value from slider
    nIterations = round(str2num(get(fighandles.editIterations,'String')));
    
    %hPatch = data.Results.Display.Handles.hPatch;
    hPatch = get_current_patch;%data.Results.Display.Handles.hPatch;
    FV.vertices = get(hPatch,'Vertices');
    FV.faces = get(hPatch,'Faces');
    
    makeuswait('start')
    [smoothedFV,A] = smooth_cortex(FV,data.Results.Display.OPTIONS.VertConn,alpha,nIterations);
    
    % Apply and Store original vertices locations in userdata of patch object (see ResetSurface)
    if ~isappdata(hPatch,'OriginalVertices');
        setappdata(hPatch,'OriginalVertices',FV.vertices)
    end
    set(hPatch,'Vertices',smoothedFV.vertices)
    makeuswait('stop')
    
    
case 'ResetSurface' % Back to original non-smoothed surface
    
    hPatch = get_current_patch;%data.Results.Display.Handles.hPatch;
    makeuswait('start')
    set(hPatch,'Vertices',getappdata(hPatch,'OriginalVertices')) % original vertices were stored in smoothed patch UserData
    makeuswait('stop')
    
case 'CurvatureThreshold' % Change color threshold for mapping of convex vs. concave surface areas
    
    fighandles = guihandles(gcbf);
    data.Results.Display.OPTIONS.CurvatureThreshold = get(fighandles.CurvatureThresholdSlider,'Value'); %Get value from slider
    % Update display
    makeuswait('start')
    [tmp,OPTIONS] = bst_imaging_display(data.Results.ImageGridAmp,data.Results.Display.OPTIONS); clear tmp
    makeuswait('stop')
    
case 'CallTessellationHandler'
    
    tessellation_handler
    
end



% --------------------------------------------------------------------
function hCurrPatch = get_current_patch
% Return handle to current patch selected in pulldpwn menu (e.g. cortex or scalp)
hFig = guihandles(gcbf);
TessHandles = getappdata(hFig.CurrentTessellation,'TessHandles') ;
iTess = get(hFig.CurrentTessellation,'Value');
hCurrPatch = TessHandles(iTess);





