function varargout = phantom_channel_assignment(varargin)
%PHANTOM_CHANNEL_ASSIGNMENT - Application M-file for phantom_channel_assignment.fig
% function varargout = phantom_channel_assignment(varargin)
%    FIG = PHANTOM_CHANNEL_ASSIGNMENT launch phantom_channel_assignment GUI.
%    PHANTOM_CHANNEL_ASSIGNMENT('callback_name', ...) invoke the named callback.
% This tool (window) returns the assignment of an EEG channel structure
% (from any subject)to the phantom channel structure
%
% Use as:
%   [assigned_locs] = phantom_channel_assignment(MontrealChannels,MontrealLandmarks,Channel,Landmark);
%
%   input:
%   MontrealChannels:   .Loc:  3xn array of channel locations
%                       .Name: 1xn structure of strings containing the names of the channels
%   MontrealLandmarks:  .Loc:  3xn array of landmark locations
%                       .Name: 1xn structure of strings containing the names of the landmarks   
%   Channel:            The standard Channel structure of Brainstorm, belonging to the subject of interest
%   Landmark:           The standard Landmark of Brainstorm, belonging to the subject of interest
%
%   output:
%   assigned_locs:      .phantom: 3xm array of doubles, the channel locations of the phantom that 
%                                 have common correspondance with the
%                                 subject (begining with Nasion, PAL, PAR, ...
%                       .subject: 3xm array of doubles, the channel locations of the subject that 
%                                 have common correspondance with the subject
%
% See also TESS_ALIGN_TOOL.m

%<autobegin> ---------------------- 02-Nov-2004 16:16:28 -----------------------
% --------- Automatically Generated Comments Block Using AUTO_COMMENTS ---------
%
% CATEGORY: Database Management
%
% Alphabetical list of external functions (non-Matlab):
%   publictoolbox\othertools\select3d.m
%   toolbox\bestfitsph.m
%   toolbox\bst_color_scheme.m
%   toolbox\bst_layout.m
%   toolbox\bst_message_window.m
%   toolbox\makeuswait.m
%   toolbox\norlig.m
%   toolbox\rownorm.m
%
% Subfunctions in this file, in order of occurrence in file:
%   varargout = initialize_gui(h,eventdata,handles,varargin);
%   Montreal_listbox_Callback(hObject, eventdata, handles)
%   Subject_listbox_Callback(hObject, eventdata, handles)
%   Autoassign_Callback(hObject, eventdata, handles)
%   Autoassign_dist_Callback(hObject, eventdata, handles)
%   Assign_Callback(hObject, eventdata, handles)
%   Deassign_Callback(hObject, eventdata, handles)
%   ViewMontrealCap_Callback(hObject, eventdata, handles)
%   ViewSubjectCap_Callback(hObject, eventdata, handles)
%   varargout = channelClick_Callback
%   varargout = Done_Callback(h, eventdata, handles, varargin)
%   varargout = Quit_Callback(h, eventdata, handles, varargin)
%
% Application data and their calls in this file:
%   'TileType'
%   'data'
%   'phantom_channel_assignment_handles'
%   
%   setappdata(0,'phantom_channel_assignment_handles',handles);
%   setappdata(fig,'TileType','T')
%   setappdata(fig,'data',data);
%   
%   data = getappdata(fig,'data');
%   handles = getappdata(0,'phantom_channel_assignment_handles');
%
% 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 phantom_channel_assignment.fig
%   uicontrol:checkbox:ViewMontrealCap "View Cap" uses Callback for <automatic>
%   uicontrol:checkbox:ViewSubjectCap "View Cap" uses Callback for <automatic>
%   uicontrol:listbox:Montreal_listbox "populating list..." uses Callback for <automatic>
%   uicontrol:listbox:Subject_listbox "populating list..." uses Callback for <automatic>
%   uicontrol:pushbutton:Assign "Assign" uses Callback for <automatic>
%   uicontrol:pushbutton:Autoassign "AutoAssign (Tag)" uses Callback for <automatic>
%   uicontrol:pushbutton:Autoassign_dist "AutoAssign (Dist)" uses Callback for <automatic>
%   uicontrol:pushbutton:Deassign "Deassign" uses Callback for <automatic>
%   uicontrol:pushbutton:Done "Go" uses Callback for <automatic>
%   uicontrol:pushbutton:Quit "Quit" uses Callback for <automatic>
%
% At Check-in: $Author: Mosher $  $Revision: 4 $  $Date: 11/02/04 2:38p $
%
% This software is part of BrainStorm Toolbox Version 2.0 (Alpha) 02-Nov-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> ------------------------ 02-Nov-2004 16:16:28 -----------------------

% Last Modified by GUIDE v2.5 13-Oct-2004 12:07:55


% /---Script Author--------------------------------------\
% |                                                      |
% | *** Dimitrios Pantazis, Ph.D. student                |
% | University of Southern California                    |
% |                                                      | 
% \------------------------------------------------------/
%  
% Date of creation: October 2004

% ----------------------------- Script History ---------------------------------
% 03-Oct-2004 DP  Creation
% 11-Oct-2004 JCM Commenting header
% 13-Oct-2004 DP  Visualize caps, fix minor bugs
% ----------------------------- Script History ---------------------------------


% All communication between functions is done using the 'data' structure 
%
%data = 
%    MontrealName: {1xnPhantomPoints cell}
%     MontrealLoc: [3xnPhantomPoints double]
%     SubjectName: {1xnSubjectPoints cell}
%      SubjectLoc: [3xnSubjectPoints double]
%     assignments: [1xnPhantomPoints double]
%      plotHandle: Handle for the plot figure
%   hannelHandles: Handle for channels
%     lineHandles: [1xnPhantomPoints double], stores handles for lines


if ~ischar(varargin{1})  % LAUNCH GUI

    warning off; %supress warning that window was created using matlab 7 (6.5 compatible)
    fig = openfig(mfilename,'reuse');
    warning on;
    
    bst_color_scheme(fig);
    setappdata(fig,'TileType','T')
    bst_layout('align',fig,2,2,4)
    set(fig,'visible','on'); % .fig saved as invisible until ready
        
	% Generate a structure of handles to pass to callbacks, and store it. 
	handles = guihandles(fig);
	guidata(fig, handles);
    
    %save arguments in data structure
    data.MontrealChannels = varargin{1};
    data.MontrealLandmarks = varargin{2};
    data.Channel = varargin{3};
    data.Landmark = varargin{4};

    %MontrealName & MontrealLoc will be the first listbox
    data.MontrealName = data.MontrealLandmarks.Name;
    data.MontrealName = [data.MontrealName data.MontrealChannels.Name];
    data.MontrealLoc = data.MontrealLandmarks.Loc;
    data.MontrealLoc = [data.MontrealLoc data.MontrealChannels.Loc];
    
    %SubjectName & SubjectLoc will be the second listbox
    data.SubjectName = data.Landmark.Name;
    data.SubjectName = [data.SubjectName {data.Channel.Name}];
    data.SubjectLoc = data.Landmark.Loc;
    data.SubjectLoc = [data.SubjectLoc data.Channel.Loc];
    
    %clear useless structures
    data = rmfield(data,'MontrealChannels');
    data = rmfield(data,'MontrealLandmarks');
    data = rmfield(data,'Channel');
    data = rmfield(data,'Landmark');
    
    %null assignments
    data.assignments = zeros(1,size(data.MontrealName,2));
    
    %save application data
    setappdata(fig,'data',data);

    %initialize
    initialize_gui(fig,[],handles,varargin{:});
    
    data = getappdata(fig,'data');
    set(data.plotHandle,'pointer','crosshair');
  	% Wait for callbacks to run and window to be dismissed:
	uiwait(fig);

    data = getappdata(fig,'data');
     
    %delete additional channels and lines
    phantom_points = size(data.MontrealName,2);
    for i = 1:phantom_points
        if ishandle(data.lineHandles(i))
            delete(data.lineHandles(i))
        end
    end
    if(ishandle(data.channelHandles));
        delete(data.channelHandles);
    end
    %delete marker if exist
    if(ishandle(data.channelMarker))
        delete(data.channelMarker)
    end
    
    %deactivate pointclicking on plotWindow
    if ishandle(data.plotHandle)
        set(data.plotHandle,'windowbuttondownfcn','');
        set(data.plotHandle,'pointer','arrow');
    end
    %delete tool handles on root window
    rmappdata(0,'phantom_channel_assignment_handles');
    %restore pointer
    
    if isfield(data,'subjectcap')
        if ishandle(data.subjectcap)
            delete(data.subjectcap);
        end
    end
    if isfield(data,'montrealcap')
        if ishandle(data.montrealcap)
            delete(data.montrealcap);
        end
    end
    
    
    if(~ishandle(fig)) %if figure is closed already
         assigned_locs.phantom = [];
         assigned_locs.subject = [];
         varargout{1} = assigned_locs;
         varargout{2} = {[]};
         return
    end
        
    varargout{1} = data.assigned_locs;
    close(fig);
    
    
    
    
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 --------------------------
% ---------------------------------------------------------------
function varargout = initialize_gui(h,eventdata,handles,varargin);
% This function initializes GUI controls, as well as two structures, 'data' and 'changed'

makeuswait('start')
fig = handles.phantom_channel_assignment; % make sure we have the handle
handles = guidata(fig);
data = getappdata(fig,'data');

%populate lists
set(handles.Montreal_listbox,'string',data.MontrealName)
set(handles.Subject_listbox,'string',data.SubjectName)


%locate plot figure (has the name: tessellations)
name = 'Tessellations';
hw = get(0,'children');		% all open windows
hw = sort(hw);			% in increasing window order
for i = 1:length(hw),
  s = get(hw(i),'Name');
  if(strcmp(deblank(s),deblank(name))),
    data.plotHandle = hw(i);
  end
end


%plot phantom channels
figure(data.plotHandle)
if isfield(data,'plotHandle')%if figure exists
    data.channelHandles = plot3(data.MontrealLoc(1,:),data.MontrealLoc(2,:),data.MontrealLoc(3,:),'ko');
    set(data.channelHandles,'markerfacecolor','red');
    axis equal
    axis off
end

%initialize data.lineHandles
data.lineHandles = -1*ones(1,size(data.MontrealLoc,2));

%activate pointclicking on plotWindow
set(data.plotHandle,'windowbuttondownfcn','phantom_channel_assignment(''channelClick_Callback'')');
%save tool handles on root window, so they can be accessed by channelClick fn
setappdata(0,'phantom_channel_assignment_handles',handles);
%define channelMarker
data.channelMarker = line('marker','o','markerfacecolor','k','linewidth',2,'markersize',8,'erasemode','xor','visible','off');
% channelMarker = data.channelMarker;
% setappdata(0,'channelMarker',channelMarker);


setappdata(fig,'data',data);

makeuswait('stop')



  

% --- Executes on selection change in Montreal_listbox.
function Montreal_listbox_Callback(hObject, eventdata, handles)
% hObject    handle to Montreal_listbox (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns Montreal_listbox contents as cell array
%        contents{get(hObject,'Value')} returns selected item from Montreal_listbox


%get handles
fig = handles.phantom_channel_assignment; % make sure we have the handle
handles = guidata(fig);
data = getappdata(fig,'data');

%get selected Montreal channel
vi = get(handles.Montreal_listbox,'value');

p = data.MontrealLoc(:,vi);

%show marker
set(data.channelMarker,'visible','on','xdata',p(1),'ydata',p(2),'zdata',p(3));




% --- Executes on selection change in Subject_listbox.
function Subject_listbox_Callback(hObject, eventdata, handles)
% hObject    handle to Subject_listbox (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns Subject_listbox contents as cell array
%        contents{get(hObject,'Value')} returns selected item from Subject_listbox

%get handles
fig = handles.phantom_channel_assignment; % make sure we have the handle
handles = guidata(fig);
data = getappdata(fig,'data');

%get selected Montreal channel
vj = get(handles.Subject_listbox,'value');

p = data.SubjectLoc(:,vj);

%show marker
set(data.channelMarker,'visible','on','xdata',p(1),'ydata',p(2),'zdata',p(3));



% --- Executes on button press in Autoassign.
function Autoassign_Callback(hObject, eventdata, handles)
% hObject    handle to Autoassign (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%get handles
fig = handles.phantom_channel_assignment; % make sure we have the handle
handles = guidata(fig);
data = getappdata(fig,'data');

%deassign everything
data.assignments = zeros(size(data.assignments));

%number of points
phantom_points = size(data.MontrealName,2);
subject_points = size(data.SubjectName,2);

%make assignments
for i = 1:phantom_points %for all phantom points
    for j = 1:subject_points %for all subject points
        detect = strfind(lower(data.SubjectName{j}),lower(data.MontrealName{i}));
        %if detected, make assignment
        if ~isempty(detect)
            data.assignments(i) = j;
        end
    end
end

%special assignments
for j = 1:subject_points
     detect = strfind(lower(data.SubjectName{j}),'nas');
     if ~isempty(detect) %nasion
         data.assignments(1) = j;
     end
          detect = strfind(lower(data.SubjectName{j}),'par');
     if ~isempty(detect) %right preauricular
         data.assignments(3) = j;
     end
     detect = strfind(lower(data.SubjectName{j}),'pal');
     if ~isempty(detect) %left preauricular
         data.assignments(2) = j;
     end

end


%display assignments
figure(data.plotHandle)
for i = 1:phantom_points
    displayStr{i} = data.MontrealName{i};
    if data.assignments(i)~=0 %if assigned
        displayStr{i} = [displayStr{i} ' --> ' data.SubjectName{data.assignments(i)}];
    end
end
set(handles.Montreal_listbox,'string',displayStr)


%plot lines between assigned channels
for i = 1:phantom_points
    %if there is already a line, delete it
    if ishandle(data.lineHandles(i))
        delete(data.lineHandles(i))
    end
    if data.assignments(i)~=0 %if assigned
        X = [data.MontrealLoc(1,i) data.SubjectLoc(1,data.assignments(i))];
        Y = [data.MontrealLoc(2,i) data.SubjectLoc(2,data.assignments(i))];
        Z = [data.MontrealLoc(3,i) data.SubjectLoc(3,data.assignments(i))];
        data.lineHandles(i) = line(X,Y,Z);
        set(data.lineHandles(i),'color','black','linewidth',2)
    end
end

setappdata(fig,'data',data);    



% --- Executes on button press in Autoassign_dist.
function Autoassign_dist_Callback(hObject, eventdata, handles)
% hObject    handle to Autoassign_dist (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


%get handles
fig = handles.phantom_channel_assignment; % make sure we have the handle
handles = guidata(fig);
data = getappdata(fig,'data');

%deassign everything
data.assignments = zeros(size(data.assignments));

%number of points
phantom_points = size(data.MontrealName,2);
subject_points = size(data.SubjectName,2);

%make assignments
montrloc = data.MontrealLoc';
subjloc = data.SubjectLoc';
for i = 1:phantom_points %for all phantom points
    
    [dummy,j] = min(rownorm(subjloc - ones(size(subjloc,1),1)*montrloc(i,:)));
    data.assignments(i) = j; %assign point
    subjloc(j,:) = [inf inf inf]; %send point to infinity, so it will not be assigned again
                                  %unless subject has less channels that phantom  
end


%display assignments
figure(data.plotHandle)
for i = 1:phantom_points
    displayStr{i} = data.MontrealName{i};
    if data.assignments(i)~=0 %if assigned
        displayStr{i} = [displayStr{i} ' --> ' data.SubjectName{data.assignments(i)}];
    end
end
set(handles.Montreal_listbox,'string',displayStr)


%plot lines between assigned channels
for i = 1:phantom_points
    %if there is already a line, delete it
    if ishandle(data.lineHandles(i))
        delete(data.lineHandles(i))
    end
    if data.assignments(i)~=0 %if assigned
        X = [data.MontrealLoc(1,i) data.SubjectLoc(1,data.assignments(i))];
        Y = [data.MontrealLoc(2,i) data.SubjectLoc(2,data.assignments(i))];
        Z = [data.MontrealLoc(3,i) data.SubjectLoc(3,data.assignments(i))];
        data.lineHandles(i) = line(X,Y,Z);
        set(data.lineHandles(i),'color','black','linewidth',2)
    end
end

setappdata(fig,'data',data);    








% --- Executes on button press in Assign.
function Assign_Callback(hObject, eventdata, handles)
% hObject    handle to Assign (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%get handles
fig = handles.phantom_channel_assignment; % make sure we have the handle
handles = guidata(fig);
data = getappdata(fig,'data');

%make assignment
vi = get(handles.Montreal_listbox,'value');
vj = get(handles.Subject_listbox,'value');
data.assignments(vi) = vj;

%display assignments
phantom_points = size(data.MontrealName,2);
for i = 1:phantom_points
    displayStr{i} = data.MontrealName{i};
    if data.assignments(i)~=0 %if assigned
        displayStr{i} = [displayStr{i} ' --> ' data.SubjectName{data.assignments(i)}];
    end
end
set(handles.Montreal_listbox,'string',displayStr)

%display line
figure(data.plotHandle)
if ishandle(data.lineHandles(vi)) %if there is already a line, delete it
     delete(data.lineHandles(vi))
end
X = [data.MontrealLoc(1,vi) data.SubjectLoc(1,data.assignments(vi))];
Y = [data.MontrealLoc(2,vi) data.SubjectLoc(2,data.assignments(vi))];
Z = [data.MontrealLoc(3,vi) data.SubjectLoc(3,data.assignments(vi))];
data.lineHandles(vi) = line(X,Y,Z);
set(data.lineHandles(vi),'color','black','linewidth',2)

setappdata(fig,'data',data);



% --- Executes on button press in Deassign.
function Deassign_Callback(hObject, eventdata, handles)
% hObject    handle to Deassign (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%get handles
fig = handles.phantom_channel_assignment; % make sure we have the handle
handles = guidata(fig);
data = getappdata(fig,'data');

%deassign
i = get(handles.Montreal_listbox,'value');
data.assignments(i) = 0;
%remove line if exists
if ishandle(data.lineHandles(i)) %if there is already a line, delete it
     delete(data.lineHandles(i))
end

%display assignments
phantom_points = size(data.MontrealName,2);
for i = 1:phantom_points
    displayStr{i} = data.MontrealName{i};
    if data.assignments(i)~=0 %if assigned
        displayStr{i} = [displayStr{i} ' --> ' data.SubjectName{data.assignments(i)}];
    end
end
set(handles.Montreal_listbox,'string',displayStr)

setappdata(fig,'data',data);   



% --- Executes on button press in ViewMontrealCap.
function ViewMontrealCap_Callback(hObject, eventdata, handles)
% hObject    handle to ViewMontrealCap (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of ViewMontrealCap

%get handles
fig = handles.phantom_channel_assignment; % make sure we have the handle
handles = guidata(fig);
data = getappdata(fig,'data');

viewmode = get(handles.ViewMontrealCap,'value');

if viewmode %if view selected
    
    %get locations
    chanlocs = data.MontrealLoc';

    %create patch
    chanlocs(:,3)=chanlocs(:,3)-max(chanlocs(:,3));
    [TH,PHI,R]=cart2sph(chanlocs(:,1),chanlocs(:,2),chanlocs(:,3));
    %PHI2=zeros(size(PHI));
    R2=R./cos(PHI).^.2;
    [Y,X]=pol2cart(TH,R2);
    %Y et X sont les coordonnées projetees dans le plan 'tangent superieur' pour chaque capteur
    bord = convhull(Y,X);
    ncapt = size(chanlocs,1);
    [center,R] = bestfitsph(chanlocs);
    coordC = chanlocs-(ones(ncapt,1)*center');
    tri = convhulln(coordC./(norlig(coordC)'*ones(1,3)));
    keep = find(~(ismember(tri(:,1),bord) & ismember(tri(:,2),bord)& ismember(tri(:,3),bord)));
    tri = tri(keep,:);
    capcolor = [.4 .4 .4];
    
    %plot patch
    hf = figure(data.plotHandle);
    M = ones(size(chanlocs,1),1)*capcolor;
    data.montrealcap = trisurf(tri,data.MontrealLoc(1,:),data.MontrealLoc(2,:),data.MontrealLoc(3,:),'facevertexcdata',M);
    set(data.montrealcap,'edgecolor','none','facecolor','interp')
    material dull
    lighting phong
    setappdata(fig,'data',data);

else %delete cap 
    delete(data.montrealcap); 
end


% --- Executes on button press in ViewSubjectCap.
function ViewSubjectCap_Callback(hObject, eventdata, handles)
% hObject    handle to ViewSubjectCap (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of ViewSubjectCap


%get handles
fig = handles.phantom_channel_assignment; % make sure we have the handle
handles = guidata(fig);
data = getappdata(fig,'data');

viewmode = get(handles.ViewSubjectCap,'value');

if viewmode %if view selected
    
    %get locations
    chanlocs = data.SubjectLoc';

    %create patch
    chanlocs(:,3)=chanlocs(:,3)-max(chanlocs(:,3));
    [TH,PHI,R]=cart2sph(chanlocs(:,1),chanlocs(:,2),chanlocs(:,3));
    %PHI2=zeros(size(PHI));
    R2=R./cos(PHI).^.2;
    [Y,X]=pol2cart(TH,R2);
    %Y et X sont les coordonnées projetees dans le plan 'tangent superieur' pour chaque capteur
    bord = convhull(Y,X);
    ncapt = size(chanlocs,1);
    [center,R] = bestfitsph(chanlocs);
    coordC = chanlocs-(ones(ncapt,1)*center');
    tri = convhulln(coordC./(norlig(coordC)'*ones(1,3)));
    keep = find(~(ismember(tri(:,1),bord) & ismember(tri(:,2),bord)& ismember(tri(:,3),bord)));
    tri = tri(keep,:);
    capcolor = [.7 .7 .7];
    
    %plot patch
    hf = figure(data.plotHandle);
    M = ones(size(chanlocs,1),1)*capcolor;
    data.subjectcap = trisurf(tri,data.SubjectLoc(1,:),data.SubjectLoc(2,:),data.SubjectLoc(3,:),'facevertexcdata',M);
    set(data.subjectcap,'edgecolor','none','facecolor','interp')
    material dull
    lighting phong
    setappdata(fig,'data',data);

else %delete cap 
    delete(data.subjectcap); 
end











function varargout = channelClick_Callback

handles = getappdata(0,'phantom_channel_assignment_handles'); %access tesselation tool
fig = handles.phantom_channel_assignment; % make sure we have the handle
data = getappdata(fig,'data');

%number of points
phantom_points = size(data.MontrealName,2);
subject_points = size(data.SubjectName,2);

%get coordinates of point
figure(data.plotHandle)
[p v vi face facei] = select3d;
if(isempty(p) & isempty(v)) %if user did not click on a tesselation
    return
end
if (isempty(p)) %if uses chooses the same point again
    p=v;
end
p = v; %select vertices and not points on cap

%show marker
set(data.channelMarker,'visible','on','xdata',p(1),'ydata',p(2),'zdata',p(3));

%change listbox selection
if size(p,1)==3
    p = p';
end
vi = find(sum(abs(data.MontrealLoc - p'*ones(1,phantom_points)))==0);
vj = find(sum(abs(data.SubjectLoc - p'*ones(1,subject_points)))==0);
if(~isempty(vi)) %if a phantom channel is selected
    set(handles.Montreal_listbox,'value',vi);
end
if(~isempty(vj)) %if a phantom channel is selected
    set(handles.Subject_listbox,'value',vj);
end




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

fig = handles.phantom_channel_assignment; % make sure we have the handle
handles = guidata(fig);
data = getappdata(fig,'data');

%ask if channels already aligned
if sum(data.assignments~=0)<5 %if less than 5 points selected
	reply = questdlg('At least 5 channels must be assigned. Choose more points?');
    if(strcmp(reply,'No'))
        bst_message_window('append','Process canceled by user because not enough channels where assigned'); 
        return
    end
    if(strcmp(reply,'Cancel'))
        bst_message_window('append','Please assign more channels'); 
        return
    end
    if(strcmp(reply,'Yes'))
        bst_message_window('append','Please assign more channels'); 
        return
    end
end

%ask if NAS,PAL,PAR not already assigned
if sum(data.assignments(1:3)~=0)<3 %if NAS/PAL/PAR
    bst_message_window('append','...');
    bst_message_window('append','Please assign Nasion, Left Preauricular, Right Preauricular'); 
    bst_message_window('append','These points are necessary to align the MR scan'); 
    return;
end

phantom_points = size(data.MontrealName,2);

%return locations of common channels (notice , NAS,PAL,PAR will be returned
%first in this order
assigned_locs.phantom = [];
assigned_locs.subject = [];
for i = 1:phantom_points
    if data.assignments(i)~=0 %if sensor assigned
        assigned_locs.phantom = [assigned_locs.phantom data.MontrealLoc(:,i)];
        assigned_locs.subject = [assigned_locs.subject data.SubjectLoc(:,data.assignments(i))];
    end
end
data.assigned_locs = assigned_locs;

setappdata(fig,'data',data);

uiresume;


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

fig = handles.phantom_channel_assignment; % make sure we have the handle
handles = guidata(fig);
data = getappdata(fig,'data');

data.assigned_locs.phantom = [];
data.assigned_locs.subject = [];
setappdata(fig,'data',data);

uiresume;



