%STARTUP - Start the BrainStorm Session
% This m-file should be in the folder containing "Toolbox", "Documents", "Custom"
%
% Startup will create a default database in the BrainStorm directory and
%  present user database, if necessary.

%<autobegin> ---------------------- 08-Jun-2004 15:14:20 -----------------------
% --------- Automatically Generated Comments Block Using AUTO_COMMENTS ---------
%
% CATEGORY: Unknown Category
%
% Alphabetical list of external functions (non-Matlab):
%   toolbox\browse_study_folder.m
%   toolbox\bst_message_window.m
%   toolbox\bst_splashscreen.m
%   toolbox\bst_static_taskbar.m
%   toolbox\data_manager.m
%   toolbox\layout_manager.m
%   toolbox\make_default_database.m
%
% Group : Preference data and their calls in this file:
%   'BrainStorm' : 'UserDataBase'
%   'BrainStorm' : 'Version'
%   'BrainStorm' : 'brainstormHomeDir'
%   'BrainStorm' : 'iUserDataBase'
%   
%   setpref('BrainStorm','UserDataBase',UserDB)
%   setpref('BrainStorm','UserDataBase',UserDB);
%   setpref('BrainStorm','UserDataBase',UsersDB);
%   setpref('BrainStorm','Version',VER);
%   setpref('BrainStorm','brainstormHomeDir',brainstormHomeDir)
%   setpref('BrainStorm','iUserDataBase',1);
%   setpref('BrainStorm','iUserDataBase',length(UserDB));
%   
%   DateofAgreement = getpref('BrainStorm','DateofAgreement',datestr(floor(now) - GRACE - 1));
%   UserDB = getpref('BrainStorm','UserDataBase');
%   UsersDB = getpref('BrainStorm','UserDataBase');
%   getpref('BrainStorm','CurrentData',[]);
%   getpref('BrainStorm','Studies',[]);
%   getpref('BrainStorm','StudySubject',[]);
%   getpref('BrainStorm','Subjects',[]);
%   if(strcmp(getpref('BrainStorm','DateofAgreement'),datestr(floor(now))))
%
% Application data and their calls in this file:
%   'BrainStormTaskbar'
%   
%   setappdata(0,'BrainStormTaskbar',TASKBAR);
%   
%
% At Check-in: $Author: Mosher $  $Revision: 45 $  $Date: 6/08/04 1:40p $
%
% This software is part of BrainStorm Toolbox Version 2.0 (Alpha) 28-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> ------------------------ 08-Jun-2004 15:14:20 -----------------------


% /---Script Author--------------------------------------\
% |                                                      |
% | *** Sylvain Baillet Ph.D.                            |
% | Cognitive Neuroscience & Brain Imaging Laboratory    |
% | CNRS UPR640 - LENA                                   | 
% | Hopital de la Salpetriere, Paris, France             |
% | sylvain.baillet@chups.jussieu.fr                     |
% |                                                      |
% | *** John C. Mosher, Ph.D.                            |
% |    Design Technology Group                           |
% |    Los Alamos National Laboratory                    |
% |    Los Alamos, New Mexico, USA                       |
% \------------------------------------------------------/
%  
% Date of creation: March 1999
% Script History -----------------------------------------------------------------------------------------------------------
% JCM 2000/03/15 Adjusting copyright notice
% JCM 2000/09/29 custom folder got moved, correcting addpath logic, cleaning up
% JCM 2001/03/01 adding in developers toolboxes for BST 2001
% SB  2001/08/14 revamped version 
% JCM 2001/12/21 turn off figure toolbar
% JCM 2002/02/25 dropped add_toolbox, use the new genpath function which handles nicely private
% .............. and object classes while recursively building the path
% JCM 2002/03/20 major changes to call taskbar and bst_splashscreen switchyards, which
% .............. now do a lot of the work originally listed here
% JCM 2002/06/60 removed initial CLC, want to see history when restarting
% JCM 2002/06/24 Added "Starting" at beginning
% JCM 2002/10/28 Fixing database and startup problems. Ensures that folders are where they
%                should be. Halts use of Custom/users.mat and bst_prev_session, relying instead
%                on getprefs. Makes sure there is a default Studies and Subjects folders in
%                the main toolbox. Lots more comments. Some rearranging of components.
% JCM 2002/11/05 Minor commenting.
% JCM 2002/11/07 Backwards compat. If users.mat is detected, copies contents into database
%                  before moving users.mat to users_old.mat
% JCM 20-May-2003 bst_layout compatability, version number in prefs
% JCM 29-May-2003 added call to the new bst_static_taskbar, mostly dummy at this point
% SB  03-Jun-2003 Added new field FILELIST to database structure for faster display in Data_Manager
% JCM 12-Jun-2003 Changed version history concept. We will retrieve the version
%                 from the Contents.m file in the toolbox directory. Also set splashscreen to once
%                 a week, instead of daily.
% JCM 20-Aug-2003 bug with DateofAgreement, if not existing, added "grace" variable, improved
%                 the generation of a default database through the centralized function
%                 make_default_database
% JCM 09-Sep-2003 Deactivating old taskbar, deactivated the old "users.mat" 
% JCM 11-Sep-2003 Cleaning notation, variables for clarity, detections of default databases
% SB  17-Oct-2003 Adding 'brainstormHomeDir' field to preference 'BrainStorm' to specify where is 
%                 BrainStorm's home directory
% JCM 17-Dec-2003 Changing case of Toolbox, contents.m to be consistent.
% SB  16-Feb-2004 Fixed bug when pref DateofAgreement was not properly defined before 
%                 (e.g. following an interrupted startup)
% JCM 11-May-2004 Fixed SB 16-Feb-2004 fix to make default date stale. Updated
%                 Welcome statements.
% JCM 27-May-2004 Matlab version handling to detect particularly 6.5.0 and alert
%                 to the need to upgrade to 6.5.1
% JCM 28-May-2004 yesterday's approach bad, rewrote version as well for other
%                 platforms
% -------------------------------------------------------------------------------------------------------------------------

% -----------------  BrainStorm Version History ----------------------------------
% Jun-2003 We begin a version number in the code. We find the version information
%  in the Contents.m file, in the Mathworks "ver" format. We write
%  the Contents.m file using make_contents, which reads the current 
%  BrainStorm pref information "Version", also in "ver" structure format.
%  The utility generate_brainstorm updates the pref information.
% 
% Numbering CONCEPT:
%  Bug fixes are increments in the third place, 2.0.1, ala Mathworks style.
% Initial scheme:
%  Version 2.0 should be the "alpha" release in USC and CNRS for bug testing
%  Version 2.1 should be the "beta" released summer 2003 to the world
%  Version 2.5 should be the full release sometime later in 2003.
% ACTUAL
% June 2003, working on 2.0 (Alpha_Pre) release, the pre release version of
%            our new Alpha version.
% -----------------  End Version History ----------------------------------

% first bootup of Matlab can be slow, give an indication we are alive
disp('Starting BrainStorm, watch for messages in Message Window . . .') 

% -------------------------- Matlab Version Check ------------------------------
if ~exist('version','builtin')
   % this command built-in for at least 6.1 or better, not sure about older
   VERSION_UNKNOWN = 1;
   MatlabVersion = ver;
   iMATLAB = strmatch('MATLAB',{MatlabVersion.Name});
   if isempty(iMATLAB) | length(iMATLAB) > 1
      % either none or too many, give up for now
      disp(sprintf('\n\nCannot determine your Matlab version. Should be 6.1 or better, but not 6.5.0.'));
      disp(sprintf('Type "ver" at the command line to confirm.\n\n'));
      ver
      MatlabVersion = []; % empty
   else
      % one matlab number
      MatlabVersion = MatlabVersion(iMATLAB); % trim to the matlab license
      % Version is something like 'x.y.z'
   end
else
   VERSION_UNKNOWN = 0; % not unknown version commmand
   MatlabVersion = version; 
end

% so MatlabVersion is a string, '6.5', '6.5.0', '6.5.1', 
%  '6.1.0.450 (R12.1)' or '6.5.1.199709 (R13) Service Pack 1'
temp = MatlabVersion;
i = 0;
MatlabRevisionNumbers = cell(1); % initialize
while ~isempty(temp),
   [nextToken,temp] = strtok(temp,'. '); % parse by dots or space
   nextNumber = str2num(nextToken);
   if ~isempty(nextNumber), % valid number
      i = i+1;
      MatlabRevisionNumbers{i} = nextNumber;
   end
end

lenVersion = i; % number of elements in version numbers
lenVersion = min(lenVersion,3); % only interested in first three
% convert 'x.y.z' to xxyyzz number

MatlabVersionNumber = 0;
for i = 1:lenVersion,
   pow = 6 - i*2; % [4 2 0]
   MatlabVersionNumber = MatlabVersionNumber + MatlabRevisionNumbers{i}*10^pow;
end

if MatlabVersionNumber < 060100, % less than 6.1
   disp(sprintf('\n\nIMPORTANT!\n\n'))
   disp(sprintf('Your Matlab version %s is earlier than 6.1 (R12.1), some commands may not work.',...
      MatlabVersion));
   disp(sprintf('Recommend you upgrade to 6.5.1 (R13.1)\n\n'));
elseif MatlabVersionNumber == 060500, % = 6.5.0
   disp(sprintf('\n\nIMPORTANT!'))
   disp(sprintf('\n\nYour Matlab version %s has known problems with fseek and ftell.',...
      MatlabVersion));
   disp(sprintf('See \n %s \n and \n %s',...
      'http://www.mathworks.com/support/solutions/data/1-1A2W2.html',...
      'http://www.mathworks.com/support/solutions/data/1-19NOK.html?solution=1-19NOK'));
   disp('Binary I/O in BrainStorm may be unreliable.');
   disp(sprintf('Recommend you upgrade to 6.5.1 (R13.1)\n\n'));
end



% ------------- First make things pretty -----------------------

format compact
% user can manually select on a figure menu, but otherwise this option can eat up enormous resources:
set(0,'defaultfiguretoolbar','none'); 

% set the default fontname for uicontrols
if(ispc)
   set(0,'defaultuicontrolfontname','arial'); % much better than ms sans serif!
   % (we could probably get away with "Helvetica" for PC, which would map Arial)
elseif(isunix)
   set(0,'defaultuicontrolfontname','Helvetica'); % should be standard in unix world   
else
   % don't do anything
end



% ----------------- Setup the MatlabPath -----------------------

brainstormHomeDir = fileparts(which(mfilename)); % where is this startup file
setpref('BrainStorm','brainstormHomeDir',brainstormHomeDir)
cd(brainstormHomeDir); % make sure we are in that directory

% Assume now we are in the BrainStorm folder. In this folder is Toolbox, Documents, and Custom.

% Add folders, pay attention to precedence. Want Developers on top, then Custom, then Toolbox,
%  then PublicToolbox, then the BrainStorm Folder.
% Add these folders in reverse precedence,
%  be careful of case sensitivity in unix, generate full file names

% We also need to be sure that these folders actually exist. So as we add them,
%  check for them

% The BrainStorm folder itself
addpath(pwd) % make sure the main brainstorm folder is in the path

NEXTDIR = {'PublicToolbox','Toolbox','Custom'}; % in reverse order of priority

for i = 1:length(NEXTDIR), % each directory
   lastwarn(''); % reset the last warning to blank
   nextdir = fullfile(brainstormHomeDir,NEXTDIR{i}); % full name
   P = genpath(nextdir); % Recursive search for subfolders in each main folder
   
   if(~isempty(lastwarn)),
      % warning was probably null assignment: 
      % "One or more output arguments not assigned during call to 'genpath'"
      % will assume so without checking
      if(~exist(nextdir,'dir')),
         % the folder doesn't exist!
         bst_error_message = {'Something wrong with your brainstorm paths. The folder:',...
               nextdir,...
               'is not present. Please check your installation in the main BrainStorm folder:',...
               brainstormHomeDir,...
               'and be sure this folder exists.'};
         bst_message_window('wrap',bst_error_message);
         error('See bst_message_window for error')
         
      else
         % we had a "lastwarn" that was not a missing directory. don't know what it is
         disp('Unknown error in generating path. Contact brainstorm@sipi.usc.edu with this complete')
         disp('error message:')
         disp(lastwarn)
         disp('Thank-you');
      end
   end
   
   addpath(P);
end



% ----------- BrainStorm Version Action ------------------
% now again ensure we are in the home directory
cd(brainstormHomeDir); % make sure we are in that directory
cd Toolbox % go into the toolbox
% "ver" is a fussy command, case sensitive, while CD and others are not
% for instance, if C:\BrainStorm_2001\Toolbox, must be
%  ver('BrainStorm\Toolbox');
% So let's keep this simple and just read our own contents.m file
fid = fopen('contents.m','rt');
Name = fgetl(fid); % the name line
STR2 = fgetl(fid); % the second line with version, release and data
fclose(fid);
Name = Name(3:end); %trim the comment
STR2 = fliplr(STR2); % easier handling
[Date,STR2] = strtok(STR2);
[Release,STR2] = strtok(STR2);
Version = strtok(STR2);
% reverse them to original
Version = fliplr(Version);
Release = fliplr(Release);
Date = fliplr(Date);

% CBB, we could compare the Contents with the Prefs. For now, just
%   overwrite.
% set this data into the preferences
VER = struct('Name',Name,'Version',Version,'Release',Release,'Date',Date);
setpref('BrainStorm','Version',VER);





% ---------------- Invoke Task Bar and Message Window ----------------------

% with paths defined, invoke taskbar and message window

% The Main BrainStorm Toolbar
% Deactivated by JCM 09-Sep-2003
% TASKBAR = taskbar; % launch the taskbar
% guidata(TASKBAR,[]) % clear it (will use getappdata in future versions)

TASKBAR = bst_static_taskbar; % launch the new static taskbar
setappdata(0,'BrainStormTaskbar',TASKBAR); % used as a flag to indicate GUI use of BrainStorm

bst_message_window; % create the window

bst_message_window('Starting BrainStorm . . .');

layout_manager; % launch the layout manager dynamic taskbar

if(exist('Developers','dir')), % there is a developers folder
   % we want to prepend ONLY one developer, not all developers
   % rather than use genpath, we'll use this custom code to create a menu
   
   cd(brainstormHomeDir); % make sure we are in that directory
   cd Developers
   
   d = dir; % directory of the present working directory
   for i = 1:length(d),
      if(d(i).name(1) == '.'), % either current or parent
         d(i).isdir = logical(0);  % don't want it
      end
   end   
   dfol = d([d.isdir]);  % only the directories
   
   bst_message_window({'','Developer''s folder detected. Select your name in the menu'});
   
   k = menu('Which developer are you?',dfol.name); % present choice to the developer
   
   P = genpath(fullfile(brainstormHomeDir,'Developers',dfol(k).name)); % get all of the folders in the developers folder
   
   addpath(P) % add all of the developer's personal folders
   
   bst_message_window({'','Your personal developer toolbox has precedence over normal BST functions'})
   bst_message_window({sprintf('Developer %s folder has highest precedence',dfol(k).name)})
   bst_message_window({sprintf('Added the following folders: %s',P),''});
   
   cd(brainstormHomeDir); % back to the brainstorm folder
   drawnow
   
end

clear P % Paths are now set



% ----------------- Say hello to the user ---------------------

% Create and Welcome the user on the Message Window
bst_message_window({sprintf('Welcome to BrainStorm!'),'', ...
      ['Default BrainStorm directory is set to: ',pwd],'',...
      'User''s custom toolbox prepended to toolbox search paths'})



% ---------------------- Confirm or Create a Database --------------------------
% verify the existence of a database and a default databases

UserDefault = make_default_database(0); % only check the current database
% confirms/creates as needed both the preference and the default database


% ----------------------- Ensure the Phantom Database --------------------------
UserDB = getpref('BrainStorm','UserDataBase'); % get the full database

if ~any(strcmp('Phantom',{UserDB.Comment})),
   % Phantom database is missing
   
   % first ensure it exists, if not, make it
   if ~exist(fullfile(brainstormHomeDir,'Phantom'),'dir'),
      mkdir(brainstormHomeDir,'Phantom'); % make it
   end
   
   UserDB(end+1) = struct('Comment','Phantom',...
      'STUDIES',fullfile(brainstormHomeDir,'Phantom'),...
      'SUBJECTS',fullfile(brainstormHomeDir,'Phantom'),...
      'FILELIST',[]);
   setpref('BrainStorm','UserDataBase',UserDB)
   % now point at the new database
   setpref('BrainStorm','iUserDataBase',length(UserDB)); 
   UserDefault = make_default_database(0); % mow check the current database for the defaults
end


   
   
% SB | 02-Jun-2003
% ----------------- Backwards Compatibility ---------------------------
% for previous databases with no FILELIST entry

% JCM 12-Sep-2003, section deprecated. make_default_database now checks this,
%  making sure the database actually exists, etc.
if(0)
   
   UserDB = getpref('BrainStorm','UserDataBase'); % get the full database
   
   
   if ~isfield(UserDB(1),'FILELIST') % DB is too old - update by adding field FILELIST to every entry
      bst_message_window('Updating current database structure. . .')
      % Now explore every DB entry and fill out the FILELIST field
      for k= 1:length(UserDB)
         UserDB(k).FILELIST = browse_study_folder(UserDB(k).STUDIES);
      end
      setpref('BrainStorm','UserDataBase',UserDB);
      bst_message_window('Updating current database structure -> DONE')
   end
end


% now the other preferences

% NOTE: bug in R12.1 does not allow us to directly retrieve preferences set to empty.
% so setpref('junk','a',[]) returns ok as getpref('junk'), and getpref('junk','a',[]), but
%  not as getpref('junk','a');

% each of these calls will initialize the preference, if it does not exist
getpref('BrainStorm','CurrentData',[]); % initialize as empty, if not exist
getpref('BrainStorm','StudySubject',[]); % initialize as empty, if not exist
% list of Studies and Subjects currently available in the database
getpref('BrainStorm','Studies',[]); % initialize as empty, if not exist
getpref('BrainStorm','Subjects',[]);



% --------------- Obsolete: Custom folder use -------------------------------

% Removed 29 Oct 2002, we now use getpref above
if (0) % deprecated formats
   % What was the previous data file system used during the previous session ?
   default_custom = what('Custom'); % where is the custom folder 
   if(~exist('Users.mat','file')), % there is no Users.mat file; use default
      bst_message_window({'','No session history detected - Using default parameters'});
      Users = struct('Comment','Default Settings','STUDIES',[],'SUBJECTS',[]);
      Users.STUDIES = fullfile(pwd,'Studies');
      Users.SUBJECTS = fullfile(pwd,'Subjects');  
      save(fullfile(default_custom.path,'bst_prev_session.mat'),'Users'); % save the default structure
      save(fullfile(default_custom.path,'Users.mat'),'Users'); % save the default structure
   else
      load('Users.mat');
   end
   
   if ~exist('bst_prev_session.mat','file') % User starts BsT for the first time - load the default database from users.mat
      load(fullfile(default_custom.path,'Users.mat'));
      Users = Users(1); % Take first database as default
      save(fullfile(default_custom.path,'bst_prev_session.mat'),'Users');
   else
      load('bst_prev_session.mat')
   end
   
   % Deactivated by JCM 09-Sep-2003
   %guidata(TASKBAR,Users);
   %setappdata(TASKBAR,'BrainStormDataBase',Users);
   
   cd(brainstormHomeDir); % back to the brainstorm folder
   
end % deprecated code


% ----------------- Backwards Compatibility ---------------------------

if(0), % obsolete, too much has changed to use Users.Mat, by jcm 8-sep-2003
   % clean up the legacy, we now use only the preferences
   user_mat = fullfile(brainstormHomeDir,'Custom','users.mat');
   if(exist(user_mat)), % old users.mat still around
      
      bst_message_window('wrap',{'Detected Users.mat in your custom directory.',...
            'Appending and sorting this information into your database.',...
            'Moving Users.mat to Users_old.mat.'});
      
      % copy this user.mat information into the database
      
      UsersMat = load(user_mat);
      UsersMat = UsersMat.Users; % remap the load structure for convenience
      
      UsersDB = getpref('BrainStorm','UserDataBase'); % reload the existing database
      
      UsersDB = [UsersDB UsersMat]; % append structure
      
      % now make unique by Comment name
      [ignore,iComment] = unique({UsersDB.Comment});
      UsersDB = UsersDB(iComment); % sorted, unique list in database
      setpref('BrainStorm','UserDataBase',UsersDB);
      % reset pointer to first in this new database
      setpref('BrainStorm','iUserDataBase',1);
      
      % move the old file
      copyfile(user_mat,strrep(user_mat,'users','users_old'));
      delete(user_mat);
   end
   
   
   user_prev = fullfile(brainstormHomeDir,'Custom','bst_prev_session.mat');
   if(exist(user_prev)),
      bst_message_window('wrap',['Detected old bst_prev_session.mat file ',...
            'in Custom folder. Moving it to bst_prev_session_old.mat.']);
      % don't use this information, just move it
      copyfile(user_prev,strrep(user_prev,'session','session_old'));
      delete(user_prev);
   end
   
end % obsolete backwards compat


% --------------- License Agreement --------------------------
GRACE = 14; % number of days to allow as grace period for renewing license

DateofAgreement = getpref('BrainStorm','DateofAgreement',datestr(floor(now) - GRACE - 1)); % initialize as stale, if not exist

if isempty(datenum(DateofAgreement)) % In case of any troubles with this preference
    DateofAgreement = datestr(floor(now) - GRACE - 1);
end

DaysSinceAgree = etime(datevec(now),datevec(DateofAgreement));
DaysSinceAgree = DaysSinceAgree/(60*60*24); % convert seconds to days

if(DaysSinceAgree < GRACE),
   % user has already agreed to Brainstorm recently
   % do nothing, skip to next switch
   ok = 1; % SB 13-Jun-2003 | flag indicating agreement conditions are valid
else
   % user has not agreed today already
   ok = 0; 
   bst_splashscreen; % is modal in the switchyard, won't return until closed
end

% have possibly just returned from splashscreen, check status of agreement again

if(strcmp(getpref('BrainStorm','DateofAgreement'),datestr(floor(now)))) | ok,
   % user has agreed to Brainstorm
   % make one long string
   msg_str= ['Thank-you for agreeing to the license terms today. ',...
         'Type ''bst_splashscreen'' at the command prompt to review, if needed.'];
   bst_message_window(' ');
   bst_message_window('wrap',msg_str);
   
   msg_str = ['Welcome to BrainStorm.'];
   msg_str2 = [];
   
   bst_message_window(' ');
   bst_message_window('wrap',[msg_str,' ',msg_str2]);
   
   
else
   % user has disagreed!
   bst_message_window('close'); % close the message window explicitly
   close('all')
   disp('License agreement unsatisfied. Closing BrainStorm. . .');
   disp('Type ''startup'' to restart BrainStorm')
   
end

% ------------------ Launch the Data Manager -------------------
% Need this to ensure that the static taskbar is loaded up with 
%  a valid study

data_manager;



% -------------------- Done with the startup ---------------------
% imitate the 'ver' command
disp('BrainStorm Version:')
disp(sprintf('%s     Version %s %s  %s',Name,Version,Release,Date));

bst_message_window('append',{'BrainStorm Version:',...
      sprintf('%s     Version %s %s  %s',Name,Version,Release,Date)})


disp('If you cannot see BrainStorm windows, try typing bst_layout(''full'') at the command prompt')
disp('to reset window locations to their default full screen.')
