function notebook(fileName, wordVer, wordLoc, templateLoc)
%NOTEBOOK Open an m-book in Microsoft Word (Windows only). 
%   NOTEBOOK, by itself, launches Microsoft Word and creates a new m-book
%   called "Document 1."
%
%   NOTEBOOK(FILENAME) launches Microsoft Word and opens the m-book
%   FILENAME.
%
%   NOTEBOOK('-SETUP') runs an interactive setup function for the Notebook.
%   The user is prompted for the version of Microsoft Word and the
%   locations of several files.
%
%   NOTEBOOK('-SETUP', WORDVER, WORDLOC, TEMPLATELOC) sets up the
%   Notebook using the specified information.  WORDVER is the version
%   of Microsoft Word (one of '95' or '97'), WORDLOC is the directory
%   containing winword.exe, and TEMPLATELOC is a Microsoft Word template
%   directory.
%   
%   Examples:
%      notebook
%      notebook c:\documents\mymbook.doc
%      notebook -setup
%
%      For the case in which Microsoft Word 97 (winword.exe) resides in the
%      C:\Program Files\Microsoft Office 97\Office
%      directory, and the Microsoft Word templates reside in the
%      C:\Program Files\Microsoft Office 97\Templates directory:
%
%      wordver = '97';
%      wordloc = 'C:\Program Files\Microsoft Office 97\Office';
%      templateloc = 'C:\Program Files\Microsoft Office 97\Templates';
%      notebook('-setup', wordver, wordloc, templateloc)

%   Copyright (c) 1984-98 by The MathWorks, Inc.
%   $Revision: 1.12 $

% Determine how many input arguments were passed in, and act accordingly.
switch (nargin)
case(0)
   % Create a new m-book
   % First, get the information from matlab.ini, and verify that it is correct.
   [wordPath, wordTempPath] = getAndVerifyNotebookProfl;
   % Then, create the blank m-book
   dos(['"' wordPath '\winword.exe " ' '"'wordTempPath, ...
         '\m-book.dot" ' '/mmwNewNotebookFromCmdLine&']);
case(1)
   % Two options:
   % The user wants of run an existing m-book, or wants to go into
   % interactive setup mode.
   if ~strcmp(lower(fileName), '-setup')
      % Open an exiting m-book
      % First, make sure that the specified file exists.  If not, error and tell
      % the user.
      if ~exist(fileName)
         error(['The specified notebook, ''', fileName, ''' , does not exist.']);
      end
      % First, get the information from matlab.ini, and verify that it is correct.
      [wordPath, wordTempPath] = getAndVerifyNotebookProfl;
      % Then, open the specified file.
      dos(['"' wordPath '\winword.exe" "' fileName '"&']);
   else
      % Call notebookSetup with arguments, invoking it in interactive mode.
      notebookSetup
   end
case(2)
   % Invalid syntax
   error(['Invalid syntax for ' mfilename '.  See HELP ' upper(mfilename)]);
case(3)
   % Invalid syntax
   error(['Invalid syntax for ' mfilename '.  See HELP ' upper(mfilename)]);
case(4)
   % The user is attempting to set up Notebook non-interactively.
   % First, verify that the arguments are OK.
   if ~(strcmpi(fileName, '-setup') & isstr(wordLoc) & isstr(templateLoc))
      error(['Invalid syntax for ' mfilename '.  See HELP ' upper(mfilename)]);
   end
   if ~(strcmp(wordVer, '95') | strcmp(wordVer, '97'))
      error(['Invalid version of Microsoft Word specified.  Must be one of ',...
            '''95'' or ''97''']);
   end
   % Call notebookSetup with arguments, invoking it in non-interactive mode.
   notebookSetup(wordVer, wordLoc, templateLoc);
% Case > 4 will throw errors due to too many arguments.
end

%--------------------------------
function [wordPath, wordTempPath] = getAndVerifyNotebookProfl
% Get the relevant information from matlab.ini, and insofar as possible,
% validate it.  Only called if we're starting a notebook, not if we're
% in setup mode.

% get Word's startup path
wordPath = getprofl('Notebook Settings','Word path',...
   'c:\msoffice\winword', 'matlab.ini');

% get Word's template path
wordTempPath = getprofl('Notebook Settings','Word dot path',...
   'c:\msoffice\template','matlab.ini');

% Verify that the specified files exist.  If not, tell the user.
if ~exist(fullfile(wordPath, 'winword.exe')) | ...
      ~exist(fullfile(wordTempPath, 'm-book.dot'))
   error('Notebook has not been configured properly.  Please run notebook -setup');
end

%--------------------------------
function notebookSetup(wordVer, wordLoc, templateLoc)
% Master function for Notebook setup

% Get data that we can extract without any user interaction.
windir = getenv('windir');
if exist(fullfile(matlabroot, 'bin', 'matlab.exe'))
   matlab_path = fullfile(matlabroot, 'bin');
else
   if exist(fullfile(matlabroot, 'bin', 'nt', 'matlab.exe'))
      matlab_path = fullfile(matlabroot, 'bin');
   end
end
% If we are in interactive mode, get wordVer, wordLoc, and templateLoc
% If the user exercises a Cancel anywhere along the way, stop.
if nargin == 0
   disp([10 'Welcome to the utility for setting up the MATLAB Notebook']);
	disp(['for interfacing MATLAB to Microsoft Word' 10 10]);
   wordVer = getWordVer;
   if isnumeric(wordVer)
      return;
   end
   wordLoc = getWordLoc(wordVer);
   if isnumeric(wordLoc)
      return;
   end
   templateLoc = getTemplateLoc;
   if isnumeric(templateLoc)
      return;
   end
end
% Cannonicalize wordLoc, and check for existence of winword.exe.
% If it doesn't exist, inform the user that the setup is going
% poorly, and exit.
wordLoc(wordLoc == '/') = '\';
if wordLoc(end) == '\'
   wordLoc = wordLoc(1:end-1);
end
if ~exist(fullfile(wordLoc, 'winword.exe'))
   error(['Incorrect location specified for winword.exe.  Please run ', ...
         'notebook -setup again.']);
end
% Cannonicalize templateLoc.
templateLoc(templateLoc == '/') = '\';
if templateLoc(end) == '\'
   templateLoc = templateLoc(1:end-1);
end

% Make sure that neither of the locations that the user specified are UNC
% paths.  getprofl won't be able to handle that.
if strcmp(wordLoc(1:2), '\\') | strcmp(templateLoc(1:2), '\\')
   error(['Microsoft Word and the template directory must be on mounted drives.  ', 10,...
         'Their loctions may not be specified by UNC paths.']);
end

% Create the new M-Book template, and save changes to the matlab.ini file.
copyMBook(wordVer, templateLoc);
saveSettings(wordLoc, templateLoc, windir, matlab_path);

%--------------------------------
function wordVer = getWordVer
% Interactive query for version of Word, called from interactive setup mode.
% Keep asking until we get a valid response.

repeatQuery = 1;
while(repeatQuery)
   repeatQuery = 0;
   disp('Choose your version of Microsoft Word:');
	disp('[1] Microsoft Word for Windows 95 (Version 7.0)');
	disp('[2] Microsoft Word 97');
	disp(['[3] Exit, making no changes' 10]);
	wordVerNum = input('Microsoft Word Version: ');
	switch(wordVerNum)
	case(1)
   	wordVer = '95';
	case(2)
   	wordVer = '97';
   case(3)
      wordVer = 0;
   	return;
   otherwise
      repeatQuery = 1;
      disp([10 'Invalid selection' 10]);
   end
end

%--------------------------------
function wordLoc = getWordLoc(wordVer)
% Interactively query the user for the location of winword.exe from interactive
% setup mode.

disp([10 'You will be presented with a dialog box.  Please use it to select']);
disp(['your copy of the Microsoft Word ' wordVer ' executable (winword.exe).']);
disp('Press any key to continue...');
pause
[x, wordLoc] = uigetfile('winword.exe', ...
   ['Select your Microsoft Word ' wordVer ' executable (winword.exe)']);

%--------------------------------
function templateLoc = getTemplateLoc
% Interactively query the user for the location of a template directory from
% interactive setup mode.

disp([10 'You will be presented with a dialog box.  Please use it to']);
disp(['select a Microsoft Word template (.dot) file in one of your']);
disp('Microsoft Word template directories.  We suggest that you specify');
disp('your normal.dot file.');
disp('Press any key to continue...');
pause
[x, templateLoc] = uigetfile('*.dot', ...
   ['Select a Microsoft Word template file']);

%--------------------------------
function copyMBook(wordVer, templateLoc)
% Copy the appropriate (95, 97) m-book into the template directory while in
% setup mode.

% Decide which version to copy.
if strcmp(wordVer, '95')
   sourceFile = fullfile(matlabroot, 'notebook', 'pc', 'm-book95.dot');
else
   sourceFile = fullfile(matlabroot, 'notebook', 'pc', 'm-book.dot');
end

% If the source file doesn't exist, we need to have the user
% re-install it to the HD.
if ~exist(sourceFile)
   error([sourceFile ' does not exist.  Please re-install this file by re-installing MATLAB.']);
end
destFile = fullfile(templateLoc, 'm-book.dot');

% If destFile already exists, attempt to delete it.
if exist(destFile)
   origDir = pwd;
   cd(tempdir);
   x = dos(['attrib -R "' destFile '"']);
   cd(origDir);
   delete(destFile)
   if exist(destFile)
      error(['Could not delete ' destFile ' for replacement.', ...
            10 'You should delete it and run notebook -setup again.']);
   end
end
% Copy the surce file to the template directory as m-book.dot
copyfile(sourceFile, destFile);

%--------------------------------
function saveSettings(wordLoc, templateLoc, windir, matlab_path)
% Make changes to matlab.ini to reflect the new state of things while in setup mode.

% Create a reference to the user's matlab.ini file
matlabini = fullfile(windir, 'matlab.ini');

% Open the existing matlab.ini file, read it, and close it.
fidOld = fopen(matlabini, 'rt');
contentsOld = fscanf(fidOld, '%c');
fclose(fidOld);
% We want to create a version of matlab.ini without the [Notebook Settings]
% key.  There are three cases to consider: [1] a key already exists, and
% there are keys following it that must be preserved.  [2] A key already
% exists, and it is the final key.  [3] There is no [Notebook Settings]
% key in the existing file.

% Does the old file contain a [Notebook Settings] section?
MSStartLoc = findstr(contentsOld, '[Notebook Settings]');
if ~isempty(MSStartLoc)
   % There was an old key.  Are there any keys after it?
   nextKey = findstr(contentsOld(MSStartLoc+1:end), '[');
   if ~isempty(nextKey)
      % There are further keys.  Where do they start?
      nextKeyStart = nextKey(1) + MSStartLoc;
      % Create the contents of the new file, by including the old contents
      % up to the [Notebook Settings] key and all keys that follow
      % [Notebook Settings].  This leaves us with the contents of the
      % old file, minus the [Notebook Settings] key.
      contentsNew = [contentsOld(1:MSStartLoc-1), ...
            contentsOld(nextKeyStart:end)];
   else
      % There was a [Notebook Settings] key, and it was the last key in the
      % file.  This means that we can simply truncate the contents of
      % the old file to remove this key.
      contentsNew = contentsOld(1:MSStartLoc-1);
   end
else
   % There was no old copy of the [Notebook Settings] key, so we don't have
   % to bother to strip it out.
   contentsNew = contentsOld;
end

% Attempt to delete matlab.ini
warnState = warning;
warning('off');
origDir = pwd;
cd(tempdir);
x = dos(['attrib -R "' matlabini '"']);
cd(origDir);
delete(matlabini);
warning(warnState);
% Did we suceed?  If not, inform the user and exit.
if exist(matlabini)
   error(['Could not make necessary changes to ', matlabini, '.', 10,...
         'Make sure that you have permission to change the file,',...
         10, 'and run notebook -setup again.']);
else
   % If we successfully deleted the old file, create a new, empty version
   % of the file.  Print the content from the old file that we want to retain,
   % and add in the (new?) [Notebook Settings] key.
   fidNew = fopen(matlabini, 'wt+');
   fprintf(fidNew, '%c', contentsNew);
   % In the process of stripping the keys out, we may have stripped out the
	% final carridge return.  If so, replace it.
   if contentsNew(end) ~= char(10)
   	fprintf(fidNew, '\n');
	end
   fprintf(fidNew, '%c', '[Notebook Settings]');
   fprintf(fidNew, '\n');
   fprintf(fidNew, '%c', ['Word path=' wordLoc]);
   fprintf(fidNew, '\n');
   fprintf(fidNew, '%c', ['Word dot path=' templateLoc]);
   fprintf(fidNew, '\n');
   fprintf(fidNew, '%c', ['matlab-path=' matlab_path]);
   fprintf(fidNew, '\n');
   fclose(fidNew);
   disp([10 'Notebook setup is complete.' 10]);
end