classdef Icon < handle
  % Icon component.
  %
  % Example:
  %   filename = fullfile(matlabroot, 'toolbox', 'shared', 'controllib', 'general', 'resources', 'run_24.png');
  %   description = 'My icon';
  %
  %   icon = toolpack.component.Icon
  %   icon = toolpack.component.Icon(filename)
  %   icon = toolpack.component.Icon(filename, description)
  %
  % Common icons can be created through static method calls:
  %   icon = toolpack.component.Icon.NEW_24
  %
  % INTERNAL USE ONLY
  %   icon = toolpack.component.Icon(imageicon);
  %   icon = toolpack.component.Icon(imageicon, description);

  % Author(s): Bora Eryilmaz
  % Revised:
  % Copyright 2010-2016 The MathWorks, Inc.

  % ----------------------------------------------------------------------------
  properties (Dependent, Access = public)
    % Brief description of the icon (string, default = '')
    Description
  end

  properties (Hidden, Dependent, GetAccess = public, SetAccess = protected)
    % Component peer (read-only, default = empty ImageIcon)
    Peer
  end

  properties (Access = private)
    % An ImageIcon or [] for default value empty ImageIcon
    Peer_
  end

  properties (Constant, Hidden, Access = public)
    % Path to resources directory for icons
    Path = fullfile(matlabroot, 'toolbox', 'shared', ...
      'controllib', 'general', 'resources', 'toolstrip_icons');
  end

  % ----------------------------------------------------------------------------
  methods
    function this = Icon(filename, description)
      % Creates an icon component.
      if nargin == 0
        % Icon()
        this.Peer = [];
      elseif nargin == 1
        filename = controllib.internal.util.hString2Char(filename);
        if isempty(filename)
          % Icon([])
          this.Peer = [];  % javax.swing.ImageIcon([]) will hang command line!
        elseif ischar(filename)
          if exist(filename, 'file')
            % Icon(filename)
            this.Peer = javax.swing.ImageIcon(filename);
          else
            error(message('Controllib:toolpack:CannotLocateFile', filename));
          end
        else
          % INTERNAL USE ONLY: Icon(imageicon)
          imageicon = filename;
          this.Peer = imageicon;
        end
      else
        filename = controllib.internal.util.hString2Char(filename);
        if isempty(filename)
          % Icon([], description)
          this.Peer = [];  % javax.swing.ImageIcon([]) will hang command line!
          this.Description = description;
        elseif ischar(filename)
          if exist(filename, 'file')
            % Icon(filename, description)
            this.Peer = javax.swing.ImageIcon(filename, description);
          else
            error(message('Controllib:toolpack:CannotLocateFile', filename));
          end
        else
          % INTERNAL USE ONLY: Icon(imageicon, description)
          imageicon = filename;
          this.Peer = imageicon;
          this.Description = description;
        end
      end
    end

    function value = get.Peer(this)
      % GET function for Peer property.
      value = this.Peer_;
      if isempty(value)
        % Default peer: empty ImageIcon
        value = javax.swing.ImageIcon;
        this.Peer_ = value; % Do not recreate an empty icon every time.
      end
    end

    function set.Peer(this, value)
      % SET function for Peer property.
      if isempty(value)
        value = []; % Will reset the peer to new empty ImageIcon.
      elseif ~isa(value, 'javax.swing.ImageIcon')
        error(message('Controllib:toolpack:InvalidPropertyValue', 'Peer'));
      end
      this.Peer_ = value;
    end

    function value = get.Description(this)
      % GET function for Description property.
      value = char(this.Peer.getDescription);
    end

    function set.Description(this, value)
      % SET function for Description property.
      value = controllib.internal.util.hString2Char(value);
      if isempty(value)
        value = '';
      elseif ~ischar(value)
        error(message('Controllib:toolpack:StringArgumentNeeded'));
      end
      this.Peer.setDescription(value);
    end
  end

  % ----------------------------------------------------------------------------
  methods (Static)
    function icon = getIcon(filename)
      % Helper method to get standard icons.
      iconfile = fullfile(toolpack.component.Icon.Path, filename);
      icon = toolpack.component.Icon(iconfile);
    end

    function showIcons
      % Helper method to show all standard icons on a figure window.
      clsName = 'toolpack.component.Icon';
      toolpack.component.Icon.showIcons_(clsName);
    end
  end

  % Standard icons from toolstrip icon library
  methods (Sealed, Static)
    function icon = ADD_16
      icon = toolpack.component.Icon.getIcon('Add_16.png');
    end
    function icon = ADD_24
      icon = toolpack.component.Icon.getIcon('Add_24.png');
    end
    function icon = BACK_16
      icon = toolpack.component.Icon.getIcon('Back_16.png');
    end
    function icon = BACK_24
      icon = toolpack.component.Icon.getIcon('Back_24.png');
    end
    function icon = BROWSE_16
      icon = toolpack.component.Icon.getIcon('Browse_16.png');
    end
    function icon = BROWSE_24
      icon = toolpack.component.Icon.getIcon('Browse_24.png');
    end
    function icon = CLEAR_16
      icon = toolpack.component.Icon.getIcon('Clear_16.png');
    end
    function icon = CLEAR_24
      icon = toolpack.component.Icon.getIcon('Clear_24.png');
    end
    function icon = CLOSE_16
      icon = toolpack.component.Icon.getIcon('Close_16.png');
    end
    function icon = CLOSE_24
      icon = toolpack.component.Icon.getIcon('Close_24.png');
    end
    function icon = COMPARE_16
      icon = toolpack.component.Icon.getIcon('Compare_16.png');
    end
    function icon = COMPARE_24
      icon = toolpack.component.Icon.getIcon('Compare_24.png');
    end
    function icon = CONFIRM_16
      icon = toolpack.component.Icon.getIcon('Confirm_16.png');
    end
    function icon = CONFIRM_24
      icon = toolpack.component.Icon.getIcon('Confirm_24.png');
    end
    function icon = CONTINUE_16
      icon = toolpack.component.Icon.getIcon('Continue_16.png');
    end
    function icon = CONTINUE_24
      icon = toolpack.component.Icon.getIcon('Continue_24.png');
    end
    function icon = CONTINUE_MATLAB_16
      icon = toolpack.component.Icon.getIcon('Continue_MATLAB_16.png');
    end
    function icon = CONTINUE_MATLAB_24
      icon = toolpack.component.Icon.getIcon('Continue_MATLAB_24.png');
    end
    function icon = COPY_16
      icon = toolpack.component.Icon.getIcon('Copy_16.png');
    end
    function icon = COPY_24
      icon = toolpack.component.Icon.getIcon('Copy_24.png');
    end
    function icon = CUT_16
      icon = toolpack.component.Icon.getIcon('Cut_16.png');
    end
    function icon = CUT_24
      icon = toolpack.component.Icon.getIcon('Cut_24.png');
    end
    function icon = DELETE_16
      icon = toolpack.component.Icon.getIcon('Delete_16.png');
    end
    function icon = DELETE_24
      icon = toolpack.component.Icon.getIcon('Delete_24.png');
    end
    function icon = DOWN_16
      icon = toolpack.component.Icon.getIcon('Down_16.png');
    end
    function icon = DOWN_24
      icon = toolpack.component.Icon.getIcon('Down_24.png');
    end
    function icon = END_16
      icon = toolpack.component.Icon.getIcon('End_16.png');
    end
    function icon = END_24
      icon = toolpack.component.Icon.getIcon('End_24.png');
    end
    function icon = EXPORT_16
      icon = toolpack.component.Icon.getIcon('Export_16.png');
    end
    function icon = EXPORT_24
      icon = toolpack.component.Icon.getIcon('Export_24.png');
    end
    function icon = FIND_FILES_16
      icon = toolpack.component.Icon.getIcon('Find_Files_16.png');
    end
    function icon = FIND_FILES_24
      icon = toolpack.component.Icon.getIcon('Find_Files_24.png');
    end
    function icon = FORWARD_16
      icon = toolpack.component.Icon.getIcon('Forward_16.png');
    end
    function icon = FORWARD_24
      icon = toolpack.component.Icon.getIcon('Forward_24.png');
    end
    function icon = GOTO_16
      icon = toolpack.component.Icon.getIcon('Goto_16.png');
    end
    function icon = GOTO_24
      icon = toolpack.component.Icon.getIcon('Goto_24.png');
    end
    function icon = HELP_16
      icon = toolpack.component.Icon.getIcon('Help_16.png');
    end
    function icon = HELP_24
      icon = toolpack.component.Icon.getIcon('Help_24.png');
    end
    function icon = IMPORT_16
      icon = toolpack.component.Icon.getIcon('Import_16.png');
    end
    function icon = IMPORT_24
      icon = toolpack.component.Icon.getIcon('Import_24.png');
    end
    function icon = LAYOUT_16
      icon = toolpack.component.Icon.getIcon('Layout_16.png');
    end
    function icon = LAYOUT_24
      icon = toolpack.component.Icon.getIcon('Layout_24.png');
    end
    function icon = LEGEND_16
      icon = toolpack.component.Icon.getIcon('Legend_16.png');
    end
    function icon = LEGEND_24
      icon = toolpack.component.Icon.getIcon('Legend_24.png');
    end
    function icon = LOCK_16
      icon = toolpack.component.Icon.getIcon('Lock_16.png');
    end
    function icon = LOCK_24
      icon = toolpack.component.Icon.getIcon('Lock_24.png');
    end
    function icon = MATLAB_16
      icon = toolpack.component.Icon.getIcon('MATLAB_16.png');
    end
    function icon = MATLAB_24
      icon = toolpack.component.Icon.getIcon('MATLAB_24.png');
    end
    function icon = NEW_16
      icon = toolpack.component.Icon.getIcon('New_16.png');
    end
    function icon = NEW_24
      icon = toolpack.component.Icon.getIcon('New_24.png');
    end
    function icon = OPEN_16
      icon = toolpack.component.Icon.getIcon('Open_16.png');
    end
    function icon = OPEN_24
      icon = toolpack.component.Icon.getIcon('Open_24.png');
    end
    function icon = PAN_16
      icon = toolpack.component.Icon.getIcon('Pan_16.png');
    end
    function icon = PAN_24
      icon = toolpack.component.Icon.getIcon('Pan_24.png');
    end
    function icon = PARALLEL_16
      icon = toolpack.component.Icon.getIcon('Parallel_16.png');
    end
    function icon = PARALLEL_24
      icon = toolpack.component.Icon.getIcon('Parallel_24.png');
    end
    function icon = PASTE_16
      icon = toolpack.component.Icon.getIcon('Paste_16.png');
    end
    function icon = PASTE_24
      icon = toolpack.component.Icon.getIcon('Paste_24.png');
    end
    function icon = PAUSE_16
      icon = toolpack.component.Icon.getIcon('Pause_16.png');
    end
    function icon = PAUSE_24
      icon = toolpack.component.Icon.getIcon('Pause_24.png');
    end
    function icon = PAUSE_MATLAB_16
      icon = toolpack.component.Icon.getIcon('Pause_MATLAB_16.png');
    end
    function icon = PAUSE_MATLAB_24
      icon = toolpack.component.Icon.getIcon('Pause_MATLAB_24.png');
    end
    function icon = PLAY_16
      icon = toolpack.component.Icon.getIcon('Play_16.png');
    end
    function icon = PLAY_24
      icon = toolpack.component.Icon.getIcon('Play_24.png');
    end
    function icon = PLOT_16
      icon = toolpack.component.Icon.getIcon('Plot_16.png');
    end
    function icon = PLOT_24
      icon = toolpack.component.Icon.getIcon('Plot_24.png');
    end
    function icon = PRINT_16
      icon = toolpack.component.Icon.getIcon('Print_16.png');
    end
    function icon = PRINT_24
      icon = toolpack.component.Icon.getIcon('Print_24.png');
    end
    function icon = PROPERTIES_16
      icon = toolpack.component.Icon.getIcon('Properties_16.png');
    end
    function icon = PROPERTIES_24
      icon = toolpack.component.Icon.getIcon('Properties_24.png');
    end
    function icon = PUBLISH_16
      icon = toolpack.component.Icon.getIcon('Publish_16.png');
    end
    function icon = PUBLISH_24
      icon = toolpack.component.Icon.getIcon('Publish_24.png');
    end
    function icon = REDO_16
      icon = toolpack.component.Icon.getIcon('Redo_16.png');
    end
    function icon = REDO_24
      icon = toolpack.component.Icon.getIcon('Redo_24.png');
    end
    function icon = REFRESH_16
      icon = toolpack.component.Icon.getIcon('Refresh_16.png');
    end
    function icon = REFRESH_24
      icon = toolpack.component.Icon.getIcon('Refresh_24.png');
    end
    function icon = RESTORE_16
      icon = toolpack.component.Icon.getIcon('Restore_16.png');
    end
    function icon = RESTORE_24
      icon = toolpack.component.Icon.getIcon('Restore_24.png');
    end
    function icon = RUN_16
      icon = toolpack.component.Icon.getIcon('Run_16.png');
    end
    function icon = RUN_24
      icon = toolpack.component.Icon.getIcon('Run_24.png');
    end
    function icon = SAVE_16
      icon = toolpack.component.Icon.getIcon('Save_16.png');
    end
    function icon = SAVE_24
      icon = toolpack.component.Icon.getIcon('Save_24.png');
    end
    function icon = SAVE_ALL_16
      icon = toolpack.component.Icon.getIcon('Save_All_16.png');
    end
    function icon = SAVE_ALL_24
      icon = toolpack.component.Icon.getIcon('Save_All_24.png');
    end
    function icon = SAVE_AS_16
      icon = toolpack.component.Icon.getIcon('Save_As_16.png');
    end
    function icon = SAVE_AS_24
      icon = toolpack.component.Icon.getIcon('Save_As_24.png');
    end
    function icon = SAVE_COPY_AS_16
      icon = toolpack.component.Icon.getIcon('Save_Copy_As_16.png');
    end
    function icon = SAVE_COPY_AS_24
      icon = toolpack.component.Icon.getIcon('Save_Copy_As_24.png');
    end
    function icon = SAVE_DIRTY_16
      icon = toolpack.component.Icon.getIcon('Save_Dirty_16.png');
    end
    function icon = SAVE_DIRTY_24
      icon = toolpack.component.Icon.getIcon('Save_Dirty_24.png');
    end
    function icon = SEARCH_16
      icon = toolpack.component.Icon.getIcon('Search_16.png');
    end
    function icon = SEARCH_24
      icon = toolpack.component.Icon.getIcon('Search_24.png');
    end
    function icon = SELECT_16
      icon = toolpack.component.Icon.getIcon('Select_16.png');
    end
    function icon = SELECT_24
      icon = toolpack.component.Icon.getIcon('Select_24.png');
    end
    function icon = SETTINGS_16
      icon = toolpack.component.Icon.getIcon('Settings_16.png');
    end
    function icon = SETTINGS_24
      icon = toolpack.component.Icon.getIcon('Settings_24.png');
    end
    function icon = SET_PATH_16
      icon = toolpack.component.Icon.getIcon('Set_Path_16.png');
    end
    function icon = SET_PATH_24
      icon = toolpack.component.Icon.getIcon('Set_Path_24.png');
    end
    function icon = SIMULINK_16
      icon = toolpack.component.Icon.getIcon('Simulink_16.png');
    end
    function icon = SIMULINK_24
      icon = toolpack.component.Icon.getIcon('Simulink_24.png');
    end
    function icon = STOP_16
      icon = toolpack.component.Icon.getIcon('Stop_16.png');
    end
    function icon = STOP_24
      icon = toolpack.component.Icon.getIcon('Stop_24.png');
    end
    function icon = TOOLS_16
      icon = toolpack.component.Icon.getIcon('Tools_16.png');
    end
    function icon = TOOLS_24
      icon = toolpack.component.Icon.getIcon('Tools_24.png');
    end
    function icon = UNDO_16
      icon = toolpack.component.Icon.getIcon('Undo_16.png');
    end
    function icon = UNDO_24
      icon = toolpack.component.Icon.getIcon('Undo_24.png');
    end
    function icon = UNLOCK_16
      icon = toolpack.component.Icon.getIcon('Unlock_16.png');
    end
    function icon = UNLOCK_24
      icon = toolpack.component.Icon.getIcon('Unlock_24.png');
    end
    function icon = UP_16
      icon = toolpack.component.Icon.getIcon('Up_16.png');
    end
    function icon = UP_24
      icon = toolpack.component.Icon.getIcon('Up_24.png');
    end
    function icon = UP_ONE_LEVEL_16
      icon = toolpack.component.Icon.getIcon('Up_One_Level_16.png');
    end
    function icon = UP_ONE_LEVEL_24
      icon = toolpack.component.Icon.getIcon('Up_One_Level_24.png');
    end
    function icon = ZOOM_IN_16
      icon = toolpack.component.Icon.getIcon('Zoom_In_16.png');
    end
    function icon = ZOOM_IN_24
      icon = toolpack.component.Icon.getIcon('Zoom_In_24.png');
    end
    function icon = ZOOM_OUT_16
      icon = toolpack.component.Icon.getIcon('Zoom_Out_16.png');
    end
    function icon = ZOOM_OUT_24
      icon = toolpack.component.Icon.getIcon('Zoom_Out_24.png');
    end
  end

  % Non-toolstrip, but common icons (for tear-aways)
  methods (Sealed, Static)
    function icon = ADD_ITEM
      icon = toolpack.component.Icon.getIcon('Add_Item.png');
    end
    function icon = REMOVE_ITEM
      icon = toolpack.component.Icon.getIcon('Remove_Item.png');
    end
    function icon = CLEAR_ALL
      icon = toolpack.component.Icon.getIcon('Clear_All.png');
    end
    function icon = LOCK
      icon = toolpack.component.Icon.getIcon('Lock.png');
    end
    function icon = UNLOCK
      icon = toolpack.component.Icon.getIcon('Unlock.png');
    end
    function icon = DELETE
      icon = toolpack.component.Icon.getIcon('Delete.png');
    end
    function icon = EDIT
      icon = toolpack.component.Icon.getIcon('Edit.png');
    end
    function icon = VIEW
      icon = toolpack.component.Icon.getIcon('View.png');
    end
  end

  % Old (deprecated) icons
  methods (Sealed, Static)
    function icon = NEW
      icon = toolpack.component.Icon.NEW_16;
    end
    function icon = OPEN
      icon = toolpack.component.Icon.OPEN_16;
    end
    function icon = SAVE
      icon = toolpack.component.Icon.SAVE_16;
    end
    function icon = PRINT
      icon = toolpack.component.Icon.PRINT_16;
    end
    function icon = HELP
      icon = toolpack.component.Icon.HELP_16;
    end
    function icon = UNDO
      icon = toolpack.component.Icon.UNDO_16;
    end
    function icon = REDO
      icon = toolpack.component.Icon.REDO_16;
    end
    function icon = SETTINGS
      icon = toolpack.component.Icon.SETTINGS_16;
    end
    function icon = MATLAB
      icon = toolpack.component.Icon.MATLAB_16;
    end
    function icon = SIMULINK
      icon = toolpack.component.Icon.SIMULINK_16;
    end
    function icon = IMPORT_DATA
      icon = toolpack.component.Icon.IMPORT_16;
    end
    function icon = RUN
      % 24-pixel version
      icon = toolpack.component.Icon.RUN_24;
    end
    function icon = STOP
      % 24-pixel version
      icon = toolpack.component.Icon.STOP_24;
    end
    %
    function icon = ADD
      icon = toolpack.component.Icon.ADD_16;
    end
    function icon = CLOSE
      icon = toolpack.component.Icon.CLOSE_16;
    end
  end

  % ----------------------------------------------------------------------------
  methods (Static, Access = protected)
    function showIcons_(clsName)
      % Find all static methods returning an icon.
      info = meta.class.fromName(clsName);
      list = info.MethodList;
      [~, I] = sort({list.Name});
      list = list(I);

      mthd = {};
      for k = 1:length(list)
        m = list(k);
        if m.Static && isempty(m.InputNames) && ...
            ~isempty(m.OutputNames) && strcmp(m.OutputNames, 'icon')
          % Static methods returning icons have no inputs and have "icon"
          % as the output argument.
          mthd{end+1} = m.Name;  %#ok<AGROW>
        end
      end

      % Remove deprecated icons from showcase
      mthd = setdiff(mthd, {'NEW', 'OPEN', 'SAVE', 'PRINT', 'HELP', 'UNDO', 'REDO', 'SETTINGS', ...
                          'MATLAB', 'SIMULINK', 'IMPORT_DATA', 'RUN', 'STOP', 'ADD', 'CLOSE'});

      % Add icons to a panel
      len = ceil(length(mthd)/5); % 5 columns and as many rows as needed.
      f = '';
      for k = 1:len
        f = sprintf('%sf:d:g,',f);
      end
      f(end) = ''; % Remove last ','.
      panel = toolpack.component.TSPanel('f:d:g,f:d:g,f:d:g,f:d:g,f:d:g',f);
      for k = 1:length(mthd)
        try
          icon = eval([clsName, '.' mthd{k}]);
          label = toolpack.component.TSLabel(mthd{k}, icon);
        catch E
          % Icon not implemented yet.
          fprintf('%s\n', E.message);
          label = toolpack.component.TSLabel(mthd{k});
        end
        i = rem(k-1,5); % col
        j = (k-i-1)/5;  % row
        str = sprintf('xy(%d,%d)', i+1, j+1);
        panel.add(label,str);
      end

      % Show icons on a panel
      fig = figure(...
        'IntegerHandle','off', ...
        'Menubar','None',...
        'Toolbar','None',...
        'Name','Icon Catalog. To use: toolpack.component.Icon.<NAME>', ...
        'NumberTitle','off', ...
        'Visible','on', ...
        'Resize', 'on', ...
        'Units','pixels');
      set(fig, 'ResizeFcn', @localFigureResize)
      pos = get(fig, 'Position');
      scroll = javaObjectEDT('javax.swing.JScrollPane', panel.Peer);
      [~, container] = matlab.ui.internal.JavaMigrationTools.suppressedJavaComponent(scroll,[0 0 pos(3) pos(4)],fig);
      set(fig, 'UserData', {panel, container});
    end
  end
end

% ----------------------------------------------------------------------------
function localFigureResize(fig,~)
% Handle figure resize
pos = get(fig, 'Position');
ud  = get(fig, 'UserData');
container = ud{2};
set(container, 'Position', [0 0 pos(3) pos(4)]);
end
