%% MNMINIT Open a Matlab/NeXtMidas connection
%
% Setup the Matlab NeXtMidas handle. This will expose all the NeXtMidas
% commands so that they may be called from Matlab. This function will read
% the nmstartup scripts in both the user directory and the NeXtMidas
% system directory. This will setup all the AUX'es and Option Trees just 
% as NeXtMidas would.
%
% Syntax
% handle = nminit()
% 
% Output Arguments
% handle - NeXtMidas handle
% 
% Example
% nmhand = nminit();
% nmhand.runCommand('say "hello, world!"');
%
function handle = nminit ( )
  % get root paths
  nmroot = getenv('ICEROOT');
  if ( isempty(nmroot) ) 
    disp('ERROR, NMROOT environment variable does not exist. Please set it');
    return
  end
  % get home directory
  home = getenv('HOME');
  if ( isempty(home) ) 
    disp('ERROR, HOME environment variable does not exist. Please set it');
    return
  end
  % javaaddclass clears all workspace variables; therefore, save vars
  vname = [home,'/cur_',datestr(now,'yyyymmdd_HHMMSS'),'.mat'];
  save(vname);
  % We are going to try to save the class paths (option trees) into a
  % hidden file. Matlab has some quirks about it that prevent adding
  % classpaths if a java handle is open. So we're going to open all the
  % known class paths. Then we'll read in the nmstartup files. If an new
  % option tree is detect, we'll have to close the java handle and add the
  % new class paths.
  fname = [home,'/.mnmpaths.mat'];
  cpaths = [];
  if ( exist(fname, 'file') == 2 ) 
    % file exists, load it
    load(fname);
    nonative_ = 'false';
    reload = false;
    ci = length(cpaths);
  else
    cdir = dir([nmroot, '/jre/*.jar']);
    len = length(cdir);
    cpaths = {nmroot};
    ci = 1;
    for m=1:len
      ci = ci + 1;
      cpaths(ci) = {[nmroot, '/jre/', cdir(m).name]};
    end
    nonative_ = 'true'; 
    reload = true;
  end  
  % add the classpaths (nmroot have to be last)
  for m=1:length(cpaths)
    nmAddPath(char(cpaths(m)));
  end
  % setup NeXtMidas
  handle = openHandle(nmroot, home, nonative_);
  % grab all the option tree paths
  npaths = handle.getNmOpts();
  % detect if any option tree's got added and handle needs to be re-loaded
  for m=1:length(npaths)
    found = false;
    for n=1:length(cpaths)
      if ( strcmp(char(npaths(m)), char(cpaths(n))) ) 
        found = true;
        break;
      end
    end
    if ( found == false ) 
      reload = true;
      ci = ci + 1;
      cpaths(ci) = {char(npaths(m))};
    end
  end  
  % check for a re-load
  if ( reload )
    % close handle (avoid quirky-ness)
    handle.close();
    clear handle;
    % load class paths
    for m=1:length(cpaths)
      nmAddPath(char(cpaths(m)));
    end
    % re-open the handle
    handle = openHandle(nmroot, home, 'false');
    % save    
    save(fname, 'cpaths', '-mat');
  end
  % reload vars
  load(vname);
  delete(vname);
  
end

function handle = openHandle ( nmroot, home, nonative_ )
  % init the handle
  handle = javaObject('nxm.sys.lib.MatLab', nmroot, home, nonative_);
  if ( ~handle.isOpen() )
   % open handle
   handle.open();
    % make sure it is open 
    if ( ~handle.isOpen() ) 
      disp('ERROR, Could not open NeXtMidas handle');
      return;
    end
  end  
end

function pexists = nmAddPath( path )
  % get the dynamic classpaths
  cpath = javaclasspath('-dynamic');
  pexists = false;
  % check if the classpath has been added
  for m=1:length(cpath)
    if ( strcmp(cpath{m}, path) )
      pexists = true;
      break;
    end
  end
  % add path if it didn't exist
  if ( ~pexists  ) 
    % add to the class path
    javaaddpath(path);
  end
end
