function cmdlist

% A simple test GUI for generating a command list
%
% Explore the idea to generate a command list - each command has
% configurable inputs and outputs
%


%% Some initial setup
versions = {};
ltpda_versions;

Gproperties.Gcol    = [240 240 240]/255;
Gproperties.Gwidth  = 800;
Gproperties.Gheight = 600;
Gproperties.Gborder = 10;
fontsize = getappdata(0, 'ltpda_repo_gui_fontsize');

Gproperties.Screen   = get(0,'screensize');
Gproperties.Gposition = [150 ...
  150 ...
  Gproperties.Gwidth...
  Gproperties.Gheight];

%  Initialize and hide the GUI as it is being constructed.
mainfig = figure('Name', 'Script Builder',...
  'NumberTitle', 'off',...
  'Visible','off',...
  'Position',Gproperties.Gposition,...
  'Color', Gproperties.Gcol,...
  'Toolbar', 'none',...
  'Resize', 'off',...
  'ToolBar',      'none',           ...
  'NextPlot',     'new',            ...
  'HandleVisibility', 'callback', ...
  'MenuBar', 'none',...
  'Tag', 'ltpdaCmdList');

setappdata(mainfig, 'commands', {});

% Add command table to JScrollPane

data    = {};
cnames = {'output', 'command', 'inputs'};
columnformat = {'char', 'char', 'char'};
columneditable =  [true false false];

cmdtbl = uitable('Parent', mainfig,...
  'Units','normalized', ...
  'BackgroundColor',  [1 1 0.6; 1 1 1], ...
  'RowStriping', 'on', ...
  'ColumnName', cnames, ...
  'Fontsize', 14, ...
  'Data', data, ...
  'ColumnEditable', columneditable, ...
  'ColumnFormat', columnformat, ...
  'CellEditCallback', @cellChanged,...
  'CellSelectionCallback', {@cellEdit, mainfig},...
  'ButtonDownFcn', {@tblClick, mainfig},...
  'Tag', 'commandTable', ...
  'Position', [0.05 0.2 0.5 0.7]...
  );

get(cmdtbl)

setappdata(mainfig, 'cmdTable', cmdtbl);

cmenu = uicontextmenu('Parent', mainfig, 'Callback', {@setContext, mainfig});
% Define the line and associate it with the context menu
set(cmdtbl, 'UIContextMenu', cmenu);




% Add button
h = uicontrol(mainfig, 'Style', 'pushbutton', ...
  'String', 'Add',...
  'Units','normalized', ...
  'Position', [0.05 0.1 0.1 0.05],...
  'Callback', {@addCommand, mainfig});

% Build button
h = uicontrol(mainfig, 'Style', 'pushbutton', ...
  'String', 'Build',...
  'Units','normalized', ...
  'Position', [0.15 0.1 0.1 0.05],...
  'Callback', {@buildCommand, mainfig});

% Command panel
hpnl = uipanel(mainfig, ...
  'BackgroundColor', Gproperties.Gcol, ...
  'Position', [0.6 0.2 0.35 0.7]);

setappdata(mainfig, 'epanel', hpnl);

% data   = {'a2', 'ao', 'a1', 'E';...
%           'a3', 'ltpda_pwelch', 'a2', 'E';...
%           };

% Make the GUI visible.
set(mainfig,'Visible','on')

  function editCell(varargin)
    
    myh = varargin{1};
    mainfig = findobj('Tag', 'ltpdaCmdList');    
    scells = getappdata(mainfig, 'selectedCells');    
    cmds = getappdata(mainfig, 'commands');
    tbl = getappdata(mainfig, 'cmdTable');
    
    cols = unique(scells(:,2));
    edt  = get(tbl, 'ColumnEditable');
    edt(cols) = true;
    set(tbl, 'ColumnEditable', edt)
    
  end

  function setContext(varargin)


    cmenu   = varargin{1};
    mainfig = varargin{3};

    delete(get(cmenu, 'Children'));

    scells = getappdata(mainfig, 'selectedCells');
    
    if ~isempty(scells)
      % commands
      if all(scells(:,2)==2)
        buildCommandsMenu(cmenu)
      else
        % inputs
        buildInputsMenu(cmenu)
      end
    end % end of isempty
    item1 = uimenu(cmenu, 'Label', 'edit', 'Callback', @editCell);

  end

  function buildInputsMenu(cmenu)
    
    mainfig = findobj('Tag', 'ltpdaCmdList');    
    scells = getappdata(mainfig, 'selectedCells');
    cmds = getappdata(mainfig, 'commands');
    
    % get the outputs of all other lines above
    mc = min(scells(:,1))-1;
    if mc > 0
      outs = [];
      for k=1:mc
        cmds(k,1)
        if ~isempty(cmds{k,1})
          outs = [outs cmds(k,1)];
        end
      end
      outs = unique(outs);

      % Build menu
      for k=1:length(outs)
        o = outs{k};
        sitem1 = uimenu(cmenu, 'Label', o, 'Callback', @cmcallback);
      end
    end    
  end


  function buildCommandsMenu(cmenu)

    % Define the context menu items

    sitem1 = uimenu(cmenu, 'Label', 'classes');
    sitem2 = uimenu(cmenu, 'Label', 'other');

    % Classes sub items
    classes = ltpda_user_classes;
    for j=1:length(classes)
      cl = classes{j};
      ss = uimenu(sitem1, 'Label', cl);

      % Collect categories
      ms = methods(cl);
      cats = {};
      for k=1:length(ms)
        m = ms{k};
        if ~strcmp(m, 'Contents')
          ct = unique(versions(find(strcmp(versions(:,2), m)), 9));
          if ~isempty(ct) && ~any(strcmp(ct, 'Internal'))
            cats = [cats; ct];
          end
        end
      end % end categories loop
      cats = squeeze(unique(cats));

      % add categories
      for k=1:length(cats)
        if isempty(cats{k})
          c = 'unknown';
        else
          c = cats{k};
          sss = uimenu(ss, 'Label', c);
        end

        % Add methods
        thisClass = versions(strcmp(versions(:,10), cl), :);
        ms = thisClass(strcmp(thisClass(:, 9), c),2);
        for l=1:length(ms)
          m = ms{l};
          ssss = uimenu(sss, 'Label', m, 'Callback', @cmcallback);
        end

      end
    end % end classes loop
    
    % Other commands
    otherCommands = versions(strcmp(versions(:,10), 'None'),:);

    % category list
    cats = unique(otherCommands(:,9));    
    for j=1:length(cats)
      ct = cats{j};
      if ~strcmp(ct, 'Internal')
        if isempty(ct)
          ct = 'unknown';
        end
        sss = uimenu(sitem2, 'Label', ct);

        % Functions
        if strcmp(ct, 'unknown')
          cfs = otherCommands(strcmp(otherCommands(:,9), ''),2);
        else
          cfs = otherCommands(strcmp(otherCommands(:,9), ct),2);
        end
        for k=1:length(cfs)
          cf = cfs{k};
          ssss = uimenu(sss, 'Label', cf, 'Callback', @cmcallback);
        end

      end

    end    
  end

  function cmcallback(varargin)

    myh = varargin{1};    
    fcn = get(myh, 'Label');
    
    mainfig = findobj('Tag', 'ltpdaCmdList');    
    scells = getappdata(mainfig, 'selectedCells');    
    cmds = getappdata(mainfig, 'commands');
    
    for j=1:size(scells,1)
      
      row = scells(j,1);
      col = scells(j,2);
      
      cmds(row,col) = {fcn};
      
    end
    
    setappdata(mainfig, 'commands', cmds);
    setTable(mainfig);
    
  end


  function tblClick(varargin)

    myh     = varargin{1};
    cinfo   = varargin{2};
    mainfig = varargin{3};




  end

  function optCellSelect(varargin)

    myh     = varargin{1};
    cinfo   = varargin{2};
    mainfig = varargin{3};


    % get cell text
    idx = cinfo.Indices;
    row = idx(1);
    col = idx(2);
    d = get(myh, 'Data');
    cval = d{row,col};


  end

  function buildCommand(varargin)
    
    mainfig = varargin{3};
    
    cmds = getappdata(mainfig, 'commands');
    
    fname = [tempname '.m'];
    % get tmp filename
    fd = fopen(fname, 'w+');
    fprintf(fd, 'clear all; \n');
    
    for j=1:size(cmds,1)
      
      cm = cmds(j,:);   
      
      if ~isempty(cm{2})
        if isempty(cm{1})
          cmd = sprintf('%s(%s)', cm{2}, cm{3})
        else
          cmd = sprintf('%s = %s(%s)', cm{1}, cm{2}, cm{3})
        end
        fprintf(fd, '%s\n', cmd);
      end
    end
    fclose(fd);
    cmd = sprintf('run(''%s'')', fname)
    evalin('base', cmd)
    
    delete(fname)
    
  end

  function addCommand(varargin)

    mainfig = varargin{end};

    cmds = getappdata(mainfig, 'commands');
    outs = getOutputs(cmds);
    cmd  = {'', '', ''};

    cmds = [cmds; cmd];

    setappdata(mainfig, 'commands', cmds);

    setTable(mainfig);

  end

  function setTable(mainfig)

    cmds = getappdata(mainfig, 'commands');
    tbl  = findobj(mainfig, 'Tag', 'commandTable');
    outs = getOutputs(cmds);

    set(tbl, 'Data', cmds);

  end

  function cellChanged(varargin)

    tbl = varargin{1};
    edata = varargin{2};
    mainfig = get(tbl, 'Parent');
    cmds = getappdata(mainfig, 'commands');

    row = edata.Indices(1);
    col = edata.Indices(2);
    cmds{row,col} = edata.NewData;
    setappdata(mainfig, 'commands', cmds);

    setTable(mainfig)

    edt = get(tbl, 'ColumnEditable');
    edt(col) = false;
    set(tbl, 'ColumnEditable', edt);
    

  end

  function o = getOutputs(commands)

    o = {};



    % Go through each command and get outputs
    for j=1:size(commands,1)
      os = commands{j,1};
      a = strrep(strrep(regexp(os, ',', 'split'), '[', ''), ']', '');
      o = [o a];
    end

    if isempty(o)
      o = {''};
    end


  end

  function cellEdit(varargin)

    myh = varargin{1};
    edata = varargin{2};
    mainfig = varargin{end};

    tbl = getappdata(mainfig, 'optTable');

    setappdata(mainfig, 'selectedCells', edata.Indices);

    %     buildOptions(tbl);

  end

end

