% LTPDAWORKBENCH creates a new LTPDA Workbench.
%
% CALL:
%         >> LTPDAworkbench
%         >> wb = LTPDAworkbench  % returns a handle to the object
%
% M Hewitson 23-11-08
%
% $Id: LTPDAworkbench.m,v 1.52 2011/02/22 15:47:04 hewitson Exp $
%

%         >> wb = LTPDAworkbench('foo.lwb') % load a workbench from file
%         >> wb = LTPDAworkbench('foo.m')   % Create a workbench with a
%                 pipeline constructed from the M-file of LTPDA commands.
%         >> wb = LTPDAworkbench(objs) % create a workbench with one
%                 pipeline for each of the objects.


classdef LTPDAworkbench < handle
  %------------------------------------------------
  %---------- Private read-only Properties --------
  %------------------------------------------------
  properties (SetAccess = public)
    mp   = [];
    name = '';
    executing = false;
    UUID = [];
  end
  
  %-----------------------------------------
  %  Public methods
  %-----------------------------------------
  methods
    
    % Construct a new workbench
    function wb = LTPDAworkbench(varargin)
      
%       c = mfilename('fullpath');
%       d = fileparts(c);
%       % add jar file to the java path
%       mpipelineJar = fullfile(d, 'MPipeline.jar');
%       javaaddpath(mpipelineJar);
      
      twb = [];
      twb = getappdata(0, 'LTPDAworkbench');
      wb.UUID = ['LWB_' num2str(round(cputime.*100))];
      
      if isa(twb, 'LTPDAworkbench')
        
        disp('*** Found existing workbench.')
        wb = twb;
        awtinvoke(wb.mp, 'setVisible', 'true');
        
      else
        
        wfile = which(mfilename);
        [path, name, ext] = fileparts(wfile);
        libpath = fullfile(path, '');
        libfile = fullfile(libpath, 'lib.mat');
        
        switch nargin
          case 0
            % Create a new LTPDAworkbench
            prefs = getappdata(0, 'LTPDApreferences');
            wb.mp = awtcreate('mpipeline.main.MainWindow', 'Ljava.lang.String;Lmpipeline.ltpdapreferences.LTPDAPreferences;', prefdir, prefs);
            if isempty(wb.mp)
              error('Failed to create the workbench java object. Contact your nearest LTPDA developer.');
            end
            pause(0.1);
            % load library 'lib'
            try
              in = load(libfile);
              % set library
              awtinvoke(wb.mp, 'setLibrary', in.lib);
%               javaMethodEDT('setLibrary', wb.mp, in.lib);
              pause(0.1);
            catch
              warning('!!! Can''t open library, rebuilding it');
              lib = wb.rebuildLibrary();
              pause(0.1);
              save(libfile, 'lib')
            end
            
            % Set the repository manager to the workbench
            rm = LTPDARepositoryManager();
            awtinvoke(wb.mp, 'setRepositoryManager', rm.manager);
%             javaMethodEDT('setRepositoryManager', wb.mp, rm.manager);
            pause(0.1);
            
            % refresh library tree
            awtinvoke(wb.mp, 'refreshLibraryTree');
%             javaMethodEDT('refreshLibraryTree', wb.mp);
            pause(0.1);
            
            % set instance identifier to the workbench
            awtinvoke(wb.mp, 'setInstanceIdentifier', wb.UUID);
%             javaMethodEDT('setInstanceIdentifier', wb.mp, wb.UUID);
            pause(0.1);
            
            % Set the instance identifier
            awtinvoke(wb.mp, 'setInstanceIdentifier', wb.UUID);
            
            % Show the workbench
            awtinvoke(wb.mp, 'setVisible', 'true');
%             javaMethodEDT('setVisible', wb.mp, true);
            pause(0.1);
            
            
            
        end
        
        %%%%%%%%%%   Controls-tab (main) buttons   %%%%%%%%%%
        
        %--- Run button
        h = handle(wb.mp.getRunBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_runPipeline});
        
        %--- Stepforward button
        h = handle(wb.mp.getStepForwardBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_stepForward});
        
        %--- Stepbackward button
        h = handle(wb.mp.getStepBackwardsBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_stepBackwards});
        
        %--- Skipforward button
        h = handle(wb.mp.getSkipForwardBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_skipForward});
        
        %--- Reset button
        h = handle(wb.mp.getResetBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_reset});
        
        %%%%%%%%%%   Controls-tab (helper) buttons   %%%%%%%%%%
        
        %----Save objects button
        h = handle(wb.mp.getSaveObjectBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_saveObjects});
        
        %---- Export to WS button
        h = handle(wb.mp.getExportWorkspaceBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_exportWS});
        
        %--- Explore button
        h = handle(wb.mp.getExploreBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_explore});
        
        %--- Plot button
        h = handle(wb.mp.getPlotBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_plot});
        
        %---- Plot history of selected object button
        h = handle(wb.mp.getHistoryBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_plotHistory});
        
        %---- Display selected objects to terminal button
        h = handle(wb.mp.getDisplayBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_display});
        
        %----Table button
        h = handle(wb.mp.getTableBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_table});
        
        %----Report
        h = handle(wb.mp.getReportBtn, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_report});
        
%         %---- Verbosity combo
%         h = handle(wb.mp.getVebosityCombo, 'callbackproperties');
%         set(h, 'ActionPerformedCallback', {@wb.cb_changeVerbosity});
        
        %%%%%%%%%%   'Tools' Menu   %%%%%%%%%%
        
        %---- 'Plot selected' menu item
        h = handle(wb.mp.getPlotSelectedMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_plot});
        
        %---- 'Explore selected' menu item
        h = handle(wb.mp.getExploreSelectedMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_explore});
        
        %---- 'LTPDA Preferences' menu item
        h = handle(wb.mp.getLtpdaPreferencesMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_launchLTPDApreferences});
        
        %---- 'LTPDA Repository GUI' menu item
        h = handle(wb.mp.getLtpdaRepoGuiMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_launchRepogui});
        
        %---- 'Spectral Window Viewer' menu item
        h = handle(wb.mp.getLtpdaSpecwinViewerMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_launchSpecwinViewer});
        
        %---- 'Object Constructor Helper' menu item
        h = handle(wb.mp.getLtpdaConstructorHelperMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_launchConstructor});
        
        %---- 'LTPDA Signal Builder' menu item
        h = handle(wb.mp.getLtpdaSignalBuilderMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_launchSigBuilder});
        
        %---- 'Rebuild LTPDA Library' menu item
        h = handle(wb.mp.getRebuildLibraryMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_rebuildLibrary});
        
        %%%%%%%%%%   'Pipeline' Menu   %%%%%%%%%%
        
        %---- Export pipeline to terminal item
        h = handle(wb.mp.getExportToTerminalMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_export2terminal});
        
        %---- Export pipeline to m-file
        h = handle(wb.mp.getExportToMFileMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_export2mfile});
        
        %%%%%%%%%%   'Help' Menu   %%%%%%%%%%
        
        %---- Block Doc
        h = handle(wb.mp.getHelpBlockDocMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_blockdoc});
        
        %%%%%%%%%%   'File' Menu   %%%%%%%%%%
        
        %----Run execution plan
        h = handle(wb.mp.getPlanRunMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_executePlan});
        
        %----Import from objects
        h = handle(wb.mp.getWBOpenFromObjectMenuItem, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_importWBfromObjects});
        
        %---- Import pipeline from M-file
        h = handle(wb.mp.getImportFromMfileMenuItem, 'callbackproperties');
%         set(h, 'ActionPerformedCallback', {@wb.cb_importFromMfile});
        
        %---- Import pipeline from workspace
        h = handle(wb.mp.getImportFromWorkspaceMenuItem, 'callbackproperties');
%         set(h, 'ActionPerformedCallback', {@wb.cb_importFromWorkspace});
        
        %%%%%%%%%%   Repository buttons    %%%%%%%%%%
        
        %----Submit to workspace
        h = handle(wb.mp.getRepoSubmitTBB, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_submitObjects});
        
        %----Open repository manager
        h = handle(wb.mp.getRepoConnectTBB, 'callbackproperties');
        set(h, 'ActionPerformedCallback', {@wb.cb_openRepoManagerGUI});
        
        %%%%%%%%%%   other    %%%%%%%%%%
        
        %--- called when window is closed
        h = handle(wb.mp, 'callbackproperties');
        set(h, 'WindowClosedCallback', {@wb.cb_guiClosed});
        set(h, 'PropertyChangeCallback', {@wb.cb_applyprefs});
        
        % set the spectral window types
        wtl = wb.mp.getWindowTypes();
        wtl.clear();
        winTypes = specwin.getTypes;
        for kk=1:numel(winTypes)
          wtl.add(winTypes{kk});
        end
        
        % create progress bar when loading built-in models
        pd = mpipeline.dialogs.ProgressDialog(wb.mp, false, 'starting', 1);
        warning('off', 'MATLAB:JavaEDTAutoDelegation')
        pd.setTitle('Uploading built-in models...');
        pd.setVisible(true);
        warning('on', 'MATLAB:JavaEDTAutoDelegation')
        
        amdls = wb.mp.getBuiltinModels('');
        amdls.clear();
        cls = utils.helper.ltpda_userclasses;
        for jj=1:numel(cls)
          cl = cls{jj};
          if ~any(strcmp(cl, {'plist'}))
            mdls = eval([cl '.getBuiltInModels;']);
            pd.setMessage(['Adding ' cl ' models']);
            pd.setMaxValue(size(mdls,1));
            pd.setValue(0);
            for kk=1:size(mdls,1)
              pd.increment();
              htxt = help([cl '_model_' mdls{kk,1}]);
              pl = [];
              try
                pl = eval([cl '_model_' mdls{kk,1} '(''plist'')']);
              end
              if ~isa(pl, 'plist')
                pl = plist;
              end
              try
                wb.mp.addBuiltInModel(cl, mdls{kk,1}, ['<html><p>' htxt '</p></html>'], LTPDAworkbench.mpl2jpl(pl))
              catch err
                fprintf(2, '\n### Failure in uploading the model %s.\n\n', mdls{kk,1});
              end
            end
          end
        end
        % get rid of progress bar
        pd.dispose();
        clear pd;
        
        % Set LTPDA prefs
%         pl = LTPDAprefs.getPrefsPlist();
%         wb.mp.uploadLtpdaPreferences(LTPDAworkbench.mpl2jpl(pl));
        
        % Set units
        units = unit.supportedUnits;
        prefixes = unit.supportedPrefixes;
        wb.mp.clearUnits;
        wb.mp.clearPrefixes;
        for ii=1:numel(units)
          wb.mp.addUnit(units{ii});
        end
        for ii=1:numel(prefixes)
          wb.mp.addPrefix(prefixes{ii});
        end
        
        
        % set working directory
        wb.mp.setWorkingDir(pwd);
        
      end
      
%       setappdata(0, 'LTPDAworkbench', wb);
    end % End constructor
    
  end % End public methods
  
  methods (Access=public)
    varargout = addErrorMessage(varargin)
    varargout = addMessage(varargin)
    varargout = addWarningMessage(varargin)

    % Display method to make a quiet output
    function display(varargin)
      wb = varargin{1};
    end
  end
  
  methods(Access=private)
    
    % Controls tab (main) buttons
    varargout = cb_runPipeline(varargin)
    varargout = cb_stepForward(varargin)
    varargout = cb_skipForward(varargin)
    varargout = cb_stepBackwards(varargin)
    varargout = cb_reset(varargin)
    
    % Controls tab (helper) buttons
    varargout = cb_saveObjects(varargin)
    varargout = cb_exportWS(varargin)
    varargout = cb_explore(varargin)
    varargout = cb_plot(varargin)
    varargout = cb_plotHistory(varargin)
    varargout = cb_display(varargin)
    varargout = cb_table(varargin)
    varargout = cb_report(varargin)
    varargout = cb_changeVerbosity(varargin)
    
    % 'Tools' Menu
    varargout = cb_launchLTPDApreferences(varargin)
    varargout = cb_launchRepogui(varargin)
    varargout = cb_launchSpecwinViewer(varargin)
    varargout = cb_launchConstructor(varargin)
    varargout = cb_launchSigBuilder(varargin)
    varargout = cb_rebuildLibrary(varargin)
    
    % 'Pipeline' Menu
    varargout = cb_export2terminal(varargin)
    varargout = cb_export2mfile(varargin)
    
    % 'File' Menu
    varargout = cb_importFromMfile(varargin)
    varargout = cb_importFromWorkspace(varargin)
    varargout = cb_executePlan(varargin)
    varargout = cb_importWBfromObjects(varargin)
    
    % 'Help' Menu
    varargout = cb_blockdoc(varargin)
    
    % Repository Buttons
    varargout = cb_submitObjects(varargin)
    varargout = cb_openRepoManagerGUI(varargin)
    
    % other
    varargout = cb_guiClosed(varargin)
    varargout = cb_applyprefs(varargin);
    
  end
  
  methods (Static=true)
    
    varargout = getWS_VarName(varargin);
    
    varargout = parseBlocks(varargin);
    varargout = clearBlockVariables(varargin);
    varargout = executeCommands(varargin)
    varargout = executeConstants(varargin)
    varargout = run(varargin)
    
    varargout = mpl2jpl(varargin)
    varargout = jpl2mpl(varargin)
    varargout = parseCmd(varargin)
    varargout = rebuildLibrary(varargin);
    
  end
  %------------------------------------------------
  % Private static methods
  %------------------------------------------------
  methods(Access=private, Static=true)
    varargout = minfo2algo(varargin)
    varargout = parse(varargin)
  end
  
end

