function gui_complete
%% Variables
wheelCount = 0;
screenSize = get(groot, 'ScreenSize');
figSize = [350, 400];
figPosition = [(screenSize(3:4) - figSize)/2, figSize];

%% Build GUI
hFig = uifigure('Position', figPosition, 'Name', 'Mouse Utility', ...
   'Color', 0.8*ones(1, 3));
% Measure! panel
hPanelMeas = uipanel(hFig, 'Title', 'Measure!', 'Position', [10, 330, 330, 60]);
hSwitch = uiswitch(hPanelMeas, 'Position', [140, 10, 100, 25]);
% Results panel
hPanelRes = uipanel(hFig, 'Title', 'Results', 'Position', [10, 70, 330, 250]);
uilabel(hPanelRes, 'Text', 'Wheel Count:', 'Position', [10, 200, 90, 20]);
hEditCount = uieditfield(hPanelRes, 'numeric', 'Editable', 'off', 'Position', [120, 200, 90, 22]);
uilabel(hPanelRes, 'Text', 'Cursor Speed (px/s):', 'Position', [10, 180, 120, 20]);
hGaugeSpeed = uigauge(hPanelRes, 'semicircular', 'Position', [10, 10, 310, 170], ...
   'Limits', [0 2e3]);
% Close button
hButtClose = uibutton(hFig, 'Text', 'Close', 'Position', [130, 20, 90, 30]);

%% Callbacks
hButtClose.ButtonPushedFcn = @(a, b)closeWindow(hFig);
hSwitch.ValueChangedFcn = @(src, data)manageGUIEnable(src);
hFig.WindowKeyPressFcn = @(src, eventData)keyListener(eventData);

%% Save data to GUI
nAverages = 15;
setappdata(hFig, 'lastTimes', repmat(clock, nAverages, 1));
setappdata(hFig, 'lastPositions', zeros(nAverages, 2));

%% Default state
manageGUIEnable(hSwitch);

%% Callback Functions
   function measureSpeed()
      newPosition = hFig.CurrentPoint;
      newTime = clock;
      
      lastPositions = getappdata(hFig, 'lastPositions');
      newPositions = [newPosition; lastPositions(1:end-1, :)];
      setappdata(hFig, 'lastPositions', newPositions);

      lastTimes = getappdata(hFig, 'lastTimes');
      newTimes = [newTime; lastTimes(1:end-1, :)];
      setappdata(hFig, 'lastTimes', newTimes);
      
      distance = norm(newPositions(1, :) - newPositions(end, :));
      dt = etime(newTimes(1, :), newTimes(end, :));
      
      hGaugeSpeed.Value = distance/dt;
   end

   function countWheel(eventData)
      wheelCount = wheelCount + abs(eventData.VerticalScrollCount);
      hEditCount.Value = wheelCount;
   end

   function manageGUIEnable(hSwitch)
      if strcmp(hSwitch.Value, 'On')
         enableValue = 'on';
         wheelFcn = @(hFig, eventData)countWheel(eventData);
         motionFcn = @(a, b)measureSpeed();
      else
         enableValue = 'off';
         wheelFcn = '';
         motionFcn = '';
      end
      set(hPanelRes.Children, 'Enable', enableValue);
      hFig.WindowScrollWheelFcn = wheelFcn;
      hFig.WindowButtonMotionFcn = motionFcn;
   end

   function keyListener(eventData)
      if strcmp(eventData.Key, 'escape')
         closeWindow(hFig);
      end
   end
end

function closeWindow(hFig)
hFig.delete();
end