% MAKETOOLBOX Create the toolbox 'ltpda'.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DESCRIPTION: MAKETOOLBOX Create the toolbox 'ltpda'.
%              This script will package together all files into a toolbox that
%              can be distributed for various OS's.
%
% CALL:        makeToolbox
%
% VERSION:     $Id: makeToolbox.m,v 1.182 2011/05/18 06:48:07 hewitson Exp $
%
% HISTORY: 30-01-07 M Hewitson
%             Creation
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function varargout = makeToolbox(varargin)

  %% Some clearing

  % remove the user preferences
  setappdata(0, 'LTPDApreferences', '');
  % now clear everything
  evalin('base', 'clear');
  
  %% Settings

  % install toolbox to this directory
  if nargin == 1
    rootdir = varargin{1};
  else
    rootdir = '/Users/hewitson/working/matlab';
  end

  % compile options
  closedSource    = 0;       % 1 => compile all .m files to .p files
  read_only       = 0;       % Make all installed files read-only? (except ltpda_startup.m)

  % copy the help files to the installed toolbox
  install_help                = true;
  % install the examples and tests
  install_examples            = true;
  
  % Run the python script to build the html help
  build_help                  = false;
  % build the documentation search database
  build_doc_search            = false;  
  % build the page of functions by category,
  build_functions_by_category = false;
  
  % rebuild workbench library
  rebuild_workbench_library   = false;
  
  % set version for the Contents.m and for packaging
  ltpda_ver       = '2.4.dev';

  %% ------------------------------------------------------------------------
  % -------------------------------------------------------------------------
  % -------------------------------------------------------------------------
  % -------------------------------------------------------------------------
  % Should not need to edit below here
  % -------------------------------------------------------------------------
  % -------------------------------------------------------------------------
  % -------------------------------------------------------------------------
  % -------------------------------------------------------------------------

  mpipelineSrc    = 'MPipeline2';
  makeDoc         = 0;       % make html doc for all m files using m2html, ref: http://www.artefact.tk/software/matlab/m2html/
  
  % build version string
  mver      = ver('MATLAB');
  ltpda_version = sprintf('%s %s %s', ltpda_ver, mver.Release, datestr(now, 'dd-mm-yy'));

  % build OS target directory
  toolboxRoot = fullfile(rootdir, 'ltpda_toolbox');
  
  % remove toolbox from matlab path
  rmpath(genpath(toolboxRoot));
  savepath;
  rehash toolboxcache;
  
  % delete old toolbox
  if exist(toolboxRoot, 'dir')
    rmdir(toolboxRoot, 's');
  end
  
  % create toolbox root
  mkdir(toolboxRoot);

  % create toolbox dir
  toolboxDir = fullfile(rootdir, sprintf('ltpda_toolbox'), 'ltpda');
  mkdir(toolboxDir);

  %% Install latest jar files

  % ConnectionManager
  copyfile(fullfile('..', 'src', 'ConnectionManager', 'dist', 'ConnectionManager.jar'), fullfile('jar', 'ConnectionManager.jar'));
  
  % MPipeline
  copyfile(fullfile('..', 'src', mpipelineSrc, 'dist', [mpipelineSrc '.jar']), fullfile('jar', 'MPipeline.jar'));
  ddir = fullfile('jar', 'lib');
  if ~exist(ddir, 'dir')
    mkdir(ddir);
  end
  copyfile(fullfile('..','src',mpipelineSrc,'dist','lib'), ddir, 'f');

  % login dialog
  copyfile(fullfile('..', 'src', 'LoginDialog', 'dist', 'LoginDialog.jar'), fullfile('jar', 'LoginDialog.jar'));

  mkdir(toolboxDir, 'jar');
  jars = dir('jar');
  for c = 1:numel(jars)
    s = jars(c);
    [path, name, ext] = fileparts(s.name);
    if strcmp(ext, '.jar')
      copyfile(fullfile('jar', s.name), fullfile(toolboxDir, 'jar'), 'f');
    end
  end

  % Also the lib dir for MPipeline
  mkdir(toolboxDir, fullfile('jar', 'lib'));
  copyfile(fullfile('jar', 'lib'), fullfile(toolboxDir, 'jar', 'lib'), 'f');

  %% copy m files

  srcs = {'m/etc/', ...
    'm/gui', ...
    'm/helper', ...
    'm/sigproc',...
    'm/built_in_models'};

  mkdir(toolboxDir, 'm');

  for s=srcs
    copyfile(char(s), fullfile(toolboxDir, char(s)), 'f');
  end

  % Copy some other files
  copyfile('m/MakeContents.m', toolboxDir, 'f');

  %% install classes

  classes = {'ltpda_obj', 'ltpda_nuo', 'ltpda_uo', 'ltpda_uoh', ...
    'minfo', 'unit', ...
    'pz', 'pzmodel', 'rational', 'parfrac',...
    'ltpda_tf', 'ltpda_filter', 'miir', 'mfir', 'filterbank', ...
    'ltpda_data', 'data2D', 'data3D', 'tsdata', 'cdata', 'xydata', 'fsdata', 'xyzdata', ...
    'provenance', 'history', 'param', 'paramValue', 'plist',...
    'ao', 'specwin', 'time', 'timespan',...
    'pest', ...
    'ssm', 'ssmport', 'ssmblock', ...
    'smodel', 'msym',  ...
    'sigBuilder', 'constructor', 'specwinViewer', ...
    'LTPDAprefs', 'LTPDAworkbench', 'LTPDADatabaseConnectionManager', 'workspaceBrowser', ...
    'LTPDAModelBrowser', ...
    'matrix', 'collection', ...
    };

  for c = classes
    cdir = fullfile('classes', sprintf('@%s', char(c)));
    mkdir(toolboxDir, cdir);
    copyfile(cdir, fullfile(toolboxDir, cdir), 'f');
  end

  %% install unit tests
  
    cdir = fullfile('classes', 'tests');
    mkdir(toolboxDir, cdir);
    copyfile(cdir, fullfile(toolboxDir, cdir), 'f');
  
  
  %% install packages

  pkgs = { 'utils'};
  for c = pkgs
    cdir = fullfile('classes', sprintf('+%s', char(c)));
    mkdir(toolboxDir, cdir);
    copyfile(cdir, fullfile(toolboxDir, cdir), 'f');
  end

  %% Install mex src files

  srcs = {'c_sources', 'ltpda_dft', 'ltpda_smoother', 'ltpda_polyreg', 'ltpda_ssmsim'};
  for c = srcs
    cdir = fullfile('src', char(c));
    mkdir(toolboxDir, cdir);
    copyfile(fullfile('../', cdir), fullfile(toolboxDir, cdir), 'f');
  end
  % Copy compileAll.m
  copyfile('../src/compileAll.m', fullfile(toolboxDir, 'src'), 'f')
  copyfile('../src/vcredist_x86.exe', fullfile(toolboxDir, 'src'), 'f')
  copyfile('../src/vcredist_x64.exe', fullfile(toolboxDir, 'src'), 'f')


  %% Now build examples directory in toolbox

  if install_examples
    % load list of tests to install
    run 'test/test_list.m';
    
    mkdir(toolboxDir, 'examples');
    installPoint = fullfile(toolboxDir, 'examples');
    for f = 1:length(test_struct)
      if test_struct(f).example
        disp(sprintf('  - installing %s', test_struct(f).name));
        copyfile(fullfile('test', [test_struct(f).name '.m']), installPoint);
      end
    end

    % Some additional files
    copyfile(fullfile('test', 'test_list.m'), installPoint);
    copyfile(fullfile('test', 'run_tests.m'), installPoint);
    copyfile(fullfile('test', 'make_test_ascii_file.m'), installPoint);

    mkdir(installPoint, 'pipelines');
    copyfile(fullfile('test', 'pipelines'), fullfile(installPoint, 'pipelines'), 'f');
  end
  
  %% Clean up
  % Remove recursive the CVS directories in toolboxDir
  rm_cvs_dir(toolboxRoot, 'CVS');
  rm_cvs_dir(toolboxRoot, '*.m~');
  rm_cvs_dir(toolboxRoot, '.#ltpda*');

  % add toolbox to matlab path
  addpath(genpath(toolboxRoot));
  
  %% Now build Contents.m files and documentation

  cdir = pwd;
  cd(toolboxDir);
  MakeContents('LTPDA', ltpda_version);
  cd(cdir);

  if makeDoc
    % Build doc list
    docs = [];
    for jj = 1:length(classes)
      docs = [docs cellstr(['classes/@' classes{jj}])];
    end
    for jj = 1:length(srcs)
      if ~strcmp(srcs{j}, 'mex')
        docs = [docs cellstr(srcs{jj})];
      end
    end

    % build documentation
    m2html('mfiles', docs,...
      'htmldir', 'html_help/help/ug',...
      'recursive', 'on',...
      'template', 'docstyle',...
      'indexFile', 'mindex');
  end

  if build_help
    % Make on-line html TOC
    cd html_help/help
    convertTOC
    % try to generate html codes
    try
      [temp pythonVer] = system('python -V');
      pythonVer = strtok(pythonVer,'Python ');
      if numel(pythonVer)>3, pythonVer(4:end)=[]; end
      pythonVer = str2double(pythonVer);
      if isnan(pythonVer)
        error('*** Failed check of Python version');
      elseif pythonVer > 2.6
        !python ./mkhelpfiles_v3.py -i helptoc.xml
      else
        !python ./mkhelpfiles.py -i helptoc.xml
      end
    catch ME
      warning('!!! Couldn''t run mkhelpfiles.py. Do you have python installed?');
    end
    cd(cdir)
    
  end
  
  % Now copy the help files
  if install_help
    status = copyfile('html_help/help', fullfile(toolboxDir,'help'), 'f')
    copyfile('html_help/info.xml', toolboxDir, 'f');
    addpath(fullfile(toolboxDir, 'help', 'ug'));
    delete(fullfile(toolboxDir,'help','ug', '*_content.html'))
  end
  
  % Now build search index
  if build_doc_search
    builddocsearchdb(fullfile(toolboxDir, 'help'))
  end
  
  % Now everything is copied so we can save the path.
  savepath;
  rehash toolboxcache;


  %% Build functions by category
  if build_functions_by_category
    disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
    disp('%%          running mk_functions_by_category       %%');
    disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
    mk_functions_by_category;
  end
  
  %% Make all files read-only
  if read_only
    files = mtfilescan(toolboxRoot);
    for jj = 1:length(files)
      fi = files{jj};
      [path,name,ext] = fileparts(fi);
      if ~strcmp(name, 'ltpda_startup')
        if ispc
          [success, message, messageid] = fileattrib(fi, '-w');
        else
          [success, message, messageid] = fileattrib(fi, '-w', 'a');
        end
        if ~success
          warning('!!! Failed to set attributes for %s', fi);
        end
      end
    end
  end

  %% Now compile all .m files and remove if necessary
  if closedSource
    mfiles = mtfilescan(toolboxDir, '.m');
    for ii = 1:length(mfiles)
      f = char(mfiles(ii));
      pcode(f, '-inplace');
      writeHelpMfile(f)
    end
  end

  %% Now clean up

  % Remove recursive the CVS directories in toolboxDir
  rm_cvs_dir(toolboxRoot, 'CVS');
  rm_cvs_dir(toolboxRoot, '*.m~');
  rm_cvs_dir(toolboxRoot, '.#ltpda*');
  
  rehash;
  rehash toolboxcache;
  ltpda_startup;
  
  if rebuild_workbench_library
    lib = LTPDAworkbench.rebuildLibrary;
    save(fullfile(toolboxRoot, 'ltpda', 'classes', '@LTPDAworkbench', 'lib.mat'), 'lib')
  end

end


function writeHelpMfile(mfile)
  % This replaces an m-file with another m-file that contains only the help
  % of the original one

  
  % get the help
  [pathstr,name,ext] = fileparts(mfile);
  h = help(name);
  disp(sprintf('** Writing help m-file for %s', name));

  fd = fopen(mfile, 'w+');
  fprintf(fd, '%s', h);
  fclose(fd);
end

function files = mtfilescan(root_dir, ext)
  % Recursively scans the given directory for files that end in
  % 'ext' and returns a list of the full paths. 

  if nargin < 2
    ext = '';
  end
  
  files = getfiles(root_dir, ext, []);
end


function ofiles = getfiles(root_dir, iext, ofiles)
  % Recursive function for getting file lists
   
  files = dir(root_dir);

  for jj = 1:length(files)
    f = files(jj);
    if f.isdir
      if ~strcmp(f.name,'.') && ~strcmp(f.name,'..')
        ofiles = getfiles([root_dir '/' f.name], iext, ofiles);
      end
    else
      [pathstr,name,ext] = fileparts(f.name);
      if ~isempty(iext)
        if any(strcmp(ext, iext))
          ofiles = [ofiles; cellstr([root_dir '/' f.name])];
        end
      else
        ofiles = [ofiles; cellstr([root_dir '/' f.name])];
      end
    end
  end
end

% END
