function varargout = plots(varargin)

% This is a plus version of the native plot function of Matlab.  The first
% enhancement is to move a curve by dragging it.  The second enhancement is
% to hide the handle of the figure to prevent the replacement by a subsequent one.
% 
% Usage:
%        The syntax is the same as the native "plot".
%
% Enhancement #2 was originated on Feb, 22, 2017 by Limin Shao.
% Enhancement #1 was originated on Nov. 18, 2007, firstly modified Nov. 23,
% 2007, seconly modified on Nov. 17, 2010, and thirdly modified on Feb. 21,
% 2017 by Limin Shao.

% __--^^| DEVELOPMENT NOTE |^^--__
% USERDATA
%   figure: previous location of last button click in the figure.
%   %curve: offset parameters for relocating the curve.
%   axes:   linewith of the axes.

FigureHandle = figure;

% Enhancement #1, free movement of a clicked curve.
UIMenuHandle = uimenu('ForegroundColor', [1 0 0], 'Position', 1, 'Label', 'Direction', 'UserData', [1 1], 'Tag', 'UIMENU');
uimenu(UIMenuHandle, 'Checked', 'on', 'Label', 'Move in all directions', 'Tag', 'all');
uimenu(UIMenuHandle, 'Label', 'Move vertically', 'Tag', 'vertical');
uimenu(UIMenuHandle, 'Label', 'Move horizontally', 'Tag', 'horizontal');
set(get(UIMenuHandle, 'Children'), 'Callback', {@direction_option, UIMenuHandle});

LineHandles = plot(varargin{:});

if nargout ~= 0
    varargout{1} = LineHandles;
end

set(LineHandles, 'ButtonDownFcn', {@capture, FigureHandle, UIMenuHandle});

% Enhancement #2, hide or unveil the handle of the figure.
ToolbarHandle = findall(FigureHandle, 'Tag', 'FigureToolBar');
ToggleProtectionHandle = findall(ToolbarHandle, 'Tag', 'protection');

Icon = ones(13, 13, 3)*0.5; Icon(:, :, 2) = ones(13, 13);

if isempty(ToggleProtectionHandle)
    uitoggletool(ToolbarHandle,'CData', Icon, 'Tag', 'protection', ...
        'TooltipString', 'Click it to protect the plot from closing by commands or replacing by another.', ...
        'OnCallback', {@HideFigureHandle, FigureHandle}, ...
        'OffCallback', {@UnveilFigureHandle, FigureHandle});
end


function capture(src, eventdata, FigureHandle, UIMenuHandle)
% src is the handle of the clicked curve.

AxesHandle = get(FigureHandle, 'CurrentAxes');

%set(AxesHandle, 'Unit', get(FigureHandle, 'Unit'), 'UserData', src);
set(AxesHandle, 'Unit', get(FigureHandle, 'Unit'));

set(FigureHandle, 'UserData', get(FigureHandle, 'CurrentPoint'));

Aux = get(AxesHandle, {'Position', 'XLim', 'YLim'});
ScalingFactor = Aux{1}(3:4)./[diff(Aux{2}) diff(Aux{3})];

Direction = get(UIMenuHandle, 'UserData');
switch diff(Direction)
    case 0, set(FigureHandle, 'Pointer', 'fleur');
    case 1, set(FigureHandle, 'Pointer', 'top');
    case -1, set(FigureHandle, 'Pointer', 'left');
end;

set(src, 'UserData', {ScalingFactor, Direction});
set(FigureHandle, 'WindowButtonMotionFcn', {@moving, src}, ...
    'WindowButtonUpFcn', @completion);


% Actions while the user is moving the curve.
function moving(src, eventdata, LineHandle)
% src is the handle of the figure.

PreviousPoint = get(src, 'UserData');
CurrentPoint = get(src, 'CurrentPoint');

LineData = get(LineHandle, {'XData', 'YData'});
Parameters = get(LineHandle, 'UserData');

Delta = (CurrentPoint - PreviousPoint)./Parameters{1};
Direction = Parameters{2};

set(LineHandle, 'XData', LineData{1} + Direction(1)*Delta(1), ...
    'YData', LineData{2} + Direction(2)*Delta(2));

set(src, 'UserData', CurrentPoint);


% Actions after the curve is moved to a desired position.
function completion(src, eventdata)
set(src, {'WindowButtonMotionFcn', 'Pointer'}, {'', get(0, 'DefaultFigurePointer')});
set(get(src, 'CurrentAxes'), 'Unit', get(0, 'DefaultAxesUnit'));


function direction_option(src, eventdata, UIMenuHndl)
set(get(UIMenuHndl, 'Children'), 'Checked', 'off');
set(src, 'Checked', 'on');
switch get(src, 'Tag')
    case 'all', set(UIMenuHndl, 'UserData', [1 1]);
    case 'vertical', set(UIMenuHndl, 'UserData', [0 1]);
    case 'horizontal', set(UIMenuHndl, 'UserData', [1 0]);
end;


function HideFigureHandle(hObject, eventdata, FigureHandle)
AxesHandle = get(FigureHandle, 'CurrentAxes');

set(AxesHandle, 'UserData', get(AxesHandle, 'LineWidth'), 'LineWidth', 2);
set(FigureHandle, 'HandleVisibility', 'off');
set(hObject, 'TooltipString', 'The plot is protected from closing by commands or replacing by another.');


function UnveilFigureHandle(hObject, eventdata, FigureHandle)
AxesHandle = get(FigureHandle, 'CurrentAxes');

set(FigureHandle, 'HandleVisibility', 'on');
set(AxesHandle, 'LineWidth', get(AxesHandle, 'UserData'));
set(hObject, 'TooltipString', 'Click it to protect the plot from closing by commands or replacing by another.');
