classdef polariMBAntennaReadout < internal.polariMouseBehavior
    
    methods
        function obj = polariMBAntennaReadout(isButtonDown)
            if nargin > 0 && isButtonDown
                obj.InstallFcn = @showToolTipAndPtr_antReadoutDown;
                obj.MotionEvent = @wbdrag;
                obj.DownEvent = [];
                obj.UpEvent = @wbup;
                obj.ScrollEvent = [];
            else
                obj.InstallFcn = @showToolTipAndPtr_antReadout;
                obj.MotionEvent = @wbmotion;
                obj.DownEvent = @wbdown;
                obj.UpEvent = [];
                obj.ScrollEvent = [];
            end
        end
    end
end

function wbmotion(p,ev)

s = computeHoverLocation(p,ev);
firstEntry = p.ChangedState;

% Span readout is special since we detect mouse hits on it even
% when mouse is OUTSIDE axes area.  Because of that we need to
% test axes-index here.
if s.overAntennaReadout
    if firstEntry
        % Only signal that we've completed entry if this is
        % the right instance.
        p.ChangedState = false;
        hoverOverReadoutChange(p.hAntenna,'start');
    end
else
    if firstEntry
        p.ChangedState = false;
    else
        % Only perform these steps if this instance completed
        % entry steps -- that is, the notify operation.
        
        % Not over span readout (possibly not over axes)
        ha = p.hAntenna;
        if ~isempty(ha)
            hoverOverReadoutChange(ha,'stop');
        end
        autoChangeMouseBehavior(p,s);
    end
end
end

function wbdown(p,ev)
% Clicked on span readout.
%
% Begin drag-and-drop change in readout position.

%resetToolTip(p);

p.hFigure.CurrentPoint = ev.Point;
st = p.hFigure.SelectionType;
if strcmpi(st,'open')
    % double-click on span readout
    %
    return
elseif strcmpi(st,'alt')
    % right-click: this action launches the context menu.
    %
    % Prevent further reaction to right-click here, so we don't
    % do any hilite and confuse the user when the context
    % menu launches.
    resetToolTip(p);
    return
end

% Get mouse coords before other work
ax = p.hAxes;

% xxx Could use hgconvertunits here
o = ax.Units;
ax.Units = 'pixels';
pt = get(p.hAxes,'CurrentPoint');
ax.Units = o;

% Update cache
%
% Get handle to span readout widget:
hWidget = gco;
if isempty(hWidget)
    return % EARY EXIT
end
tagStr = sprintf('polariAntennaReadout%d',p.pAxesIndex);
if ~strcmpi(hWidget.Tag,tagStr)
    % clicked on something else (span patch?)
    internal.polariMBGeneral.wbmotion(p,ev);
    return
end
% Clicked on span readout for this polari instance.
% Get position, units are pixels for this uicontrol:
ci.OrigPos = hWidget.Position(1:2);
ci.XLim = ax.XLim;
ci.YLim = ax.YLim;
ci.OrigPt = pt(1,1:2);

% One-time creation of event payload, with dummy location set
% to origin:
ci.EventData = internal.polariEvent([0 0]);

% Disable mouse in all other instances of polari within
% this figure
[ci.OtherPolariInstances, ci.OtherPolariPrevEna] = ...
    enableMouseInOtherInstances(p,false);
p.AntennaReadout_CacheInfo = ci;
changeMouseBehavior(p,'antennareadout_buttondown');

end

function wbdrag(p,ev)

% Drag span readout
%  - graphical updates to position

p.hFigure.CurrentPoint = ev.Point;
updateAntennaReadoutPosition(p);

end

function wbup(p,ev)

% Set point into axes:
p.hFigure.CurrentPoint = ev.Point;
updateAntennaReadoutPosition(p);

ci = p.AntennaReadout_CacheInfo;

% Enable mouse in all other instances of polari within
% this figure
%
% Get list of other instances from cache before clearing it.
% Removes need to recompute list.
enableMouseInOtherInstances(p,true, ...
    ci.OtherPolariInstances, ...
    ci.OtherPolariPrevEna);

% Clear out drag-cache, so we release marker handles etc
p.AntennaReadout_CacheInfo = [];

% Update mouse handlers, and kick it once manually for mouse
% pointer updates etc:
%
% Check where mouse is to determine next step:
s = computeHoverLocation(p,ev);
if ~s.overAntennaReadout
    hoverOverReadoutChange(p.hAntenna,'stop');
    autoChangeMouseBehavior(p,s);
else
    changeMouseBehavior(p,'antennareadout');
end

end

function updateAntennaReadoutPosition(p)
% Change position of span readout
%
% pt: data units, so is everything in ci

% xxx integrate with updateSpanReadoutPosition
%
%  -> make this into a generic updateReadoutPosition()
hTheReadout = p.hAntenna;
ci = p.AntennaReadout_CacheInfo;

hax = p.hAxes;
u = hax.Units;
hax.Units = 'pixels';

xl = ci.XLim;
yl = ci.YLim;

pt = hax.CurrentPoint;
tmp = pt(1,1:2) - ci.OrigPt; % data units

ax_pos = hax.Position;
hax.Units = u;

ax_dx = ax_pos(3);
ax_dy = ax_pos(4);

% Get max unit, due to "square" aspect ratio
data_per_xposunit = (xl(2)-xl(1)) / ax_dx;
data_per_yposunit = (yl(2)-yl(1)) / ax_dy;
data_per_posunit = max([data_per_xposunit,data_per_yposunit]);
newPos = round(tmp / data_per_posunit + ci.OrigPos); % in pixels

% Update readout position
updatePosition(hTheReadout,newPos);
end

function showToolTipAndPtr_antReadoutDown(p)
setptr(p.hFigure,'closedhand');
resetToolTip(p);
end

function showToolTipAndPtr_antReadout(p)
setptr(p.hFigure,'hand');
if p.ToolTips && ~isempty(p.hToolTip) && isvalid(p.hToolTip)
    start(p.hToolTip, ...
        {'ANTENNA METRICS', ...
        'Drag to reposition', ...
        'Right-click for options'});
end

end
