classdef TSToggleButton < toolpack.component.TSButtonBehavior
  % Toolstrip toggle button.
  %
  % See also toolpack.component.TSCheckBox, toolpack.component.TSRadioButton,
  % toolpack.component.ButtonGroup.
  
  % Author(s): Bora Eryilmaz
  % Revised:
  % Copyright 2010-2011 The MathWorks, Inc.
  
  % ----------------------------------------------------------------------------
  properties (Dependent, Access = public)
    % Component's text (string, default = '')
    Text
    % Component's icon (Icon, default = Icon.empty)
    Icon
  end
  
  properties (Dependent, GetAccess = public, SetAccess = private)
    % Button group (ButtonGroup, default = ButtonGroup.empty)
    Group
  end
  
  properties (Dependent, Access = public, SetObservable, AbortSet)
    % State of the component (logical, default = false)
    Selected
  end
  
  properties (Access = private)
    % Icon or [] for default Icon.empty
    Icon_
    % Logical
    Selected_
    % ButtonGroup or [] for default value ButtonGroup.empty.
    Group_
  end
  
  % ----------------------------------------------------------------------------
  events
    % Event sent upon selection changes.
    ItemStateChanged
  end
  
  % ----------------------------------------------------------------------------
  methods
    function this = TSToggleButton(text, icon, selected)
      % Creates a toolstrip button.
      %
      % Example:
      %   text = 'Apply';
      %   icon = toolpack.component.Icon.NEW;
      %   selected = true;
      %
      %   btn = toolpack.component.TSToggleButton
      %   btn = toolpack.component.TSToggleButton(icon)
      %   btn = toolpack.component.TSToggleButton(text)
      %   btn = toolpack.component.TSToggleButton(text, selected)
      %   btn = toolpack.component.TSToggleButton(icon, selected)
      %   btn = toolpack.component.TSToggleButton(text, icon)
      %   btn = toolpack.component.TSToggleButton(text, icon, selected)
      
      this = this@toolpack.component.TSButtonBehavior;
      cls = 'com.mathworks.toolstrip.components.TSToggleButton';
      if nargin == 0
        % TSToggleButton();
        this.Peer = javaObjectEDT(cls);
      elseif nargin == 1
        text = controllib.internal.util.hString2Char(text);
        if ischar(text)
          % TSToggleButton(text)
          this.Peer = javaObjectEDT(cls, text);
        else
          % TSToggleButton(icon)
          icon = text;
          this.Icon = icon;
          this.Peer = javaObjectEDT(cls, icon.Peer);
        end
      elseif nargin == 2
        text = controllib.internal.util.hString2Char(text);          
        if ischar(text)
          if islogical(icon)
            % TSToggleButton(text, selected)
            selected = icon;
            this.Peer = javaObjectEDT(cls, text, selected);
          else
            % TSToggleButton(text, icon)
            this.Icon = icon;
            this.Peer = javaObjectEDT(cls, text, icon.Peer);
          end
        else
          % TSToggleButton(icon, selected)
          selected = icon;
          icon = text;
          this.Icon = icon;
          this.Peer = javaObjectEDT(cls, icon.Peer, selected);
        end
      else
        % TSToggleButton(text, icon, selected)
        this.Icon = icon;
        this.Peer = javaObjectEDT(cls, text, icon.Peer, selected);
      end
      this.Selected = this.Peer.isSelected;
      addItemListener( this, {@LocalItemStateChanged, this} )
    end
    
    function value = get.Text(this)
      % GET function for Text property.
      value = char(this.Peer.getText);
    end
    
    function set.Text(this, value)
      % SET function for Text property.
      value = controllib.internal.util.hString2Char(value);
      if isempty(value)
        value = '';
      elseif ~ischar(value)
        ctrlMsgUtils.error('Controllib:toolpack:StringArgumentNeeded')
      end
      this.Peer.setText(value);
    end
    
    function value = get.Icon(this)
      % GET function for Icon property.
      value = this.Icon_;
      if isempty(value)
        value = toolpack.component.Icon.empty; % default
      end
    end
    
    function set.Icon(this, value)
      % SET function for Icon property.
      if isempty(value)
        value = [];
        this.Peer.setIcon(value)
      elseif isa(value, 'toolpack.component.Icon')
        this.Peer.setIcon(value.Peer)
      else
        ctrlMsgUtils.error('Controllib:toolpack:InvalidPropertyValue', 'Icon')
      end
      this.Icon_ = value;
    end
    
    function value = get.Selected(this)
      % GET function for Selected property.
      value = this.Selected_;
    end
    
    function set.Selected(this, value)
      % SET function for Selected property.
      if ~islogical(value)
        ctrlMsgUtils.error('Controllib:toolpack:InvalidPropertyValue', 'Selected')
      end
      this.Selected_ = value;
      this.Peer.setSelected(value);
    end
    
    function value = get.Group(this)
      % GET function for Group property.
      value = this.Group_;
      if isempty(value)
        value = toolpack.component.ButtonGroup.empty; % default
      end
    end
    
    function set.Group(this, value)
      % SET function for Group property.
      if isempty(value)
        value = [];
      elseif ~isa(value, 'toolpack.component.ButtonGroup')
        ctrlMsgUtils.error('Controllib:toolpack:InvalidPropertyValue', 'Group')
      end
      this.Group_ = value;
    end
    
    function delete(this)
      % Deletes the component
      if ~isempty(this.Group)
        % Remove this toggle button from the button group.
        this.Group.remove(this)
      end
    end
  end
  
  methods (Hidden)
    function utSetGroup(this, group)
      this.Group = group;
    end
  end
  
  methods (Access = private)
    function addItemListener(this, fcn)
      % Do not modify. Use as is to prevent Java memory leaks.
      L = addlistener(this.Peer, 'ItemStateChanged', fcn);
      this.Listeners = [this.Listeners; L];
    end
  end
end

% ------------------------------------------------------------------------------
function LocalItemStateChanged(~,~,obj)
obj.Selected = obj.Peer.isSelected;
obj.notify('ItemStateChanged')
end
