function varargout = results_visualization(varargin)
%RESULTS_VISUALIZATION - Application M-file View the results of source modeling
% function varargout = results_visualization(varargin)
%    FIG = RESULTS_VISUALIZATION launch results_visualization GUI.
%    RESULTS_VISUALIZATION('callback_name', ...) invoke the named callback.
%
% Launches MRI_READ_TOOL as companion for orthogonal viewing of results
% E.G. 
%    fig = results_visualization;
%    fighandles = guihandles(fig);
%    results_visualization('loadparametric_Callback',...
%      fighandles.loadparametric, [], fighandles, ResultsFname);
% where ResultsFname is the name of a BrainStorm results file,
% or do not include ResultsFname for an interactive load.
%
% See also MRI_READ_TOOL

%<autobegin> ---------------------- 26-May-2004 11:34:17 -----------------------
% --------- Automatically Generated Comments Block Using AUTO_COMMENTS ---------
%
% CATEGORY: Visualization
%
% Alphabetical list of external functions (non-Matlab):
%   toolbox\bst_color_scheme.m
%   toolbox\bst_layout.m
%   toolbox\bst_message_window.m
%   toolbox\get_user_directory.m
%   toolbox\good_channel.m
%   toolbox\mri_read_tool.m
%   toolbox\transform.m
%
% Subfunctions in this file, in order of occurrence in file:
%   varargout = loadparametric_Callback(h, eventdata, handles, varargin)
%   varargout = sourcelist_Callback(h, eventdata, handles, varargin)
%   varargout = loadsources_Callback(h, eventdata, handles, varargin)
%   varargout = loadnonparametric_Callback(h, eventdata, handles, varargin)
%   varargout = sourceparams_Callback(h, eventdata, handles, varargin)
%   varargout = sourcelistmenu_Callback(h, eventdata, handles, varargin)
%   varargout = deletesource_Callback(h, eventdata, handles, varargin)
%   ShowSourceTopography_Timecourse(h, eventdata, handles, sourcenumber)
%   p = InitDrawSource(pos,or,name,mri_scan,mritoolhandles,col,marker,offset)
%   mainud = InitTopographyPlot(handles,Chanfname,ChannelFlag)
%   varargout = hidesource_Callback(h, eventdata, handles, varargin)
%   varargout = hideall_Callback(h, eventdata, handles, varargin)
%   varargout = deleteall_Callback(h, eventdata, handles, varargin)
%   varargout = showall_Callback(h, eventdata, handles, varargin)
%   varargout = Quit_Callback(h, eventdata, handles, varargin)
%   varargout = showsource_Callback(h, eventdata, handles, varargin)
%   varargout = tools_Callback(h, eventdata, handles, varargin)
%   varargout = rot3d_Callback(h, eventdata, handles, varargin)
%   varargout = sourcelist_ButtondownFcn(h, eventdata, handles, varargin)
%   varargout = indeptopo_ButtondownFcn(h, eventdata, handles, varargin)
%   varargout = timecoursemenu_Callback(h, eventdata, handles, varargin)
%   varargout = addon_Callback(h, eventdata, handles, varargin)
%   varargout = ShowAllTopos_Callback(h, eventdata, handles, varargin)
%   LocSetTight(ax);
%
% Application data and their calls in this file:
%   'TileType'
%   'mri_fig'
%   'resviewerhandle'
%   
%   setappdata(fig,'TileType','T');
%   setappdata(fig,'mri_fig',h_mritool);
%   setappdata(fig,'mri_fig',mri_fig);
%   setappdata(handles.sourceview_main,'mri_fig',h_mritool);
%   setappdata(mainud.multitopofigure,'TileType','T');
%   setappdata(mri_fig,'resviewerhandle',fig);
%   
%   h_mritool = getappdata(fig,'mri_fig');
%   mritoolhandles = guidata(getappdata(handles.sourceview_main,'mri_fig'));
%   ud = get(getappdata(handles.sourceview_main,'mri_fig'),'UserData');
%
% Figure Files opened by this function:
%   mfilename
%
%   Format of strings below: Type:Style:Tag, "String", CallBack Type and Call
%   <automatic> callback is <Tag>_Callback by Matlab default
%
% Callbacks by figure results_visualization.fig
%   axes::indeptopo "" uses ButtonDownFcn for
%     results_visualization('indeptopo_ButtondownFcn',gcbo,[],guidata(gcbo))
%   uicontextmenu::sourcelistmenu "" uses Callback for <automatic>
%   uicontextmenu::timecoursemenu "" uses Callback for <automatic>
%   uicontrol:listbox:sourcelist "Listbox" uses ButtonDownFcn for
%     results_visualization('sourcelist_ButtondownFcn',gcbo,[],guidata(gcbo))
%   uicontrol:listbox:sourcelist "Listbox" uses Callback for <automatic>
%   uicontrol:listbox:sourceparams "" uses Callback for <automatic>
%   uicontrol:pushbutton:Quit "Quit" uses Callback for <automatic>
%   uicontrol:pushbutton:ShowAllTopos "Show All Topographies" uses Callback for <automatic>
%   uimenu::addon "" uses Callback for <automatic>
%   uimenu::deleteall "" uses Callback for <automatic>
%   uimenu::deletesource "" uses Callback for <automatic>
%   uimenu::hideall "" uses Callback for <automatic>
%   uimenu::hidesource "" uses Callback for <automatic>
%   uimenu::loadnonparametric "" uses Callback for <automatic>
%   uimenu::loadparametric "" uses Callback for <automatic>
%   uimenu::loadsources "" uses Callback for <automatic>
%   uimenu::rot3d "" uses Callback for <automatic>
%   uimenu::showall "" uses Callback for <automatic>
%   uimenu::showsource "" uses Callback for <automatic>
%   uimenu::tools "" uses Callback for <automatic>
%
% At Check-in: $Author: Mosher $  $Revision: 29 $  $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:17 -----------------------


% Last Modified by GUIDE v2.0 05-Nov-2002 19:14:07

% ------------ History ------------------------------
% AOS Summer 2002  First creation forms by Alex Ossadtchi, USC
% JCM 19-May-2003  bst_layout updates
% SB  25-Jul-2003  initiate plug into new Viewer
% JCM 16-Nov-2003  commenting, verbosity
% JCM 17-Nov-2003  fix bug for deleting sources, their timeplot remained.
% JCM 11-Dec-2003  added multi color option from old version of Alex
% JCM 05-Jan-2003  fixed filename problem by using fullfile
% ------------ History ------------------------------

VERBOSE = 0; % no chatty messages displayed

if nargin == 0  % LAUNCH GUI
   
   fig = openfig(mfilename,'reuse');
   
   % Use system color scheme for figure:
   %set(fig,'Color',get(0,'defaultUicontrolBackgroundColor'));
   
   % Generate a structure of handles to pass to callbacks, and store it. 
   handles = guihandles(fig);
   guidata(fig, handles);
   
   if nargout > 0
      varargout{1} = fig;
   end
   
   bst_color_scheme(fig);
   setappdata(fig,'TileType','T');
   bst_layout('align',fig,1,2,2);
   set(fig,'Visible','on')
   
   
   % now open up a unique mri window for just this window
   mri_fig = mri_read_tool; % new window
   setappdata(mri_fig,'resviewerhandle',fig);
   
   setappdata(fig,'mri_fig',mri_fig); % save the handle
   
   if VERBOSE,
      bst_message_window({'Welcome to source visualization!'...
            'Choose LoadSources\Load Parametric menu'...
            'to load new set of sources'...
            '------------------'});
   end
   
       
elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK
   
   try
      if (nargout)
         [varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
      else
         feval(varargin{:}); % FEVAL switchyard
      end
   catch
      disp(lasterr);
   end
   
end


% ------------------------ Local Functions ------------------

% --------------------- Callbacks ----------------------------


% --------------------------------------------------------------------
function varargout = loadparametric_Callback(h, eventdata, handles, varargin)
% Menu call to load parametric results
% If varargin{1} has the name of a file, use it

VERBOSE = 0;

fig = handles.sourceview_main; % figure handle
figure(fig); % bring forward
h_mritool = getappdata(fig,'mri_fig'); % the corresponding mri window
figure(h_mritool); % bring forward

Current = get_user_directory; % current database information

if(isempty(varargin)), % nothing given on input, a GUI call
   cd(Current.STUDIES)
   [result_file,result_dir] = uigetfile('*result*.mat','Load Result Structure from...');
   if result_file == 0, 
      return, 
   end
   Results = load(fullfile(result_dir,result_file));
else
   % varargin{1} is assumed to have the results file
   Results = load(fullfile(Current.STUDIES,varargin{1}));
end

try 
   Data = load(fullfile(Current.STUDIES,Results.GUI.DataName)); % load corresponding data
catch
   Data = [];
end;

if VERBOSE,
   bst_message_window({'Results file'...
         sprintf('%s',fullfile(Current.STUDIES,Results.GUI.DataName))...
         'loaded into results visualization tool'...
         '------------------'});
   
   bst_message_window({'Click on the list of sources to place a source on the MRI scan'...
         'To append list of sources choose LoadSources\Load Parametric '...
         'To delete a source from the list right click '...
         'while the cursor is over the source list to get a drop-down menu'...
         'and choose an appropriate action'...
         '------------------'});
end

nsource = length(Results.SourceLoc);
listud = get(handles.sourcelist,'UserData');
try
% if list is empty open MRI tool window 
if(isfield(Results.Subject,'SubjectImage'))
   SubjectImageFile = fullfile(Current.SUBJECTS,Results.Subject.SubjectImage);
elseif(isfield(Results.Subject,'Anatomy'))
   SubjectImageFile = fullfile(Current.SUBJECTS,Results.Subject.Anatomy);
else
   warndlg('<Anatomy> or <SubjectImage> fields are not specified in the Results.Subject object');
   
   bst_message_window({'Warning!: <Anatomy> or <SubjectImage> fields are'...
            'not specified in the Results.Subject object'...
            '------------------'});
   return;
end;
catch
   warndlg('Results structure does not contain all necessary fields');
end;
    

[PATHSTR,NAME,EXT,VERSN] = fileparts(SubjectImageFile);
filebs = [NAME EXT]; 
pathbs = PATHSTR; 
SubjectImageFile = fullfile(pathbs,filebs);

%mri_read_tool('readbs_Callback',[],[],guidata(h_mritool),SubjectImageFile);
%h_mritool = getappdata(handles.sourceview_main,'mritool_handle');

mri_scan = get(h_mritool,'UserData');
if(isempty(mri_scan))
    mri_read_tool('readbs_Callback',[],[],guidata(h_mritool),SubjectImageFile);
    mri_scan = get(h_mritool,'UserData');
end;
    
OldSubjectImageFile = mri_scan.filename;
if(~strcmp(SubjectImageFile,OldSubjectImageFile))
    if(strcmp(questdlg('Results are from the different subject than currently loaded into MRI_tool. Reload the new mri file?','What to do, Master!','Yes','No','Yes'),'Yes'))
           deleteall_Callback(h, eventdata, handles, varargin);
           delete(h_mritool); 
           h_mritool = mri_read_tool; % new window
           setappdata(fig,'mri_fig',h_mritool); % save the handle
           mri_read_tool('readbs_Callback',[],[],guidata(h_mritool),SubjectImageFile);
           listud = get(handles.sourcelist,'UserData');
           mri_scan = get(h_mritool,'UserData');
    end;
end;           

if(isempty(mri_scan))
   warndlg('There was a problem loading MR image into the MRI_Tool, please check appropriate pathes');
   delete(h_mritool);
   return;
end;


PCS.R = inv(mri_scan.rot);
PCS.t = mri_scan.center;

if(isfield(listud,'Source'))
   n_old = length(listud.Source);
   listud.nloads = listud.nloads + 1;
else
   n_old = 0;
   listud.nloads = 1;
end;

listud.ChannelFlag = Results.ChannelFlag;
set(handles.sourcetimeseries,'NextPlot','Add');
for n=1:nsource
   
   listud.Source{n_old+n}.ChannelFlag = Results.ChannelFlag;
   listud.Source{n_old+n}.ptname = num2str(n+n_old);
   listud.Source{n_old+n}.ptcoord = Results.SourceLoc{n};
   listud.Source{n_old+n}.TimeSeries = Results.TimeSeries(:,n);
   
   
   if isfield(Results,'DataFlag') % Original data: either MEG, EEG or Fusion 
      listud.Source{n_old+n}.DataFlag = Results.DataFlag;
   else
      listud.Source{n_old+n}.DataFlag = 'MEG'; % Assume default
   end
   
   
   if(~isempty(Data))
       listud.Source{n_old+n}.Time = Data.Time(Results.Time);
   else
       listud.Source{n_old+n}.Time =  1:length(listud.Source{n_old+n}.TimeSeries);
   end;
   
   % JCM 15-Nov-2003 for some reason, AOS removed the mean. Reversed that
   %  and multiplied the time series  by 1e9 to yield nA-m
   if 0,
      listud.Source{n_old+n}.TCPlotHandle = plot(listud.Source{n_old+n}.Time*1000,...
         listud.Source{n_old+n}.TimeSeries-...
         mean(listud.Source{n_old+n}.TimeSeries),...
         'LineWidth',1,'Color','b','Visible','off',...
         'Parent',handles.sourcetimeseries);
   else
      % time in milliseconds, amplitude in nA-m
      listud.Source{n_old+n}.TCPlotHandle = plot(listud.Source{n_old+n}.Time * 1000,...
         listud.Source{n_old+n}.TimeSeries * 1e9,...
         'LineWidth',1,'Color','b','Visible','off',...
         'Parent',handles.sourcetimeseries);
   end

   
   listud.Source{n_old+n}.SourceCorrelation = Results.SourceCorrelation(n);      
   listud.Source{n_old+n}.IndepTopo = Results.IndepTopo(:,n);
   
   if(isfield(Results.StudySubject,'Channel')) % Channel is a field from StudySubject
      listud.Source{n_old+n}.Channel=Results.StudySubject.Channel;      
   elseif(isfield(Results.Study,'Channel'))
      listud.Source{n_old+n}.Channel=Results.Study.Channel;
   else
      listud.Source{n_old+n}.Channel=[];
      bst_message_window({sprintf('Default channel file %s not found',ChannelTest),...
            'Source topography will not be available'});
   end;
   
   
   listud.Source{n_old+n}.SourceOrder = Results.SourceOrder(n);
   listud.Source{n_old+n}.Comment = Results.Comment;
   listud.Source{n_old+n}.ptcoordMRI = transform('rap2mri',Results.SourceLoc{n},PCS);
   if(listud.Source{n_old+n}.SourceOrder==-1)
       tmp = transform('rap2mri',Results.SourceOrientation{n},PCS);                                         
       listud.Source{n_old+n}.ptorientMRI = tmp/norm(tmp);
   elseif(listud.Source{n_old+n}.SourceOrder==2)
       tmp = transform('rap2mri',Results.SourceOrientation{n}(1:3),PCS);                                         
       listud.Source{n_old+n}.ptorientMRI(:,1) = tmp/norm(tmp);
       tmp = transform('rap2mri',Results.SourceOrientation{n}(4:6),PCS);                                         
       listud.Source{n_old+n}.ptorientMRI(:,2) = tmp/norm(tmp);
   else
       listud.Source{n_old+n}.ptorientMRI = [0 0 0]';
   end;
end;
% update sourcelist structure    
aux={};  
for n = 1:length(listud.Source)
   aux{n}=listud.Source{n}.ptname;
end;
set(handles.sourcelist,'Value',1,'String',aux);
set(handles.sourcelist,'Userdata',listud);

% and show topography and time course
ShowSourceTopography_Timecourse(h, eventdata, handles, 1);
setappdata(handles.sourceview_main,'mri_fig',h_mritool);

mri_scan = get(h_mritool,'UserData');
mritoolhandles = guidata(getappdata(handles.sourceview_main,'mri_fig'));

colors = ['c' 'r' 'g' 'b' 'm' 'y'];
ncolors = length(colors);

SourceMarkers = {'o','s','>','o','s','>'};
for n=1:nsource
   or = listud.Source{n_old+n}.ptorientMRI;  
   offset = 1;
   pname = [listud.Source{n_old+n}.ptname];
   if(listud.Source{n_old+n}.SourceOrder<2)
      col = colors(mod(listud.nloads,ncolors)+1);
      offset = 1;
   else
      col = 'g';
      offset = -1;
   end
   pos = listud.Source{n_old+n}.ptcoordMRI;  
   aux = [];
   
   for k=1:size(pos,2)
      p = InitDrawSource(pos(:,k),or(:,min(k,size(or,2))),[pname repmat('"',1,k-1)],mri_scan,mritoolhandles,col,SourceMarkers{listud.Source{n_old+n}.SourceOrder+2},offset);
      aux = [aux p.pt_s p.pln_s p.pl_s p.pt_a p.pln_a p.pl_a p.pt_c p.pln_c p.pl_c];
   end;
   if(n>1)
      set(aux,'Visible','off');
   end;
   listud.Source{n_old+n}.pthandle = aux;
end;

coord = listud.Source{n_old+1}.ptcoordMRI;
set(mritoolhandles.slider2,'Value',coord(3)/mri_scan.fov(3));
mri_read_tool('slider2_Callback',mritoolhandles.slider2, eventdata, mritoolhandles, varargin);   
set(mritoolhandles.slider3,'Value',1-coord(2)/mri_scan.fov(2));        
mri_read_tool('slider3_Callback',mritoolhandles.slider3, eventdata, mritoolhandles, varargin);   
set(mritoolhandles.slider1,'Value',coord(1)/mri_scan.fov(1));        
mri_read_tool('slider1_Callback', mritoolhandles.slider1, eventdata, mritoolhandles, varargin);   



set(handles.sourcelist,'UserData',listud);

% --------------------------------------------------------------------
function varargout = sourcelist_Callback(h, eventdata, handles, varargin)

listud = get(handles.sourcelist,'UserData');
mainud = get(handles.sourceview_main,'UserData');

if(isempty(get(handles.sourcelist,'String')))
    return;
end;

val = get(h,'Value');
ShowSourceTopography_Timecourse(h, eventdata, handles, val);

%if(strcmp(get(handles.addon,'Checked'),'on'))
%    if(isfield(mainud,'stack'))
%        mainud.stack = unique([mainud.stack,val]);
%    else
%        mainud.stack = val;
%    end;
%else
%    mainud.stack=[];
%end;

listud = get(h,'UserData');
if(isempty(listud)) return; end;

%obrain vector of MRI_tool handles
try
   mritoolhandles = guidata(getappdata(handles.sourceview_main,'mri_fig'));
catch
   warndlg('You have accidentially closed MRI_tool window. Please reload the sources in order to open a new MRI_tool instance');
   return;
end;

mri_scan = get(mritoolhandles.mrireadtool_main,'Userdata');
figure(mritoolhandles.mrireadtool_main);
if(val>0)
   
   hlist = handles.sourcelist;
   coord = listud.Source{val}.ptcoordMRI;
   
   set(listud.Source{val}.pthandle,'Visible','on');
   
   set(mritoolhandles.slider2,'Value',coord(3)/mri_scan.fov(3));        
   mri_read_tool('slider2_Callback',mritoolhandles.slider2, eventdata, mritoolhandles, varargin);   
   set(mritoolhandles.slider3,'Value',1-coord(2)/mri_scan.fov(2));        
   mri_read_tool('slider3_Callback',mritoolhandles.slider3, eventdata, mritoolhandles, varargin);   
   set(mritoolhandles.slider1,'Value',coord(1)/mri_scan.fov(1));        
   mri_read_tool('slider1_Callback', mritoolhandles.slider1, eventdata, mritoolhandles, varargin);   
else
   return;
end;





% --------------------------------------------------------------------
function varargout = loadsources_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = loadnonparametric_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = sourceparams_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = sourcelistmenu_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = deletesource_Callback(h, eventdata, handles, varargin)

listud = get(handles.sourcelist,'UserData');
if(isempty(listud))
    return;
end;
num = get(handles.sourcelist,'Value');
set(listud.Source{num}.pthandle,'Visible','off');
set(listud.Source{num}.TCPlotHandle,'Visible','off');

for k = 1:length(listud.Source{num}.pthandle)
   delete(listud.Source{num}.pthandle(k))
end;  
listud.Source(num)=[];

aux={};  
for n = 1:length(listud.Source)
   aux{n}=listud.Source{n}.ptname;
end;
set(handles.sourcelist,'Value',1,'String',aux);
set(handles.sourcelist,'Userdata',listud);

if(length(listud.Source)>0)
   ShowSourceTopography_Timecourse(h, eventdata, handles,1);    
else
   axes(handles.indeptopo); cla;
   axes(handles.sourcetimeseries); cla;
end;



% ------------------------------------------------------------------------  
function ShowSourceTopography_Timecourse(h, eventdata, handles, sourcenumber)

% obtain two main handles

SourceTypes = {'Current Dipole','Magnetic Diplole',...
      '1-st order multipole', ...
      'Synchronous Pair of Dipoles',...
      'Synchronous Pair of Magnetic Diploles',...
      'Synchronous Pair of of the 1-st order multipoles'};
Current = get_user_directory;
listud = get(handles.sourcelist,'UserData');
mainud = get(handles.sourceview_main,'UserData');

if(~isempty(listud.Source{sourcenumber}.Channel))
       chanfilename = fullfile(Current.STUDIES, listud.Source{sourcenumber}.Channel);
       if(isempty(mainud))
          mainud = InitTopographyPlot(handles,chanfilename,listud.Source{sourcenumber}.ChannelFlag);
       elseif(~strcmp(mainud.ChanFileName,chanfilename))
          axes(handles.indeptopo); cla;
%          set(handles.indeptopo,'NextPlot','replace');
          mainud = InitTopographyPlot(handles,chanfilename,listud.Source{sourcenumber}.ChannelFlag);
       end;
   
       XI = mainud.InterpChanPos;
       X0 = mainud.OrigChanPos;
       v = listud.Source{sourcenumber}.IndepTopo;
       Vp = griddata(X0(:,1),X0(:,2),v,XI{1},XI{2},'invdist');
       set(mainud.toposurf,'CData',Vp,'Visible','on','facecolor','interp');
       set(get(mainud.toposurf,'Parent'),'Ydir','normal');
%       axis square
       set(handles.indeptopo,'Visible','off','View',[-180 90]);
       set(get(handles.indeptopo,'parent'),'Colormap',mainud.ColorMap);
else
   if(~isempty(mainud))
      try
         set(mainud.toposurf,'Visible','off');
      catch
      end;
   end;
end;

if(strcmp(get(handles.addon,'Checked'),'off'))
    for k = 1:length(listud.Source)
        set(listud.Source{k}.TCPlotHandle,'Visible','off');
    end;
end;
for k = 1:length(listud.Source)
    set(listud.Source{k}.TCPlotHandle,'Color','b','LineWidth',1);
end;
set(listud.Source{sourcenumber}.TCPlotHandle,'Visible','on','LineWidth',1.5,'Color',[0.7 0.1 0.2]);
LocSetTight(handles.sourcetimeseries);

ud = get(getappdata(handles.sourceview_main,'mri_fig'),'UserData');
if(isfield(ud,'filename'))
    paramstring{1} = ['Subject: ' ud.filename];
else
    paramstring{1} = ['Subject: ' 'Unknown'];
end;
    
paramstring{2} = SourceTypes{listud.Source{sourcenumber}.SourceOrder+2};
paramstring{3} = ['Correlation:' num2str(listud.Source{sourcenumber}.SourceCorrelation)];
paramstring{4} = ['Comment:' listud.Source{sourcenumber}.Comment];
set(handles.sourceparams,'String',paramstring);


% ---------------------------------------------------------------------
function p = InitDrawSource(pos,or,name,mri_scan,mritoolhandles,col,marker,offset)

vs = 10;  

x1 = pos(1);   
x2 = pos(2);   
x3 = pos(3);   
o1 = [x1 x1+or(1)];
o2 = [x2 x2+or(2)];
o3 = [x3 x3+or(3)];

pname = name;
p.pt_s=patch('parent',mritoolhandles.axs,'xdata',x2,'ydata',x3,'Marker',marker,'MarkerEdgeColor','none','MarkerFaceColor',col);
vor =[or(2) or(3)];
ox = [x2 x2+vs*vor(1)];
oy = [x3 x3+vs*vor(2)];
p.pln_s = line('parent',mritoolhandles.axs,'xdata',ox,'ydata',oy,'LineWidth',2,'Color',col);
p.pl_s = text(x2+offset,x3+offset,pname,'Color','w','parent',mritoolhandles.axs,'FontSize',10,'FontWeight','demi');
set(p.pl_s,'ButtonDownFcn','mri_read_tool(''sag_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
set(p.pt_s,'ButtonDownFcn','mri_read_tool(''sag_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
set(p.pln_s,'ButtonDownFcn','mri_read_tool(''sag_ButtonDownFcn'',gcbo,[],guidata(gcbo))');

p.pt_a=patch('parent',mritoolhandles.axa,'xdata',x2,'ydata',x1,'Marker',marker,'MarkerEdgeColor','none','MarkerFaceColor',col);
p.pl_a = text(x2+offset,x1+offset,pname,'Color','w','parent',mritoolhandles.axa,'FontSize',10,'FontWeight','demi');
vor =[or(2) or(1)];
ox = [x2 x2+vs*vor(1)];
oy = [x1 x1+vs*vor(2)];
p.pln_a = line('parent',mritoolhandles.axa,'xdata',ox,'ydata',oy,'LineWidth',2,'Color',col);
set(p.pl_a,'ButtonDownFcn','mri_read_tool(''ax_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
set(p.pt_a,'ButtonDownFcn','mri_read_tool(''ax_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
set(p.pln_a,'ButtonDownFcn','mri_read_tool(''ax_ButtonDownFcn'',gcbo,[],guidata(gcbo))');

p.pt_c=patch('parent',mritoolhandles.axc,'xdata',x1,'ydata',x3,'Marker',marker,'MarkerEdgeColor','none','MarkerFaceColor',col);
p.pl_c = text(x1+offset,x3+offset,pname,'Color','w','parent',mritoolhandles.axc,'FontSize',10,'FontWeight','demi');
vor =[or(1) or(3)];
ox = [x1 x1+vs*vor(1)];
oy = [x3 x3+vs*vor(2)];
p.pln_c = line('parent',mritoolhandles.axc,'xdata',ox,'ydata',oy,'LineWidth',2,'Color',col);
set(p.pl_c,'ButtonDownFcn','mri_read_tool(''cor_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
set(p.pt_c,'ButtonDownFcn','mri_read_tool(''cor_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
set(p.pln_c,'ButtonDownFcn','mri_read_tool(''cor_ButtonDownFcn'',gcbo,[],guidata(gcbo))');


% --------------------------------------------------------------------
function mainud = InitTopographyPlot(handles,Chanfname,ChannelFlag)

listud = get(handles.sourcelist,'UserData');
mainud = get(handles.sourceview_main,'UserData');

if(~exist(Chanfname,'file'))
   warndlg(sprintf('Please make sure that file %s exists and then press OK',Chanfname));
%   return;
end;

chan = load(Chanfname);
switch (upper(listud.Source{1}.DataFlag)) % switch depending on the type of data -> opeartes a selection of the corresponding subset of channels
case {'MEG','EEG'}
   validchannels = good_channel(chan.Channel,ChannelFlag,upper(listud.Source{1}.DataFlag));
case 'FUSION' 
   % Still not supported 
   return;
otherwise
   errordlg(sprintf('Data type %s is not supported in result file (use ''MEG'', ''EEG'' or ''FUSION'')',listud.Source{1}.DataFlag))
   return
end

%validchannels = find(ChannelFlag==1);
%chanloc=zeros(length(validchannels),3);
p = 1;
for i = 1:length(validchannels)
   if(~isempty(chan.Channel(validchannels(i)).Loc))
      sensloc(p,:)=chan.Channel(validchannels(i)).Loc(:,1)';
      p=p+1;
   end;
end;

% load the pretesselated sphere, must be in the 
%\Toolbox directory
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

center = [0 0 0]; % default head center location
nmes = size(sensloc,1);
position = sensloc;
[teta,phi,R] = cart2sph(sensloc(:,1)-center(1),sensloc(:,2)-center(2),sensloc(:,3)-center(3));
angles = [teta,phi];

teta = angles(:,1);
phi = angles(:,2);
R = 1;

phimin = min(phi);
phimax = max(phi);
tetamin = min(teta);
tetamax = max(teta);
[x y z] = sph2cart(teta,phi,R*ones(size(phi)));
[xt yt zt] = sph2cart(teta,phi,R*1.05*ones(size(phi)));
N = 19;
phi = (phimin:(pi/2 - phimin)/N:pi/2)'*ones(1,N+1);
teta= (0: 2*pi/N : 2*pi )'*ones(1,N+1);

xs = cos(teta').*cos(phi);
ys = sin(teta').*cos(phi);
zs = sin(phi);

mainud.InterpChanPos = {xs, ys, zs};
set(handles.indeptopo,'NextPlot','add');
for i=1:nmes
   plot3(xt(i),yt(i),zt(i),'o','markerfacecolor',[.2 1 .2],'markersize',3,'Tag','sensor','Parent',handles.indeptopo);
end
%set(handles.indeptopo,'NextPlot','replace');

%%%%%%%%%%%%%%%%%%%%%%%%

mainud.toposurf = surf(xs,ys,zs,'Parent',handles.indeptopo,'visible', 'off','edgecolor','none');
set(handles.indeptopo,'Visible','off')
axes(handles.indeptopo); axis equal; view(0,-90);

%%%%% Colormap
C = [flipud(fliplr(hot(128)));hot(128)];

mainud.ChanFileName = Chanfname;
mainud.OrigChanPos = [x(:) y(:) z(:)];
mainud.ColorMap = C;
mainud.XT = xt;
mainud.YT = yt;
mainud.ZT = zt;
mainud.XS = xs;
mainud.YS = ys;
mainud.ZS = zs;

set(handles.sourceview_main,'UserData',mainud);


% --------------------------------------------------------------------
function varargout = hidesource_Callback(h, eventdata, handles, varargin)

hlist = handles.sourcelist;
num = get(hlist,'Value');
listud = get(hlist,'UserData');
if(isempty(listud)) return; end;
if(isempty(listud.Source{num})) return; end;
set(listud.Source{num}.pthandle,'visible','off');
set(hlist,'UserData',listud);





% --------------------------------------------------------------------
function varargout = hideall_Callback(h, eventdata, handles, varargin)

if(strcmp(get(h,'checked'),'off'))
   set(h,'checked','on');
   hlist = handles.sourcelist;
   listud = get(hlist,'UserData');
   if(isempty(listud)) return; end;
   if(isempty(listud.Source)) return; end;
   for num = 1:length(listud.Source)
      set(listud.Source{num}.pthandle,'visible','off');
   end;
   set(hlist,'UserData',listud);
else
   set(h,'checked','off');
   hlist = handles.sourcelist;
   listud = get(hlist,'UserData');
   if(isempty(listud)) return; end;
   if(isempty(listud.Source)) return; end;
   for num = 1:length(listud.Source)
      set(listud.Source{num}.pthandle,'visible','on');
   end;
   set(hlist,'UserData',listud);
end;





% --------------------------------------------------------------------
function varargout = deleteall_Callback(h, eventdata, handles, varargin)

listud = get(handles.sourcelist,'UserData');
if(isempty(listud))
    return;
end;

if(~isempty(listud.Source))
   for num = 1:length(listud.Source)
      try 
         %              set(listud.Source{num}.pthandle,'Visible','off');
         for k = 1:length(listud.Source{num}.pthandle)
            delete(listud.Source{num}.pthandle(k))
         end;
      catch
      end;
   end;
   listud.Source={};
   set(handles.sourcelist,'Value',1,'String',{});
   set(handles.sourcelist,'Userdata',listud);
   axes(handles.indeptopo); cla;
   axes(handles.sourcetimeseries); cla;
   mainud = get(handles.sourceview_main,'UserData');
   mainud = [];
   set(handles.sourceview_main,'UserData',mainud);
end;
set(handles.sourcelist,'UserData',listud);





% --------------------------------------------------------------------
function varargout = showall_Callback(h, eventdata, handles, varargin)

hlist = handles.sourcelist;
listud = get(hlist,'UserData');
if(isempty(listud)) return; end;
if(isempty(listud.Source)) return; end;
for num = 1:length(listud.Source)
   set(listud.Source{num}.pthandle,'visible','on');
end;
set(handles.hideall,'checked','off');



% --------------------------------------------------------------------
function varargout = Quit_Callback(h, eventdata, handles, varargin)

mainud = get(handles.sourceview_main,'UserData');
try
 mritoolhandles = guidata(getappdata(handles.sourceview_main,'mri_fig'));
 close(mritoolhandles.mrireadtool_main)
 if(isfield(mainud,'multitopofigure'))
     close(mainud.multitopofigure);
 end;
catch
end;
close(handles.sourceview_main);





% --------------------------------------------------------------------
function varargout = showsource_Callback(h, eventdata, handles, varargin)

hlist = handles.sourcelist;
num = get(hlist,'Value');
listud = get(hlist,'UserData');
if(isempty(listud)) return; end;
if(isempty(listud.Source{num})) return; end;
set(listud.Source{num}.pthandle,'visible','on');
set(hlist,'UserData',listud);





% --------------------------------------------------------------------
function varargout = tools_Callback(h, eventdata, handles, varargin)




% --------------------------------------------------------------------
function varargout = rot3d_Callback(h, eventdata, handles, varargin)

if(strcmp(get(h,'checked'),'off'))
   rotate3d on;
   axes(handles.indeptopo);
   set(h,'checked','ON');
else
   rotate3d off;
   axes(handles.indeptopo);
   set(h,'checked','OFF');
end;



% --------------------------------------------------------------------
function varargout = sourcelist_ButtondownFcn(h, eventdata, handles, varargin)

% --------------------------------------------------------------------
function varargout = indeptopo_ButtondownFcn(h, eventdata, handles, varargin)
% Stub for ButtondownFcn of the axes handles.indeptopo.



% --------------------------------------------------------------------
function varargout = timecoursemenu_Callback(h, eventdata, handles, varargin)




% --------------------------------------------------------------------
function varargout = addon_Callback(h, eventdata, handles, varargin)

if(strcmp(get(h,'Checked'),'off')==1)
    set(h,'Checked','on');
    set(handles.sourcetimeseries,'NextPlot','Add');
else
    set(h,'Checked','off');
    set(handles.sourcetimeseries,'NextPlot','Replace');
end;
    

% --------------------------------------------------------------------
function varargout = ShowAllTopos_Callback(h, eventdata, handles, varargin)

ch = get(handles.sourcetimeseries,'Children');
Lch = length(ch);
if(Lch>1)
   mainud = get(handles.sourceview_main,'UserData');
   listud = get(handles.sourcelist,'UserData');
   
   mainud.multitopofigure = figure; % open a new figure
   
   % pretty up the new figure
   set(mainud.multitopofigure,'visible','off');
   bst_color_scheme(mainud.multitopofigure);
   setappdata(mainud.multitopofigure,'TileType','T');
   bst_layout('align',mainud.multitopofigure,1,1,1);
   set(mainud.multitopofigure, 'Name', 'Source Topographies');
   set(mainud.multitopofigure,'visible','on');
   figure(mainud.multitopofigure); % make current figure

   
   n=2;
   m = ceil(Lch/n);
   xs = get(mainud.toposurf,'XData');
   ys = get(mainud.toposurf,'YData');
   zs = get(mainud.toposurf,'ZData');
   for k = 1:Lch
      subp(k) = subplot(m,n,k);
      topo(k) = surf(xs,ys,zs,'edgecolor','none');
      axis off;
      axis equal;
      view(0,90);
      XI = mainud.InterpChanPos;
      X0 = mainud.OrigChanPos;
      v = listud.Source{k}.IndepTopo;
      Vp = griddata(X0(:,1),X0(:,2),v,XI{1},XI{2},'invdist');
      set(topo(k),'CData',Vp,'Visible','on','facecolor','interp');
      set(get(topo(k),'Parent'),'Ydir','normal');
      axis square
      set(subp(k),'Visible','off','View',[180 90]);
      set(get(subp(k),'parent'),'Colormap',mainud.ColorMap);
      title(sprintf('Source %s',listud.Source{k}.ptname));
   end;
   set(handles.sourceview_main,'UserData',mainud);
else
   return;
end;


% --------------------------------------------------------------------
function LocSetTight(ax);
%called in response to axis tight
%we can assume that ax is length=1

ch = allchild(ax);
%allchild is important because it finds things with handlevisibility "off",
%which is very important in a user object world

limits = [inf -inf inf -inf inf -inf];
hasdepth = 0;

for i=1:length(ch),
    switch get(ch(i),'type')
    case {'patch','surface','line'}
        data{i} = get(ch(i),{'xdata','ydata','zdata'});
    case 'image'
        data{i} = get(ch(i),{'xdata','ydata','cdata'});
        
        % Offset data limits by half a pixel
        siz = size(data{i}{3});
        data{i}{1} = [min(data{i}{1}) max(data{i}{1})];
        data{i}{2} = [min(data{i}{2}) max(data{i}{2})];
        dx = diff(data{i}{1}); dy = diff(data{i}{2});
        if isequal(siz(2),1)
            % single x value, set range +/- half that value
            data{i}{1} = data{i}{1} + [-1 1]/2;
        else
            data{i}{1} = data{i}{1} + [-dx dx]/(siz(2)-1)/2;
        end
        if isequal(siz(1),1)
            % single y value, set range +/- half that value
            data{i}{2} = data{i}{2} + [-1 1]/2;
        else
            data{i}{2} = data{i}{2} + [-dy dy]/(siz(1)-1)/2;
        end
        data{i}{3} = [];
    case 'text'
        % Ignore text like the axes object does.  This
        % handles filtering out the xlabel, ylabel, zlabel, and
        % title objects as well.
        data{i} = cell(1,3);
    otherwise
        data{i} = cell(1,3);
    end
    
    if ~isempty(data{i}{1})
        limits(1:2) = [min(limits(1),min(data{i}{1}(:))) ...
                max(limits(2),max(data{i}{1}(:)))];
    end
    if ~isempty(data{i}{2})
        limits(3:4) = [min(limits(3),min(data{i}{2}(:))) ...
                max(limits(4),max(data{i}{2}(:)))];
    end
    if ~isempty(data{i}{3}),
        limits(5:6) = [min(limits(5),min(data{i}{3}(:))) ...
                max(limits(6),max(data{i}{3}(:)))];
        
        if limits(5)~=limits(6)
            hasdepth = 1;
        end
    end
end

% Protect against axis limit values being the same
ndx = find(diff(limits)==0 & [1 0 1 0 1]);

% handle log scales
logscales = [0 0 0 0 0 0];
logscales(1) = strcmp(get(ax,'xscale'),'log');
logscales(3) = strcmp(get(ax,'yscale'),'log');
if hasdepth
    logscales(5) = strcmp(get(ax,'zscale'),'log');
end

if ~isempty(ndx)
    if any(logscales(ndx))
        for i = 1:length(ndx)
            j = ndx(i);
            if logscales(i)
                % handle semilogx(1,1:10)
                % Scale upper 10 (log)
                % Scale lower limit by .1 (log)
                limits(j+1) = limits(j) * 10;
                limits(j) = limits(j) / 10;
            else
                % handle semilogy(1:10,1)
                % Bump upper and lower limits by 1
                limits(j+1) = limits(j)+1;
                limits(j) = limits(j)-1;
            end
        end
    else
        % Bump upper and lower limits by 1
        % handle semilogx(1:10,1)
        % handle semilogy(1,1:10)
        % handle plot(1,1:10), plot(1,1), plot(1:10,1)
        limits(ndx+1) = limits(ndx)+1;
        limits(ndx) = limits(ndx)-1;
    end
end

if all(isfinite(limits(1:4))),
    set(ax,...
        'xlim',limits(1:2),...
        'ylim',limits(3:4))
end

if hasdepth
    set(ax,'zlim',limits(5:6))
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
