function varargout = mri_read_tool(varargin)
%MRI_READ_TOOL - AOS Version Application M-file to read in MRI and manipulate
% function varargout = mri_read_tool(varargin)
%    FIG = MRI_READ_TOOL launch mri_read_tool GUI.
%    MRI_READ_TOOL('callback_name', ...) invoke the named callback.
%
% Particularly useful with results_visulation to automatically load
%  results. 
% See also RESULTS_VISULIZATION 

%<autobegin> ---------------------- 26-May-2004 11:31:10 -----------------------
% --------- 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\mri_scan_params.m
%   toolbox\pcs_params.m
%   toolbox\transform.m
%
% Subfunctions in this file, in order of occurrence in file:
%   varargout = ShowAll(handles, SlicePos)
%   varargout = ShowAxial(handles, SlicePos)
%   varargout = ShowSagital(handles, SlicePos)
%   varargout = ShowCoronal(handles, SlicePos)
%   mri =  Convert2uint8(mri)
%   Header = FillCTFHeader(Header,file)
%   varargout = savemrscans_Callback(h, eventdata, handles, varargin)
%   varargout = savemrscans_Bsuite_Callback(h, eventdata, handles, varargin)
%   varargout = readmrscans_Callback(h, eventdata, handles, varargin)
%   varargout = readctf_Callback(h, eventdata, handles, varargin)
%   varargout = rawformat_Callback(h, eventdata, handles, varargin)
%   varargout = readbs_Callback(h, eventdata, handles, varargin)
%   varargout = slider1_Callback(h, eventdata, handles, varargin)
%   varargout = slider2_Callback(h, eventdata, handles, varargin)
%   varargout = slider3_Callback(h, eventdata, handles, varargin)
%   varargout = slider4_Callback(h, eventdata, handles, varargin)
%   varargout = slider5_Callback(h, eventdata, handles, varargin)
%   varargout = slider6_Callback(h, eventdata, handles, varargin)
%   varargout = addpoint_Callback(h, eventdata, handles, varargin)
%   varargout = listpoints_Callback(h, eventdata, handles, varargin)
%   varargout = listpoints_ButtonDownFcn(h, eventdata, handles, varargin)
%   InstallGotoPointMode(handles)
%   varargout = sag_ButtonDownFcn(h, eventdata, handles, varargin)
%   varargout = ax_ButtonDownFcn(h, eventdata, handles, varargin)
%   varargout = cor_ButtonDownFcn(h, eventdata, handles, varargin)
%   varargout = ShowCrosshairs_Callback(h, eventdata, handles, varargin)
%   varargout = coords_Callback(h, eventdata, handles, varargin)
%   varargout = deletepoints_Callback(h, eventdata, handles, varargin)
%   varargout = deleteall_Callback(h, eventdata, handles, varargin)
%   varargout = deletecurrent_Callback(h, eventdata, handles, varargin)
%   varargout = hidecurrent_Callback(h, eventdata, handles, varargin)
%   varargout = hideall_Callback(h, eventdata, handles, varargin)
%   varargout = showall_Callback(h, eventdata, handles, varargin)
%   varargout = coord_Callback(h, eventdata, handles, varargin)
%   varargout = definepcs_Callback(h, eventdata, handles, varargin)
%   varargout = savepoints_Callback(h, eventdata, handles, varargin)
%   varargout = darken_Callback(h, eventdata, handles, varargin)
%   varargout = brighten_Callback(h, eventdata, handles, varargin)
%   varargout = Quit_Callback(h, eventdata, handles, varargin)
%   varargout = zoomtoggle_Callback(h, eventdata, handles, varargin)
%   varargout = readbsuite_Callback(h, eventdata, handles, varargin)
%   [DIM,VOX]=analyze_header_read(s)
%   analyze_header_save(s,DIM,VOX,MACHINEFORMAT)
%
% Application data and their calls in this file:
%   'TileType'
%   'mri_fig'
%   
%   setappdata(fig,'TileType','T');
%   setappdata(h_dm,'mri_fig',[]);
%   
%   h = getappdata(handles.mrireadtool_main,'resviewerhandle');
%   h_dm = getappdata(handles.mrireadtool_main,'DataManager');
%
% 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 mri_read_tool.fig
%   uicontextmenu::deletepoints "" uses Callback for <automatic>
%   uicontrol:listbox:coords "Coordinates" uses Callback for
%     mri_read_tool('coord_Callback',gcbo,[],guidata(gcbo))
%   uicontrol:listbox:listpoints "Selected Points" uses ButtonDownFcn for <automatic>
%   uicontrol:listbox:listpoints "Selected Points" uses Callback for <automatic>
%   uicontrol:pushbutton:addpoint "Add Point" uses Callback for <automatic>
%   uicontrol:pushbutton:brighten "Brighten" uses Callback for <automatic>
%   uicontrol:pushbutton:darken "Darken" uses Callback for <automatic>
%   uicontrol:pushbutton:definepcs "Define PCS" uses Callback for <automatic>
%   uicontrol:pushbutton:Hloadbsformat "Load BST Format" uses Callback for
%     mri_read_tool('readbs_Callback',gcbo,[],guidata(gcbo))
%   uicontrol:pushbutton:Quit "Quit" uses Callback for <automatic>
%   uicontrol:slider:slider1 "" uses Callback for <automatic>
%   uicontrol:slider:slider2 "" uses Callback for <automatic>
%   uicontrol:slider:slider3 "" uses Callback for <automatic>
%   uicontrol:slider:slider4 "" uses Callback for <automatic>
%   uicontrol:slider:slider5 "" uses Callback for <automatic>
%   uicontrol:slider:slider6 "" uses Callback for <automatic>
%   uicontrol:togglebutton:zoomtoggle "Zoom On" uses Callback for <automatic>
%   uimenu::deleteall "" uses Callback for <automatic>
%   uimenu::deletecurrent "" uses Callback for <automatic>
%   uimenu::hideall "" uses Callback for <automatic>
%   uimenu::hidecurrent "" uses Callback for <automatic>
%   uimenu::print_preview "" uses Callback for printpreview(gcbf)
%   uimenu::rawformat "" uses Callback for <automatic>
%   uimenu::readbsuite "" uses Callback for <automatic>
%   uimenu::readctf "" uses Callback for <automatic>
%   uimenu::readmrscans "" uses Callback for <automatic>
%   uimenu::savemrscan_Bsuite "" uses Callback for
%     mri_read_tool('savemrscans_Bsuite_Callback',gcbo,[],guidata(gcbo))
%   uimenu::savemrscans "" uses Callback for <automatic>
%   uimenu::savepoints "" uses Callback for <automatic>
%   uimenu::showall "" uses Callback for <automatic>
%   uimenu::ShowCrosshairs "" uses Callback for <automatic>
%
% At Check-in: $Author: Mosher $  $Revision: 26 $  $Date: 5/26/04 9:59a $
%
% 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:31:10 -----------------------

% Last Modified by GUIDE v2.0 17-May-2002 15:09:09

% ------------------ History --------------------------
% April 2002 Alex Ossadtchi original version, based loosely on 
% BST 2000 MRI View tool
% JCM 16-May-2002, tweaks, formatting, adaptation into BST MMII viewing routines
%                  first is to get Results loaded directly in.
% SB  20-Nov-2002  Replaced Alex's custom call to myget_user_directory to 
%                  regular GET_USER_DIRECTORY.M
% JCM 19-May-2003  bst_layout update
% JCM 15-Nov-2003  cleanup of unused menu callbacks
% ------------------ History --------------------------

VERBOSE = 0; % mostly silent mode

if nargin == 0  % LAUNCH GUI
   fig = openfig(mfilename,'reuse');
   % 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
   
   if VERBOSE,
      bst_message_window({'Welcome to MRItool of BSTII!'...
            'Load MRI files of formats other than BSTII choose'...
            'Import/Export\Read MR Scans\(appropriate format)'...
            '------------------'});
   end
   
   % customization
   bst_color_scheme(fig);
   setappdata(fig,'TileType','T'); % tile
   bst_layout('align',fig,1,2,1);
   set(fig,'Visible','on')
   
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


% subfunctions

% ---------------------- LOCAL FUNCTIONS -----------------------------
% ---------------------------------------------------------------
function varargout = ShowAll(handles, SlicePos)

%obtain handle to the MRITool window
h = handles.mrireadtool_main;
%get Userdata structure
mri_scan = get(h,'Userdata');

if(isfield(mri_scan,'filename'))
   [ignore subjectname ext] = fileparts(mri_scan.filename);
   set(handles.TitleSubjecText,'String',[subjectname ext ' (BST)']);
else(isfield(mri_scan,'filemri'))
   [ignore subjectname ext] = fileparts(mri_scan.filemri);
   set(handles.TitleSubjecText,'String',[subjectname ext]);
end;

X1 = [0:mri_scan.pix_siz(1):(mri_scan.siz(1)-1)*mri_scan.pix_siz(1)];
X2 = [0:mri_scan.pix_siz(2):(mri_scan.siz(2)-1)*mri_scan.pix_siz(2)];
X3 = [0:mri_scan.pix_siz(3):(mri_scan.siz(3)-1)*mri_scan.pix_siz(3)];

axes(handles.axa);cla;
mri_scan.ax = imagesc(X2,X1,mri_scan.mri(:,:,SlicePos(3)),'Parent',handles.axa);    
hold on;
set(get(mri_scan.ax,'Parent'),'XDir','reverse');
set(get(mri_scan.ax,'Parent'),'YDir','normal');
axis on;
set(handles.axa, 'Color',[0 0 0]);
set(handles.axa, 'vis','on');
set(handles.mrireadtool_main,'colormap',gray)
axis square

axes(handles.axc);cla;
mri_scan.cor = imagesc(X1,X3,squeeze(mri_scan.mri(:,SlicePos(2),:))','Parent',handles.axc);
hold on;
set(get(mri_scan.cor,'Parent'),'XDir','normal');
set(get(mri_scan.cor,'Parent'),'YDir','normal');
set(handles.axc, 'Color',[0 0 0]);
set(handles.axc, 'vis','on');
axis square

axes(handles.axs);cla;
mri_scan.sag = imagesc(X2, X3, squeeze(mri_scan.mri(SlicePos(1),:,:))','Parent',handles.axs);
hold on;
set(get(mri_scan.sag,'Parent'),'XDir','reverse');
set(get(mri_scan.sag,'Parent'),'YDir','normal');
set(handles.axs, 'vis','on');
set(handles.axs, 'Color',[0 0 0]);
axis square

%initialize crosshairs

set(handles.axa,'Ticklength',[0.5 0.5],'Xcolor',[0.5 0.6 0.7],'Ycolor',[0.5 0.6 0.7],'XTick',0,'YTick',0);
set(handles.axs,'Ticklength',[0.5 0.5],'Xcolor',[0.5 0.6 0.7],'Ycolor',[0.5 0.6 0.7],'XTick',0,'YTick',0);
set(handles.axc,'Ticklength',[0.5 0.5],'Xcolor',[0.5 0.6 0.7],'Ycolor',[0.5 0.6 0.7],'XTick',0,'YTick',0);

% Reposition slider in the central position
set(handles.slider1,'Value',0.5);
set(handles.slider2,'Value',0.5);
set(handles.slider3,'Value',0.5);
set(handles.slider4,'Value',0.5);
set(handles.slider5,'Value',0.5);
set(handles.slider6,'Value',0.5);
% update Userdata
set(h,'Userdata',mri_scan);
InstallGotoPointMode(handles);



% ---------------------------------------------------------------
function varargout = ShowAxial(handles, SlicePos)

mri_scan = get(handles.mrireadtool_main,'Userdata');
set(mri_scan.ax,'cdata',mri_scan.mri(:,:,round(SlicePos)));

%mri_scan.ax = imagesc(X2(end:-1:1),X1(end:-1:1),mri_scan.mri(end:-1:1,end:-1:1,end-SlicePos(3))','Parent',handles.axa);    
%mri_scan.cor = imagesc(X3(end:-1:1),X2(end:-1:1),squeeze(mri_scan.mri(SlicePos(1),:,:))','Parent',handles.axc);
%mri_scan.sag = imagesc(X3(end:-1:1),X1(end:-1:1),squeeze(mri_scan.mri(:,end-SlicePos(2),:))','Parent',handles.axs);


x2 =  get(handles.axa,'XTick');
x1 =  get(handles.axa,'YTick');
x3 =  get(handles.axs,'YTick');
aux{1} = sprintf('X = %2.2f',x1); 
aux{2} = sprintf('Y = %2.2f',x2); 
aux{3} = sprintf('Z = %2.2f',x3); 
set(handles.coords,'Value',1,'String',aux);


% ---------------------------------------------------------------
function varargout = ShowSagital(handles, SlicePos)

mri_scan = get(handles.mrireadtool_main,'Userdata');
set(mri_scan.sag,'cdata',squeeze(mri_scan.mri(round(SlicePos),:,:))');

%set(handles.axs,'vis','on');
x2 =  get(handles.axa,'XTick');
x1 =  get(handles.axa,'YTick');
x3 =  get(handles.axs,'YTick');
aux{1} = sprintf('X = %2.2f',x1); 
aux{2} = sprintf('Y = %2.2f',x2); 
aux{3} = sprintf('Z = %2.2f',x3); 
set(handles.coords,'Value',1,'String',aux);


% ---------------------------------------------------------------
function varargout = ShowCoronal(handles, SlicePos)

mri_scan = get(handles.mrireadtool_main,'Userdata');
set(mri_scan.cor,'cdata',squeeze(mri_scan.mri(:,round(SlicePos),:))');

x2 =  get(handles.axa,'XTick');
x1 =  get(handles.axa,'YTick');
x3 =  get(handles.axs,'YTick');
aux{1} = sprintf('X = %2.2f',x1); 
aux{2} = sprintf('Y = %2.2f',x2); 
aux{3} = sprintf('Z = %2.2f',x3); 
set(handles.coords,'Value',1,'String',aux);





% ---------------------------------------------------------------
function    mri =  Convert2uint8(mri)

ngray = 256;

mri = mri(end:-1:1,:,end:-1:1);
M = double(max(mri(:))); % May be rather time consuming if limited RAM is availlable

if M > (ngray-1)    
   % Scale gray levels to 255 to save the MRI in uint8
   % Memory requirememts necessitate a slice-by-slice loop on most machines
   hw = waitbar(0,'Scaling the MRI to 256 gray levels...');
   for k = 1:size(mri,3)
      waitbar(k/size(mri,3),hw);
      tmp = double(mri(:,:,k)) ;
      mri(:,:,k) = int16(tmp * ((ngray - 1 )/M)) ;
   end
   
   mri = uint8(mri);
   delete(hw)          
   drawnow
end





% ---------------------------------------------------------------
function Header = FillCTFHeader(Header,file)

warning off;
Header.identifierString = char(fread(file,32,'char')');
warning on;
Header.imageSize = fread(file,1,'short');
Header.dataSize = fread(file,1,'short');
Header.clippingRange = fread(file,1,'short');
Header.imageOrientation= fread(file,1,'short');
Header.mmPerPixel_sagittal = fread(file,1,'float32');
Header.mmPerPixel_coronal = fread(file,1,'float32');
Header.mmPerPixel_axial = fread(file,1,'float32');

% Head Model Info
Header.HeadModel_Info.Nasion_Sag = fread(file,1,'short');
Header.HeadModel_Info.Nasion_Cor = fread(file,1,'short');
Header.HeadModel_Info.Nasion_Axi = fread(file,1,'short');
Header.HeadModel_Info.LeftEar_Sag = fread(file,1,'short');
Header.HeadModel_Info.LeftEar_Cor = fread(file,1,'short');
Header.HeadModel_Info.LeftEar_Axi = fread(file,1,'short');
Header.HeadModel_Info.RightEar_Sag = fread(file,1,'short');
Header.HeadModel_Info.RightEar_Cor = fread(file,1,'short');
Header.HeadModel_Info.RightEar_Axi = fread(file,1,'short');
Header.HeadModel_Info.defaultSphereX= fread(file,1,'float32');
Header.HeadModel_Info.defaultSphereY= fread(file,1,'float32');
Header.HeadModel_Info.defaultSphereZ= fread(file,1,'float32');
Header.HeadModel_Info.defaultSphereRadius= fread(file,1,'float32');
% Head Model Info ********************************************

% Image Info
Header.Image_Info.modality = fread(file,1,'short');
Header.Image_Info.manufacturerName = fread(file,64,'char');
Header.Image_Info.instituteName = fread(file,64,'char');
Header.Image_Info.patientID = fread(file,32,'char');
Header.Image_Info.dateAndTime = fread(file,32,'char');
Header.Image_Info.scanType = fread(file,32,'char');
Header.Image_Info.contrastAgent = fread(file,32,'char');
Header.Image_Info.imagedNucleus = fread(file,32,'char');
Header.Image_Info.Frequency = fread(file,1,'float32');
Header.Image_Info.FieldStrengh = fread(file,1,'float32');
Header.Image_Info.EchoTime = fread(file,1,'float32');
Header.Image_Info.RepetitionTime = fread(file,1,'float32');
Header.Image_Info.InversionTime = fread(file,1,'float32');
Header.Image_Info.FlipAngle = fread(file,1,'float32');
Header.Image_Info.NoExcitations = fread(file,1,'short');
Header.Image_Info.NoAcquisitions = fread(file,1,'short');
Header.Image_Info.commentString = fread(file,256,'char');
Header.Image_Info.forFutureUse = fread(file,64,'char');
% Image Info ********************************************
Header.headOrigin_sagittal = fread(file,1,'float32');
Header.headOrigin_coronal = fread(file,1,'float32');
Header.headOrigin_axial  = fread(file,1,'float32');
Header.rotate_coronal = fread(file,1,'float32');
Header.headOrigin_sagittal = fread(file,1,'float32');
Header.headOrigin_axial  = fread(file,1,'float32');
Header.orthogonalFlag = fread(file,1,'short');
Header.unused = fread(file,272,'uchar');
fseek(file,1028,-1); % Skip the whole header by padding to 1028




% ---------------------- CALLBACKS -----------------------------
% --------------------------------------------------------------------
function varargout = savemrscans_Callback(h, eventdata, handles, varargin)
% optional varargin{1} is the name of the file to save to

mri_scan = get(handles.mrireadtool_main,'Userdata');
if isempty(mri_scan)
   errordlg('Please Load a Scan First','The BrainStorm Toolbox')
   return
end
Cube = uint8(mri_scan.mri); % Convert to int8 data type 
Voxsize = mri_scan.pix_siz;
if isfield(mri_scan,'Segment')
   Segment = mri_scan.Segment;
else
   Segment = [];
end
if isfield(mri_scan,'pcs') % A PCS has been defined 
   PCS.R =inv(mri_scan.rot); % According to BrainStorm convention
   PCS.t = mri_scan.center; % According to BrainStorm convention
   PCS.Comment = mri_scan.pcs_type;
   PCS.PCSFiducial = mri_scan.PCSFiducial;
   PCS.CubeFiducial = mri_scan.CubeFiducial;
   PCS.FiducialName = mri_scan.FiducialName;
   PCS.PERM = mri_scan.PERM;
   PCS.FLP =  mri_scan.FLP;
   Comment = mri_scan.pcs_type;
else 
   PCS = [];
   Comment = 'new';
end

Current = get_user_directory;
cd(Current.SUBJECTS)

if isempty(varargin),
   [file,path] = uiputfile('subjectimage.mat','Save Anatomical Scans in...');
   if file == 0
      return
   end
else
   [path,FILENAME,EXT] = fileparts(varargin{1});
   file = [FILENAME, EXT];
end

if(isempty(findstr(file,'_subjectimage')))
   file = [file '_subjectimage.mat'];
end;
cd(path)
eval(['save ',file,' Cube Voxsize Comment Segment PCS -mat'])
mri_scan.filename = file;
set(handles.mrireadtool_main,'Userdata',mri_scan);




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

mri_scan = get(handles.mrireadtool_main,'Userdata');
if isempty(mri_scan)
   errordlg('Please Load a Scan First','The BrainStorm Toolbox')
   return
end

if(isfield(mri_scan,'FLP')&isfield(mri_scan,'PERM'))
   for d = 1:3
      if(mri_scan.FLP(d)==1)
         mri_scan.mri = flipdim(mri_scan.mri,d);
      end;
   end;
   mri_scan.mri = ipermute(mri_scan.mri,mri_scan.PERM);
end


Cube = uint8(mri_scan.mri(end:-1:1,:,end:-1:1)); % Convert to int8 data type 
if isfield(mri_scan,'Segment')
   Segment = mri_scan.Segment;
else
   Segment = [];
end

Current = get_user_directory;
cd(Current.SUBJECTS)

[file,path] = uiputfile('*.img','Save Anatomical Scans in...');
if file == 0
   return
end
cd(path)
hdrfile = [file(1:end-4) '.hdr'];
analyze_header_save(hdrfile,mri_scan.siz,mri_scan.pix_siz,'L');
fh = fopen(file,'wb');
if(fh==0)
   errordlg('Error openning file for writing')
   return
end;
fwrite(fh,Cube,'char');  
fclose(fh);



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



% --------------------------------------------------------------------
function varargout = readctf_Callback(h, eventdata, handles, varargin)
% Pretty much the same as 'READ_HEADER', even simpler though.

VERBOSE = 0;

if get(handles.littleendian_radiobutton,'value') == 1
   MACHINEFORMAT = 'l';
else
   MACHINEFORMAT = 'b';
end;
axes(handles.axc); cla;
axes(handles.axs); cla;
axes(handles.axa); cla;

clear mri_scan

Current = get_user_directory;
cd(Current.SUBJECTS)

[filebs, pathbs] = uigetfile('*.mri','Please select a CTF .mri file');
if filebs==0
   return
end
cd(pathbs); 
drawnow;    
file = fopen(filebs,'rb',MACHINEFORMAT); 
if file < 1
   errordlg(['Error when opening : ',fullfile(pathbs, filebs)]);
   return
end

listud = get(handles.listpoints,'Userdata');
if(~isempty(listud))
   listud.ptname = {};
   listud.otherfig = [];
   listud.ptcoord = [];
   listud.pthandle  = [];
   listud.ptlabels  = [];
   listud.gotopoint = 0;
   listud.seepoints = 0;
   listud.seelabels = 1;
   set(handles.listpoints,'Value',0,'String',listud.ptname);
   set(handles.listpoints,'Userdata',listud);
end;


hmsg = msgbox('Reading file...');
drawnow;    

% insert here
Header = [];
Header = FillCTFHeader(Header,file);

% Header Info  ********************************************

%Read Image
mri_scan.nslice = Header.imageSize;
mri_scan.siz =  [256 256 mri_scan.nslice];

switch(Header.dataSize)
case 1
   mri_scan.code = 'uchar';
case 2
   mri_scan.code = 'ushort';
otherwise
   errordlg('Unrecognized data format - Please check the file format');
   return
end

mri_scan.mri = int16(fread(file, prod(mri_scan.siz),mri_scan.code)); % Read the whole volume / store in a huge vector   
fclose(file);
delete(hmsg);
mri_scan.mri = reshape(mri_scan.mri,mri_scan.siz(1),mri_scan.siz(2),mri_scan.siz(3)); % reshape it into a 3-D array.
%mri_scan.mri = permute(mri_scan.mri,[3,1,2]);   

mri_scan.clippingRange = Header.clippingRange ;
mri_scan.scantype = 'Sagittal';
mri_scan.pix_siz = [Header.mmPerPixel_axial Header.mmPerPixel_coronal Header.mmPerPixel_sagittal];
mri_scan.fov = [mri_scan.siz].*mri_scan.pix_siz;
mri_scan.slice_thick = Header.mmPerPixel_sagittal;

mri_scan.readslice = 1;
mri_scan.filemri = fullfile(pathbs, filebs);  
mri_scan.header = 0;


mri_scan.mri = Convert2uint8(mri_scan.mri);

mri_scan.ptname = {};
mri_scan.otherfig = [];
mri_scan.ptcoord = [];
mri_scan.pthandle  = [];
mri_scan.ptlabels  = [];
mri_scan.gotopoint = 0;
mri_scan.seepoints = 0;
mri_scan.seelabels = 1;
set(handles.mrireadtool_main,'Userdata',mri_scan)   
SlicePos(1) = round(mri_scan.siz(1)/2); 
SlicePos(2) = round(mri_scan.siz(2)/2);
SlicePos(3) = round(mri_scan.siz(3)/2);
ShowAll(handles,SlicePos);

bst_message_window({'As the MRI volume is loaded'...
      'you need to orient it properly inside the MRI cube'...
      'and define a Patient Coordinate System'...
      'Please, specify fiducial points.'...
      'To do this, postion the crosshairs over the desired point' ...
      'and click "Add Point" button. After all 4 points specified'...
      'click "Define PCS" button'...
      '------------------'});




%----------------------------------------------end of readctf_Callback()--------------------------------%





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

if get(handles.littleendian_radiobutton,'value') == 1
   MACHINEFORMAT = 'l';
else
   MACHINEFORMAT = 'b';
end;

clear mri_scan

hprms = mri_scan_params;
hdone = findobj(hprms,'tag', 'done');
waitfor(hdone,'Enable','off');
% after parameters setup and 'Done' button is pressed we can proceed
try 
   mri_scan.header = get(findobj(hprms,'tag', 'header'),'String');
catch
   return;
end;

mri_scan.siz = str2num(get(findobj(hprms,'tag', 'image_size'),'String'));
if length(mri_scan.siz)==1
   mri_scan.siz = [mri_scan.siz,mri_scan.siz];
end
mri_scan.slice_thick = str2num(get(findobj(hprms,'tag', 'slice_thickness'),'String'));
mri_scan.fov = str2num(get(findobj(hprms,'tag', 'fov'),'String'));
mri_scan.nslice = str2num(get(findobj(hprms,'tag', 'nslice'),'String'));

SCAN_TYPE = (get(findobj(hprms,'tag', 'scan_type'),'String'));
mri_scan.scantype = strtok(char(SCAN_TYPE{get(findobj(hprms,'tag', 'scan_type'),'Value')}));

DATA_FORMAT = (get(findobj(hprms,'tag', 'data_format'),'String'));
mri_scan.code = strtok(char(DATA_FORMAT{get(findobj(hprms,'tag', 'data_format'),'Value')}));

delete(hprms);

% open file section dialog
d = dir;
str = {d.name};
[s,v] = listdlg('PromptString','Select a file:',...
   'SelectionMode','multiple',...
   'ListString',str);
if v == 0
   return
end
while length(s)==1
   cd(str{s});
   d = dir;
   str = {d.name};
   [s,v] = listdlg('PromptString','Select a file:',...
      'SelectionMode','multiple',...
      'ListString',str);
   if v==0
      return
   end
end


%check number of selected files = number of slices
mri_scan.s = s;
mri_scan.str = str;
mri_scan.nslice = length(s);
mri_scan.pix_siz = [mri_scan.fov(1)/(mri_scan.siz(1)-1) mri_scan.fov(2)/(mri_scan.siz(2)-1) mri_scan.slice_thick];

mri = zeros(mri_scan.siz(1),mri_scan.siz(2),mri_scan.nslice);
hh = waitbar(0,'Reading files...');
str = str(s);
for i=1:mri_scan.nslice
   file = fopen(str{i},'rb',MACHINEFORMAT);
   % Assume here that code is 'int16'
   status = fseek(file,-mri_scan.siz(1)*mri_scan.siz(2)*2,'eof');
   if status == -1 
      errordlg('Please Check Image size / Number of Slices : do not match file size')
      return
   end
   mri(:,:,i) = fread(file,[mri_scan.siz(1),mri_scan.siz(2)],mri_scan.code);
   fclose(file);
   waitbar(i/mri_scan.nslice);
end
close(hh);

mri_scan.mri = Convert2uint8(mri);
mri_scan.readslice = 1;
mri_scan.filemri = str{i};  
mri_scan.siz =  size(mri_scan.mri);
mri_scan.fov =  mri_scan.pix_siz.*mri_scan.siz;

if strcmp(mri_scan.scantype,'Coronal')
   mri_scan.mri = permute(mri_scan.mri,[1,3,2]);   
elseif strcmp(mri_scan.scantype,'Sagittal')   
   mri_scan.mri = permute(mri_scan.mri,[3,1,2]);   
end

if strcmp(mri_scan.scantype,'Coronal')
   mri_scan.pix_siz  = mri_scan.pix_siz([3,2,1]);   
   mri_scan.fov = mri_scan.fov([3,2,1]);
elseif strcmp(mri_scan.scantype,'Sagittal')
   mri_scan.pix_siz  = mri_scan.pix_siz([1,3,2]);   
   mri_scan.fov = mri_scan.fov([1,3,2]);
end

mri_scan.ptname = {};
mri_scan.otherfig = [];
mri_scan.ptcoord = [];
mri_scan.pthandle  = [];
mri_scan.ptlabels  = [];
mri_scan.gotopoint = 0;
mri_scan.seepoints = 0;
mri_scan.seelabels = 1;
set(handles.mrireadtool_main,'Userdata',mri_scan)   
SlicePos(1) = round(mri_scan.siz(1)/2); 
SlicePos(2) = round(mri_scan.siz(2)/2);
SlicePos(3) = round(mri_scan.siz(3)/2);
ShowAll(handles,SlicePos)

try
   bst_message_window({'As the MRI volume is loaded'...
         'you need to orient it properly inside the MRI cube'...
         'and define a Patient Coordinate System'...
         'Please, specify fiducial points and aproximate Cz'...
         'To do this, postion the crosshairs over the desired point' ...
         'and click "Add Point" button. After all 4 points specified'...
         'click "Define PCS" button'...
         '------------------'});
catch
end




% ------------------------------------------------------------------
function varargout = readbs_Callback(h, eventdata, handles, varargin)
VERBOSE = 0;

%Pretty much the same as 'READ_HEADER', even more simple though.

clear mri_scan
Current = get_user_directory;
cd(Current.SUBJECTS)
if(isempty(varargin))
   [filebs, pathbs] = uigetfile('*subjectimage.mat','Select a .mat file containing the subject image');
   if filebs==0
      return
   end
else
   [PATHSTR,NAME,EXT,VERSN] = fileparts(varargin{1});
   filebs = [NAME EXT];
   pathbs = PATHSTR;
end;

listud = get(handles.listpoints,'Userdata');
if(~isempty(listud))
   listud.ptname = {};
   listud.otherfig = [];
   listud.ptcoord = [];
   listud.pthandle  = [];
   listud.ptlabels  = [];
   listud.gotopoint = 0;
   listud.seepoints = 0;
   listud.seelabels = 1;
   set(handles.listpoints,'Value',0,'String',listud.ptname);
   set(handles.listpoints,'Userdata',listud);
end;

mri_scan.filename = fullfile(pathbs,filebs);
if(exist(mri_scan.filename,'file'))
   cd(pathbs); 
   eval(['load ',mri_scan.filename,' -mat']);
else
   warndlg(sprintf('There is a problem with *subjectimage* file name %s',mri_scan.filename));
   return;
end;


mri_scan.mri = Cube;
clear Cube
mri_scan.pix_siz = Voxsize;
siz = size(mri_scan.mri);

mri_scan.fov = Voxsize.*siz; 
mri_scan.scantype = 'Sagital'; 
mri_scan.filemri = Comment; 
mri_scan.header = 0; 
mri_scan.siz = siz; 
mri_scan.nslice= siz(3); 
mri_scan.slice_thick = Voxsize(3); 
mri_scan.code= 'char'; 
mri_scan.readslice = 0;

if isfield(PCS,'R')% A PCS has been defined 
   mri_scan.pcs = 1;
   mri_scan.rot = inv(PCS.R);
   mri_scan.center = PCS.t ;
   mri_scan.pcs_type = PCS.Comment ;
   mri_scan.PCSFiducial = PCS.PCSFiducial ;
   mri_scan.CubeFiducial = PCS.CubeFiducial ;
   mri_scan.FiducialName = PCS.FiducialName;
   if(isfield(PCS,'PERM'))
      mri_scan.PERM = PCS.PERM;
      mri_scan.FLP  = PCS.FLP;
   else
      mri_scan.PERM = [];
      mri_scan.FLP  = [];
   end;
   
   if exist('scale_fiducials','var') % User uses the dummy head
      mri_scan.scale_fiducials = scale_fiducials;
      mri_scan.rot = mri_scan.scale_fiducials*mri_scan.rot ;
   end
else
   mri_scan.pcs = 0;
end

set(handles.mrireadtool_main,'Userdata',mri_scan) 
SlicePos(1) = round(mri_scan.siz(1)/2); 
SlicePos(2) = round(mri_scan.siz(2)/2);
SlicePos(3) = round(mri_scan.siz(3)/2);
ShowAll(handles,SlicePos)

if isfield(PCS,'R')% A PCS has been defined 
   for p = 1:size(mri_scan.CubeFiducial(:,:),2)
      pcoord = mri_scan.CubeFiducial(:,p).*mri_scan.pix_siz';
      addpoint_Callback(h, eventdata, handles,  pcoord, mri_scan.FiducialName{p},'y');
   end;
end;

if VERBOSE,
   bst_message_window({'To define a new patient coordinate system'...
         'please, specify fiducial points and aproximate Cz'...
         'To do this, postion the crosshairs over the desired point' ...
         'and click "Add Point" button. After all 4 points specified'...
         'click "Define PCS" button'...
         '------------------'});
end



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

ud = get(handles.mrireadtool_main,'Userdata');
if(isempty(ud)) return;  end;
pos =get(h,'Value');
x = pos*ud.fov(1);
ud = get(handles.mrireadtool_main,'Userdata');
set(handles.axa,'YTick',x);
set(handles.axa,'vis','on');

pos = get(h,'Value');
x = pos*ud.fov(1);
set(handles.axc,'XTick',x);

aux1 = min(pos*ud.fov(1),ud.fov(1));
aux1 = max(aux1,1);
ShowSagital(handles,fix(aux1/ud.pix_siz(1)))
set(handles.slider6,'Value',pos);

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

ud = get(handles.mrireadtool_main,'Userdata');
if(isempty(ud)) return;  end;
pos = get(h,'Value');
x = pos*ud.fov(3);

set(handles.axc,'YTick',x);
set(handles.axs,'YTick',x);

aux1 = min(pos*ud.fov(3),ud.fov(3));
aux1 = max(aux1,1);
ShowAxial(handles,fix(aux1/ud.pix_siz(3)))
set(handles.slider5,'Value',pos);


% --------------------------------------------------------------------
function varargout = slider3_Callback(h, eventdata, handles, varargin)
ud = get(handles.mrireadtool_main,'Userdata');
if(isempty(ud)) return;  end;
pos = 1-get(h,'Value');
y = pos*ud.fov(1);

set(handles.axs,'XTick',y);
set(handles.axa,'XTick',y);

aux1 = min(pos*ud.fov(2),ud.fov(2));
aux1 = max(aux1,1);
ShowCoronal(handles,fix(aux1/ud.pix_siz(2)));
set(handles.slider4,'Value',1-pos);



% --------------------------------------------------------------------
function varargout = slider4_Callback(h, eventdata, handles, varargin)
set(handles.slider3,'Value',get(h,'Value'));
slider3_Callback(h, eventdata, handles, varargin)





% ---------------------------------------------------------------
function varargout = slider5_Callback(h, eventdata, handles, varargin)
set(handles.slider2,'Value',get(h,'Value'));
slider2_Callback(h, eventdata, handles, varargin)





% ---------------------------------------------------------------
function varargout = slider6_Callback(h, eventdata, handles, varargin)
set(handles.slider1,'Value',get(h,'Value'));
slider1_Callback(h, eventdata, handles, varargin)





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

VERBOSE = 0;

% obtain necessary handles
mri_scan = get(handles.mrireadtool_main,'Userdata');
hlist = handles.listpoints;

if(isempty(mri_scan)) return; end;
if(isempty(varargin))
   x1 =  get(handles.axa,'YTick');
   x2 =  get(handles.axa,'XTick');
   x3 =  get(handles.axs,'YTick');
else
   x1 = varargin{1}(1);
   x2 = varargin{1}(2);
   x3 = varargin{1}(3);
end;


if((x1*x2*x3)==0) 
   errordlg('Not all crosshairs are located. The point is not uniquely defined','The BrainStorm Toolbox')
   return; 
end;
% fill handle structure
listud = get(hlist,'UserData');

% initialize fields
if(~isfield(listud,'pthandle')) listud.pthandle=[]; end;
if(~isfield(listud,'ptcoord'))  listud.ptcoord=[];  end;
if(~isfield(listud,'ptlabels')) listud.ptlabels=[];  end;
if(~isfield(listud,'ptname')) listud.ptname={};  end;

%add point

prompt  = {'Enter point name:'}; 
title   = 'Please assign a label to the selected point';
lines= 1;

if(isempty(varargin))
   def     = {'LeftEar'};
   answer  = inputdlg(prompt,title,lines,def);
   col = [0.5 0.73 0.96];
else
   answer{1} = varargin{2};
   if(~isempty(varargin{3}))
      col = varargin{3};
   else
      col = [0.5 0.73 0.96];
   end;
end

if ~isempty(answer)
   
   if(length(answer{1})<2)            
      answer{1} = [' ' answer{1}];
   end;
   
   offset = 1;
   pt_s=patch('parent',handles.axs,'xdata',x2,'ydata',x3,'Marker','o',...
      'MarkerEdgeColor','none','MarkerFaceColor',col);
   pl_s = text(x2+offset,x3+offset,answer{1}(1:2),'Color','w','parent',handles.axs,'FontSize',10,'FontWeight','demi');
   set(pl_s,'ButtonDownFcn','mri_read_tool(''sag_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
   set(pt_s,'ButtonDownFcn','mri_read_tool(''sag_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
   
   pt_a=patch('parent',handles.axa,'xdata',x2,'ydata',x1,...
      'Marker','o','MarkerEdgeColor','none','MarkerFaceColor',col);
   pl_a = text(x2+offset,x1+offset,answer{1}(1:2),'Color','w','parent',handles.axa,'FontSize',10,'FontWeight','demi');
   
   set(pl_a,'ButtonDownFcn','mri_read_tool(''ax_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
   set(pt_a,'ButtonDownFcn','mri_read_tool(''ax_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
   
   xlim = get(handles.axc,'xlim');
   pt_c=patch('parent',handles.axc,'xdata',x1,'ydata',x3,...
      'Marker','o','MarkerEdgeColor','none','MarkerFaceColor',col);
   
   pl_c = text(x1+offset,x3+offset,answer{1}(1:2),'Color','w','parent',handles.axc,'FontSize',10,'FontWeight','demi');
   
   set(pl_c,'ButtonDownFcn','mri_read_tool(''cor_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
   set(pt_c,'ButtonDownFcn','mri_read_tool(''cor_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
   
   
   listud.pthandle = [listud.pthandle ; [pt_s,pt_a,pt_c]];
   listud.ptcoord = [listud.ptcoord ; [x1,x2,x3]];
   listud.ptlabels=[listud.ptlabels;[pl_s,pl_a,pl_c]];
   listud.ptcurrent = size(listud.pthandle,1);        
   listud.ptname(listud.ptcurrent)= answer;
   set(hlist,'String',listud.ptname);
   npoints = size(get(hlist,'String'),1);
   set(hlist,'Value',npoints);
   set(handles.hideall,'checked','off');
end
set(hlist,'UserData',listud);
%    toggle_zoomact_Callback(handles.togglebutton4, eventdata, handles, varargin);
if length(listud.pthandle) <= 3, 
   if VERBOSE,
      
      bst_message_window({'A tip: To remove\hide a point Right click'...
            'on the spoints list'...
            '------------------'});
      
   end
end;


%----------------------------------------------------------------------------
function varargout = listpoints_Callback(h, eventdata, handles, varargin)
listud = get(h,'UserData');
if(isempty(listud)) return; end;
ud = get(handles.mrireadtool_main,'Userdata');
val = get(h,'Value');
if(val>0)
   hlist = handles.listpoints;
   coord = listud.ptcoord(val,:);
   
   set(handles.slider2,'Value',coord(3)/ud.fov(3));        
   slider2_Callback(handles.slider2, eventdata, handles, varargin);   
   set(handles.slider3,'Value',1-coord(2)/ud.fov(2));        
   slider3_Callback(handles.slider3, eventdata, handles, varargin);   
   set(handles.slider1,'Value',coord(1)/ud.fov(1));        
   slider1_Callback(handles.slider1, eventdata, handles, varargin);   
   
   lud = get(handles.listpoints,'Userdata');
   if(isempty(lud)) return; end;
   set(lud.ptlabels(val,:),'visible','off');
   set(lud.ptlabels(val,:),'visible','on');
   set(lud.pthandle(val,:),'visible','off');
   set(lud.pthandle(val,:),'visible','on');
   set(handles.hideall,'checked','off');
else
   return;
end;





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





% ---------------------------------------------------------------
function  InstallGotoPointMode(handles)

mri_scan = get(handles.mrireadtool_main,'Userdata');
set(mri_scan.sag,'ButtonDownFcn','mri_read_tool(''sag_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
set(mri_scan.ax,'ButtonDownFcn','mri_read_tool(''ax_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
set(mri_scan.cor,'ButtonDownFcn','mri_read_tool(''cor_ButtonDownFcn'',gcbo,[],guidata(gcbo))');





% ---------------------------------------------------------------
function varargout = sag_ButtonDownFcn(h, eventdata, handles, varargin)
hfig = handles.mrireadtool_main;
ud = get(handles.mrireadtool_main,'Userdata');

if(strcmp(get(hfig,'SelectionType'),'normal')+strcmp(get(hfig,'SelectionType'),'open'));
   sag_point = get(gcbf,'CurrentPoint');
   axpos = get(handles.axs,'Position');
   x0 = axpos(1);
   y0 = axpos(2);
   xlim  =  get(handles.axs,'xlim');
   ylim  =  get(handles.axs,'ylim');
   coord = ((sag_point-axpos(1:2))./axpos(3:4)).*[xlim(2)-xlim(1)  ylim(2)-ylim(1)];
   x = xlim(2)-coord(1);
   y = ylim(2)-coord(2);
   set(handles.slider2,'Value',1-y/ud.fov(3));        
   %   set(handles.slider2,'Value',1-y);        
   slider2_Callback(handles.slider2, eventdata, handles, varargin);
   set(handles.slider3,'Value',1-x/ud.fov(2));        
   %   set(handles.slider3,'Value',x);        
   slider3_Callback(handles.slider3, eventdata, handles, varargin);
   lud = get(handles.listpoints,'Userdata');
   %       set(ud.sag,'EraseMode','xor');
   if(isempty(lud)) return; end;
   
   %      set(lud.pthandle,'visible','off');
   %      set(lud.pthandle,'visible','on');
   
end;





% ---------------------------------------------------------------
function varargout = ax_ButtonDownFcn(h, eventdata, handles, varargin)
hfig = handles.mrireadtool_main;
ud = get(handles.mrireadtool_main,'Userdata');
if(strcmp(get(hfig,'SelectionType'),'normal')+strcmp(get(hfig,'SelectionType'),'open'));
   ax_point = get(gcbf,'CurrentPoint');
   axpos = get(handles.axa,'position');
   x0 = axpos(1);
   y0 = axpos(2);
   xlim  =  get(handles.axa,'xlim');
   ylim  =  get(handles.axa,'ylim');
   
   coord = ((ax_point-axpos(1:2))./axpos(3:4)).*[xlim(2)-xlim(1) ylim(2)-ylim(1)];
   x = xlim(1)+coord(1);
   y = ylim(2)-coord(2);
   
   set(handles.slider1,'Value',1-y/ud.fov(1));        
   slider1_Callback(handles.slider1, eventdata, handles, varargin);
   set(handles.slider3,'Value',x/ud.fov(2));        
   slider3_Callback(handles.slider3, eventdata, handles, varargin);
   lud = get(handles.listpoints,'Userdata');
   if(isempty(lud)) return; end;
   
   %     set(lud.pthandle,'visible','off');
   %    set(lud.pthandle,'visible','on');
end;



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

hfig = handles.mrireadtool_main;
ud = get(handles.mrireadtool_main,'Userdata');
if(strcmp(get(hfig,'SelectionType'),'normal')+strcmp(get(hfig,'SelectionType'),'open'));
   ax_point = get(gcbf,'CurrentPoint');
   axpos = get(handles.axc,'position');
   x0 = axpos(1);
   y0 = axpos(2);
   xlim  =  get(handles.axc,'xlim');
   ylim  =  get(handles.axc,'ylim');
   
   coord = ((ax_point-axpos(1:2))./axpos(3:4)).*[xlim(2)-xlim(1) ylim(2)-ylim(1)];
   x = xlim(1)+coord(1);
   y = ylim(2)-coord(2);
   
   set(handles.slider2,'Value',1-y/ud.fov(3));        
   slider2_Callback(handles.slider2, eventdata, handles, varargin);
   
   set(handles.slider1,'Value',x/ud.fov(1));        
   slider1_Callback(handles.slider1, eventdata, handles, varargin);
   
   lud = get(handles.listpoints,'Userdata');
   if(isempty(lud)) return; end;
   %       set(lud.pthandle,'visible','off');
   %      set(lud.pthandle,'visible','on');
end;





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

if(strcmp(get(h,'checked'),'on'))
   set(h,'checked','off')
   set(handles.axa,'visible','off');
   set(handles.axs,'visible','off');
   set(handles.axc,'visible','off');
else
   set(h,'checked','on')
   set(handles.axa,'visible','on');
   set(handles.axs,'visible','on');
   set(handles.axc,'visible','on');
end;





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





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





% --------------------------------------------------------------------
function varargout = deleteall_Callback(h, eventdata, handles, varargin)
hlist = handles.listpoints;
listud = get(hlist,'UserData');
if(isempty(listud)) return; end;
if(isempty(listud.ptname)) return; end;
drawnow;
if(strcmp(questdlg('This will delete all points','Warning!','OK','Cancel','Cancel'),'OK'));
   set(listud.pthandle(:,:),'visible','off');
   set(listud.ptlabels(:,:),'visible','off');
   listud.pthandle(:,:)=[];
   listud.ptlabels(:,:)=[];
   listud.ptcoord(:,:)=[];
   listud.ptname(:)=[];
   set(hlist,'Value',0,'String',listud.ptname);
   set(hlist,'UserData',listud);
end;





% --------------------------------------------------------------------
function varargout = deletecurrent_Callback(h, eventdata, handles, varargin)
hlist = handles.listpoints;
val = get(hlist,'Value');

listud = get(hlist,'UserData');
if(isempty(listud)) return; end;
if(isempty(listud.ptname)) return; end;
quest = sprintf('This will delete point %s',listud.ptname{val}); 
drawnow;
if(strcmp(questdlg(quest,'Warning!','OK','Cancel','Cancel'),'OK'));
   set(listud.pthandle(val,:),'visible','off');
   set(listud.ptlabels(val,:),'visible','off');
   listud.pthandle(val,:)=[];
   listud.ptlabels(val,:)=[];
   listud.ptcoord(val,:)=[];
   listud.ptname(val)=[];
   strng = get(hlist,'String');
   %       strng(val) = []; 
   set(hlist,'String',listud.ptname)
   npoints = size(get(hlist,'String'),1);
   set(hlist,'Value',npoints);
   set(hlist,'UserData',listud);
end;





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

hlist = handles.listpoints;
val = get(hlist,'Value');
listud = get(hlist,'UserData');
if(isempty(listud)) return; end;
if(isempty(listud.ptname)) return; end;
set(listud.pthandle(val,:),'visible','off');
set(listud.ptlabels(val,:),'visible','off');
set(hlist,'UserData',listud);





% --------------------------------------------------------------------
function varargout = hideall_Callback(h, eventdata, handles, varargin)
if(strcmp(get(h,'checked'),'on'))
   set(h,'checked','off');
   hlist = handles.listpoints;
   listud = get(hlist,'UserData');
   if(isempty(listud)) return; end;
   if(isempty(listud.ptname)) return; end;
   set(listud.pthandle,'visible','on');
   set(listud.ptlabels,'visible','on');
   set(hlist,'UserData',listud);
else
   set(h,'checked','on');
   hlist = handles.listpoints;
   listud = get(hlist,'UserData');
   if(isempty(listud)) return; end;
   if(isempty(listud.ptname)) return; end;
   set(listud.pthandle,'visible','off');
   set(listud.ptlabels,'visible','off');
   set(hlist,'UserData',listud);
end;    





% ---------------------------------------------------------------
function varargout = showall_Callback(h, eventdata, handles, varargin)
set(handles.hideall,'checked','off');
hlist = handles.listpoints;
listud = get(hlist,'UserData');
if(isempty(listud)) return; end;
if(isempty(listud.ptname)) return; end;
set(listud.pthandle,'visible','on');
set(listud.ptlabels,'visible','on');
set(hlist,'UserData',listud);


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





% --------------------------------------------------------------------
function varargout = definepcs_Callback(h, eventdata, handles, varargin)
% vargin empty prompts for assignments.
%  else vargin should be 'ass' and 'CTF'
%  where 'ass' is a index vector of which existing points
%  are Nasion, Left, and Right, and CTF is 0 or 1 depending on
%  coordinate system.

bst_message_window({'To assign selected fiducial points (Right list)'...
      'to their anatomical counterparts (Left list), simply'...
      'choose a pair of corresponding points and press'...
      'Assign button.'...
      'Choose coordinate system type and when you are done click'...
      '"Done" button :)'...
      'To abandon the window simply press "Quit"'... 
      '------------------'});

mri_scan = get(handles.mrireadtool_main,'Userdata');
hlist = handles.listpoints;
listud = get(hlist,'Userdata');

if isempty(varargin),
   % no input provided

   hprms = pcs_params;
   try
      hlistbox1 = findobj(hprms,'tag', 'listbox1');
   catch
      return;
   end;
   set(hlistbox1,'String',listud.ptname);
   FidNames{1} = 'Nasion Point';
   FidNames{2} = 'LEFT Preauricular Point';
   FidNames{3} = 'RIGHT Preauricular Point';
   %FidNames{4} = 'Central Zenith Point';
   
   hlistbox2 = findobj(hprms,'tag', 'listbox2');
   set(hlistbox2,'String',FidNames);
   hcheckboxctf = findobj(hprms,'tag', 'checkboxctf');
   hcheckboxnmag = findobj(hprms,'tag', 'checkboxnmg');
   set(hcheckboxctf,'Value',1);
   set(hcheckboxnmag,'Value',0);
   
   hdone = findobj(hprms,'tag', 'done');
   
   waitfor(hdone,'Enable','off');
 
   try
      ass = get(hprms,'Userdata');
   catch
      % no assignment made, cancelled
      return;
   end;
   
   CTF =  get(hcheckboxctf,'Value');
   
   delete(hprms);

else

   ass = varargin{1};
   CTF = varargin{2};
   
end

fov = mri_scan.fov;
% to be compatible with Sylvains notations and coordinate system
if (prod(ass)==0) return; end;
if (length(ass)~=3) return; end;

NAS = listud.ptcoord(ass(1),:);
LPA = listud.ptcoord(ass(2),:);
RPA = listud.ptcoord(ass(3),:);
%CZE = listud.ptcoord(ass(4),:);
CNT = (LPA+RPA)/2;
%figure out direction and dimension flips

RPA_LPA = RPA-LPA;
[ignore PERM(1)] = max(abs(RPA_LPA));
FLP(1) = RPA_LPA(PERM(1))<0;

NAS_CNT = NAS-CNT;
[ignore PERM(2)] = max(abs(NAS_CNT));
FLP(2) = NAS_CNT(PERM(2))<0;

%CZE_CNT = CZE-CNT;
LR = RPA-LPA;LR = LR/norm(LR);
CN = NAS-CNT; CN = CN/norm(CN);
CZE_CNT = cross(LR,CN);
[ignore PERM(3)] = max(abs(CZE_CNT));
FLP(3) = CZE_CNT(PERM(3))<0;

mri_scan.mri = permute(mri_scan.mri,PERM);
mri_scan.pix_siz = mri_scan.pix_siz(PERM);
mri_scan.fov = mri_scan.fov(PERM);
mri_scan.siz = mri_scan.siz(PERM);
for i = 1:size(listud.ptcoord,1)
   listud.ptcoord(i,:) = listud.ptcoord(i,PERM);
end;

for d = 1:3
   if(FLP(d)==1)
      mri_scan.mri = flipdim(mri_scan.mri,d);
      for i = 1:size(listud.ptcoord,1)
         listud.ptcoord(i,d) = mri_scan.fov(d) - listud.ptcoord(i,d);
      end;
   end;
end;

offset = 1;
for i = 1:size(listud.ptcoord,1)
   set(listud.pthandle(i,1),'xdata',listud.ptcoord(i,2),'ydata',listud.ptcoord(i,3));
   set(listud.ptlabels(i,1),'Position',[listud.ptcoord(i,2)+offset,listud.ptcoord(i,3)+offset, 0]);
   
   set(listud.pthandle(i,2),'xdata',listud.ptcoord(i,2),'ydata',listud.ptcoord(i,1));
   set(listud.ptlabels(i,2),'Position',[listud.ptcoord(i,2)+offset,listud.ptcoord(i,1)+offset, 0]);
   
   set(listud.pthandle(i,3),'xdata',listud.ptcoord(i,1),'ydata',listud.ptcoord(i,3));
   set(listud.ptlabels(i,3),'Position', [listud.ptcoord(i,1)+offset,listud.ptcoord(i,3)+offset, 0]);
end;

%%%  [pl_s,pl_a,pl_c]
% and then reobtain the points
NAS = listud.ptcoord(ass(1),:);
LPA = listud.ptcoord(ass(2),:);
RPA = listud.ptcoord(ass(3),:);
%CZE = listud.ptcoord(ass(4),:);
CNT = (LPA+RPA)/2;


SlicePos(1) = round(mri_scan.siz(1)/2); 
SlicePos(2) = round(mri_scan.siz(2)/2);
SlicePos(3) = round(mri_scan.siz(3)/2);


auxmat = [NAS; LPA; RPA];

if(rank(auxmat)<3)
   errordlg('Rank of the fiducial coordinate matrix is less than 3. Please reassign the fiducials');
   return;
end;

set(listud.pthandle(ass(1),:),'MarkerFaceColor','y'); 
set(listud.pthandle(ass(2),:),'MarkerFaceColor','y'); 
set(listud.pthandle(ass(3),:),'MarkerFaceColor','y'); 
set(hlist,'Userdata',listud);

mri_scan.CubeFiducial = round([NAS./mri_scan.pix_siz;LPA./mri_scan.pix_siz;RPA./mri_scan.pix_siz]'); 

% Indices of the slices containing the fiducials
% mri_scan.CubeFiducial = round([NAS;LPA;RPA]'); % Indices of the slices containing the fiducials


if(CTF==1) %define CTF system
   center = .5*(LPA+RPA)';
   nLR= cross(NAS-RPA,RPA-LPA);  % Vector normal to the NLR plane
   nLR = nLR/norm(nLR);
   vx = (NAS-center')'/norm((NAS-center'));
   vy = inv([vx';nLR;cross(vx',nLR)])*[0 0 1]'; % y direction
   vy = vy/norm(vy);
   vz = cross(vx,vy);
   mri_scan.pcs_type = 'CTF';
else % define MRI system
   vx = (RPA' - LPA')/norm(RPA' - LPA'); % Left\Right Vector
   center = LPA'+vx*(vx'*(NAS'-LPA'));
   vy = (NAS'-center)/norm(NAS'-center);
   vz = cross(vx,vy);
   mri_scan.pcs_type = 'NEUROMAG';
end;
rot = inv([vx vy vz]);

mri_scan.CubeFiducial = [mri_scan.CubeFiducial,round(center./mri_scan.pix_siz')];

mri_scan.pcs = 1;
mri_scan.center = center;
mri_scan.RPA = RPA;
mri_scan.LPA = LPA;
mri_scan.NAS = NAS;
mri_scan.rot = rot;
if(isfield(mri_scan, 'PERM'))
   if(~isempty(mri_scan.PERM))
      mri_scan.FLP = xor(FLP,mri_scan.FLP);
      mri_scan.PERM = mri_scan.PERM(PERM);
   else
      mri_scan.FLP = FLP;
      mri_scan.PERM = PERM;
   end;
else
   mri_scan.FLP = FLP;
   mri_scan.PERM = PERM;
end;


% Coordinates of the fiducials in the PCS
fiduc  = transform('mri2pcs',[NAS',LPA', RPA'],inv(mri_scan.rot),mri_scan.center);
mri_scan.PCSFiducial = [fiduc,[0 0 0]'];
mri_scan.FiducialName = listud.ptname([ass(1),ass(2),ass(3)]);
mri_scan.FiducialName{4} = 'Origin';

set(handles.mrireadtool_main,'Userdata',mri_scan);
addpoint_Callback(h, eventdata, handles, center,'Or','r');
listud = get(hlist,'Userdata');
set(hlist,'Userdata',listud);
ShowAxial(handles, SlicePos(3));
ShowCoronal(handles, SlicePos(1));
ShowSagital(handles, SlicePos(2));
drawnow;

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

mri_scan = get(handles.mrireadtool_main,'Userdata');
listud = get(handles.listpoints,'Userdata');

if isempty(listud)
   return
end


ptname =  listud.ptname ;
ptcoordMRI = listud.ptcoord;
if isempty(ptcoordMRI)
   return
end

if(isfield(mri_scan,'rot'))
   ptcoordPCS = transform('mri2pcs',ptcoordMRI',inv(mri_scan.rot),mri_scan.center)';
else
   ptcoordPCS = inf;
end;

ptcoordCube = fix(ptcoordMRI*diag(1./mri_scan.pix_siz));

[fpt_file,fpt_dir] = uiputfile('*.fpt','Save point locations in...');

try
   file = fopen([fpt_dir,fpt_file],'w+');
catch
   return
end;


for i = 1:length(ptname)
   tmp = char(ptname{i});
   fprintf(file,'%d\t%s\t\t\t%6.2f\t%6.2f\t%6.2f\t%d\t%d\t%d\n',i,tmp,[ptcoordPCS(i,1),ptcoordPCS(i,2),ptcoordPCS(i,3)], ...
      round([ptcoordCube(i,1),ptcoordCube(i,2),ptcoordCube(i,3)]));
end;
fclose(file);    





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

ud = get(handles.mrireadtool_main,'Userdata');
if(isempty(ud)) return;  end;

clim = get(handles.axs,'CLim');
set(handles.axs,'CLim',1.1*clim);
set(handles.axa,'CLim',1.1*clim);
set(handles.axc,'CLim',1.1*clim);





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

ud = get(handles.mrireadtool_main,'Userdata');
if(isempty(ud)) return;  end;
clim = get(handles.axs,'CLim');
set(handles.axs,'CLim',.9*clim);
set(handles.axa,'CLim',.9*clim);
set(handles.axc,'CLim',.9*clim);



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

h = [];
try
   h = getappdata(handles.mrireadtool_main,'resviewerhandle');
catch
end;

if(~isempty(h))
   close(h);
end;

h_dm = getappdata(handles.mrireadtool_main,'DataManager');
if(~isempty(h_dm))
   setappdata(h_dm,'mri_fig',[]);
end;
close(handles.mrireadtool_main);



% --------------------------------------------------------------------
function varargout = zoomtoggle_Callback(h, eventdata, handles, varargin)
ud = get(handles.mrireadtool_main,'Userdata');
if(isempty(ud)) return;  end;
if(get(h,'Value')==1)
   zoom('on');
   setptr(handles.mrireadtool_main,'glass')
   set(h,'String','Zoom Off');
else
   zoom('off');
   setptr(handles.mrireadtool_main,'arrow')
   set(h,'String','Zoom On');
end;

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

if get(handles.littleendian_radiobutton,'value') == 1
   MACHINEFORMAT = 'l';
else
   MACHINEFORMAT = 'b';
end;

clear mri_scan

clear mri_scan
Current = get_user_directory;
cd(Current.SUBJECTS)
if(isempty(varargin))
   [filebs, pathbs] = uigetfile('*.img','Select a .mat file containing the subject image');
   if filebs==0
      return
   end
end;

cd(pathbs); 
[PATHSTR,NAME,EXT,VERSN] = FILEPARTS(filebs);
HeaderFile = [NAME '.hdr'];
if(~exist(HeaderFile,'file'))
   warndlg(sprintf('Header file to %s can not be found',HeaderFile),'Import BrainSUITE format');
end;

[mri_scan.siz,mri_scan.pix_siz] = analyze_header_read(HeaderFile);
%   [A B] = analyze_header_save('test.hdr',mri_scan.siz,mri_scan.pix_siz,'L');

VolumeFile = [NAME '.img'];
f = fopen(VolumeFile,'rb');
mri_scan.mri = int16(fread(f,'uchar'));
fclose(f);
mri_scan.mri = reshape(mri_scan.mri,mri_scan.siz);
mri_scan.slice_thick = mri_scan.pix_siz(3);
mri_scan.nslice = mri_scan.siz(3);
mri_scan.fov = [mri_scan.siz].*mri_scan.pix_siz;
mri_scan.scantype = 'Axial';


listud = get(handles.listpoints,'Userdata');
if(~isempty(listud))
   listud.ptname = {};
   listud.otherfig = [];
   listud.ptcoord = [];
   listud.pthandle  = [];
   listud.ptlabels  = [];
   listud.gotopoint = 0;
   listud.seepoints = 0;
   listud.seelabels = 1;
   set(handles.listpoints,'Value',0,'String',listud.ptname);
   set(handles.listpoints,'Userdata',listud);
end;

mri_scan.readslice = 1;
mri_scan.filemri = fullfile(pathbs, filebs);  
mri_scan.header = 0;


mri_scan.mri = Convert2uint8(mri_scan.mri);

mri_scan.ptname = {};
mri_scan.otherfig = [];
mri_scan.ptcoord = [];
mri_scan.pthandle  = [];
mri_scan.ptlabels  = [];
mri_scan.gotopoint = 0;
mri_scan.seepoints = 0;
mri_scan.seelabels = 1;
set(handles.mrireadtool_main,'Userdata',mri_scan)   
SlicePos(1) = round(mri_scan.siz(1)/2); 
SlicePos(2) = round(mri_scan.siz(2)/2);
SlicePos(3) = round(mri_scan.siz(3)/2);
ShowAll(handles,SlicePos);


function [DIM,VOX]=analyze_header_read(s)

hdr=[];
hdr.endian = 'ieee-le';
fid=fopen(s,'rb',hdr.endian);
if (fid<0) error(sprintf('Unable to open %s',s)); end;
hdrsize = fread(fid,1,'int32');
if (hdrsize>5000)
   hdr.endian = 'ieee-be';
end;
fclose(fid);

fid=fopen(s,'rb',hdr.endian);
if (fid<0) error(sprintf('Unable to open %s',s)); end;

hdr.sizeof_hdr = fread(fid,1,'int32');
hdr.datatype = char(fread(fid,10,'char')');
hdr.dbName = char(fread(fid,18,'char')');
hdr.extents = fread(fid,1,'int32');
hdr.sessionError = fread(fid,1,'short');
hdr.regular = char(fread(fid,1,'char'));
hdr.hkeyUn0 = fread(fid,1,'char');
hdr.ndims = fread(fid,1,'int16');
hdr.xdim = fread(fid,1,'int16');
hdr.ydim = fread(fid,1,'int16');
hdr.zdim = fread(fid,1,'int16');
hdr.tdim = fread(fid,1,'int16');
hdr.pad3 = fread(fid,10,'int16');
hdr.datatype = fread(fid,1,'int16');
hdr.bits = fread(fid,1,'int16');
hdr.pad4 = fread(fid,6,'char');
hdr.xsize = fread(fid,1,'float32');
hdr.ysize = fread(fid,1,'float32');
hdr.zsize = fread(fid,1,'float32');
hdr.pad5  = fread(fid,5,'float32');
hdr.pad6  = fread(fid,28,'char');
hdr.glmax = fread(fid,1,'int32');
hdr.glmin = fread(fid,1,'int32');
hdr.descrip = fread(fid,80,'char');
hdr.pad7 = fread(fid,120,'char');

VOX = [hdr.xsize hdr.ysize hdr.zsize];
DIM = [hdr.xdim hdr.ydim hdr.zdim];

fclose(fid);

function analyze_header_save(s,DIM,VOX,MACHINEFORMAT)

hdr=[];
if(upper(MACHINEFORMAT)=='L')
   hdr.endian = 'ieee-le';
else
   hdr.endian = 'ieee-be';
end;
fid=fopen(s,'wb',hdr.endian);
if (fid<0) error(sprintf('Unable to open %s',s)); end;


fwrite(fid,int32(348),'int32');
fwrite(fid,'BST to BSU','char'); %hdr.datatype
fwrite(fid,'BST to BSU convers','char'); %hdr.dbName;
fwrite(fid,int32(1242912),'int32');   %hdr.extents   
fwrite(fid,int16(-1),'int16'); %hdr.sessionError;
fwrite(fid,'r','char'); %hdr.regular;
fwrite(fid,char(119),'char'); %hdr.hkeyUn0;
hdr.ndims = fwrite(fid,int16(3),'int16'); %hdr.ndims
fwrite(fid,int16(DIM(1)),'int16'); %hdr.xdim
fwrite(fid,int16(DIM(2)),'int16'); %hdr.ydim
fwrite(fid,int16(DIM(3)),'int16'); %hdr.zdim
fwrite(fid,int16(0),'int16'); %hdr.tdim
fwrite(fid,int16(zeros(1,10)),'int16');%hdr.pad3
fwrite(fid,int16(2),'int16');%hdr.datatype
fwrite(fid,int16(8),'int16'); %hdr.bits
fwrite(fid,char(zeros(1,6)),'char');%hdr.pad4
fwrite(fid,VOX(1),'float32'); %hdr.xsize
fwrite(fid,VOX(2),'float32'); %hdr.ysize
fwrite(fid,VOX(3),'float32'); %hdr.zsize
fwrite(fid,(zeros(1,5)), 'float32');%hdr.pad5
fwrite(fid,char(zeros(1,28)), 'char');%hdr.pad6
fwrite(fid,int32(1243032), 'int32');%hdr.glmax
fwrite(fid,int32(4590617), 'int32');%hdr.glmin
fwrite(fid,char(zeros(1,80)),'char'); %hdr.descrip
fwrite(fid,char(zeros(1,120)), 'char');%hdr.pad7

fclose(fid);
