%DIPORIEN   Interactive orientation testing
%   DIPORIEN ON turns on interactive testing of the current image.
%   DIPORIEN OFF turns it off.
%   DIPORIEN by itself toggles the state.
%
%   The image containing the orientation must be specified in a dialog
%   box the first time you select the option.
%
%   When DIPORIEN is turned on, the current coordinates and orientation
%   value are displayed while a mouse button is depressed. The mouse
%   cursor indicates the current tangent orientation. Orientation lies
%   between -pi/2 and pi/2. A vertical line correspondes with 0 and
%   horizontal with +-pi/2. You can move the mouse while holding down
%   the mouse button to find some coordinates.
%
%   DIPORIEN only works on 2D figure windows created through DIPSHOW.
%
%   Also: DIPORIEN(H,'ON'), DIPORIEN(H,'OFF'), etc. to specify a window handle.
%
%   See also DIPSHOW, DIPLINK, DIPZOOM, DIPSTEP, DIPTEST.

% code mostly copied from diptest.m

% (C) Copyright 1999-2000               Pattern Recognition Group
%     All rights reserved               Faculty of Applied Physics
%                                       Delft University of Technology
%                                       Lorentzweg 1
%                                       2628 CJ Delft
%                                       The Netherlands
%
% Bernd Rieger, Jan 2001
% 30 March 2001 (CL): Added 'Compute' button to IMAGESELECT and implemented
%                     computing functionality here.
% 28 June 2001 (CL): Fixed bug that occurred when clicking outside the image area.
% 29 July 2001 (CL): now using dipfig_getcurpos(), a shared private function.
% 16-26 August 2001 (CL): Changed DIPSHOW. This function changes accordingly.
% 15 September 2001 (CL): Using FORMATVALUE instead of NUM2STR to display orientation values.
% 21 Juni 2005 (BR): enable binary images

%??? TODO: allow specifying the orientation image through a parameter, so
%    that the dialog box is not shown.

function menu_out = diporien(arg1,arg2)

% Avoid being in menu
if nargin == 1 & ischar(arg1) & strcmp(arg1,'DIP_GetParamList')
   menu_out = struct('menu','none');
   return
end

if nargin == 0
   fig = get(0,'CurrentFigure');
   if isempty(fig)
      error('No figure window open to do operation on.')
   end
   action = 'toggle';
elseif nargin == 1
   if ischar(arg1)
      fig = gcbf;
      if ~isempty(fig)
         switch lower(arg1)
         case 'motion'
            diporienMotionFcn(fig);
            return
         case 'down'
            diporienButtonDownFcn(fig);
            return
         case 'up'
            diporienButtonUpFcn(fig);
            return
         otherwise
            action = lower(arg1);
         end
      else
         fig = get(0,'CurrentFigure');
         if isempty(fig)
            error('No figure window open to do operation on.')
         end
         action = lower(arg1);
      end
   else
      try
	fig = getfigh(arg1);
      catch
         error('Argument must be a valid figure handle.')
      end
      action = 'toggle';
   end
else
   fig = arg1;
   try
      fig = getfigh(arg1);
   catch
      error('Argument must be a valid figure handle.')
   end
   action = lower(arg2);
end
if findstr(get(fig,'Tag'),'DIP_Image_2D')
   udata = get(fig,'UserData');
   switch (action)
   case 'toggle'
      if strcmp(udata.state,'diporien');
         dipfig_clear_state(fig,udata);
      else
         makeDIPorienObj(fig,udata);
      end
   case 'on'
      if ~strcmp(udata.state,'diporien')
         makeDIPorienObj(fig,udata);
      end
   case 'off'
      if strcmp(udata.state,'diporien')
         dipfig_clear_state(fig,udata);
      end
   end
end


%
% Enable the diporien tool.
%
function makeDIPorienObj(fig,udata,figH_orien)
if ~isfield(udata,'orientationim')
   if strcmp(get(fig,'Tag'),'DIP_Image_2D_Color')
      tmp = imageselect('Select an orientation image',0);
   else
      tmp = imageselect('Select an orientation image',1);
   end
   if ischar(tmp)
      % compute orientation image
      tmp = dip_structuretensor2d(udata.imagedata,'firgauss',[1,1],...
                                  'firgauss',[2,2],'firgauss',1,{'orientation'});
   end
   if isempty(tmp)
      return
   end
   if isa(tmp,'dip_image_array')
      error('Orientation image is an image array.')
   end
   sz = size(udata.imagedata);
   sz = sz(1:2);
   if ~isequal(size(tmp),sz)
      error('Orientation image is wrong size.');
   end
   udata.orientationim = tmp;
end

udata.state = 'diporien';

set(fig,'pointer','arrow',...
        'WindowButtonDownFcn','diporien(''down'')',...
        'WindowButtonUpFcn','',...
        'WindowButtonMotionFcn','',...
        'ButtonDownFcn','',...
        'UserData',[]);   % Solve MATLAB bug!
set(fig,'UserData',udata);
dipfig_set_action_check(fig,udata.state);


%
% Callback function for mouse down in images
%
function diporienButtonDownFcn(fig)
if findstr(get(fig,'Tag'),'DIP_Image_2D')
   img = get(fig,'CurrentObject');
   if strcmp(get(img,'Type'),'image')
      udata = get(fig,'UserData');
      udata.ax = get(img,'Parent');
      udata.oldAxesUnits = get(udata.ax,'Units');
      udata.oldNumberTitle = get(fig,'NumberTitle');
      set(udata.ax,'Units','pixels');
      set(fig,'WindowButtonMotionFcn','diporien(''motion'')',...
              'WindowButtonUpFcn','diporien(''up'')',...
              'NumberTitle','off','pointer','custom','UserData',[]);  % Solve MATLAB bug!
      set(fig,'UserData',udata);
      updateOrientation(fig,udata.ax,img,udata);
   end
end


%
% Callback function for mouse move in images
%
function diporienMotionFcn(fig)
if findstr(get(fig,'Tag'),'DIP_Image_2D')
   img = get(fig,'CurrentObject');
   if strcmp(get(img,'Type'),'image')
      udata = get(fig,'UserData');
      updateOrientation(fig,udata.ax,img,udata);
   end
end


%
% Callback function for mouse up in images
%
function diporienButtonUpFcn(fig)
if findstr(get(fig,'Tag'),'DIP_Image_2D')
   udata = get(fig,'UserData');
   set(udata.ax,'Units',udata.oldAxesUnits);
   set(fig,'WindowButtonMotionFcn','','WindowButtonUpFcn','',...
           'NumberTitle',udata.oldNumberTitle);
   udata = rmfield(udata,{'ax','oldAxesUnits','oldNumberTitle'});
   dipfig_titlebar(fig,udata);
   set(fig,'pointer','arrow','UserData',[]);    % Solve MATLAB bug!
   set(fig,'UserData',udata);
end


%
% Retrieve coordinates and image value, and update figure title.
%
function updateOrientation(fig,ax,img,udata)
pt = dipfig_getcurpos(ax);
udata = get(fig,'UserData');
phi = double(udata.orientationim(pt(1),pt(2)));
set(fig,'Name',['(' num2str(pt(1)),',',num2str(pt(2)),') : ',formatvalue(phi)]);
updateCursor(fig,phi);

%
% Update the the cursor
%
function updateCursor(fig,angle)
ps = {[...
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   2   2   2   2   2   2   2   2   2   2   2   2   2   2   2   NaN
   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ],...
[...
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   2   2   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   1   1   1   2   2   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN 1   1   1   2   2   2   NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN 1   1   1   2   2   2   NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   1   1   2   2   2   NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   1   1   NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ],...
[...
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN 2   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN 1   1   2   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN 1   1   2   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN 1   1   2   NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN 1   2   2   NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN 1   1   2   2   NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   1   2   2   NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   1   NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ],...
[...
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN 2   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ],...
[...
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ],...
[...
   NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN 1   2   NaN NaN NaN NaN NaN
   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ]};
%orientation [-pi/2,pi/2], in 2D it is the radius vector of a cicrle
% the cursor should be the tangent -> 0 = vertical and +-pi/2 = horizontal

angle = mod(angle+(pi/2),pi)-(pi/2);
for n=0:5
   if (angle >= -pi/24+n*pi/12  &  angle < pi/24+n*pi/12)
      pointershape = rot90(ps{n+1},1);
      break;
   end
   if (angle < -pi/24-n*pi/12 & angle >= -pi/24-(n+1)*pi/12)
      pointershape = ps{6-n};
      break;
   end
end
if (angle >= pi/24+5*pi/12 | angle < -pi/24-5*pi/12)
   pointershape = ps{1};
end

set(fig,'PointerShapeCData',pointershape,'PointerShapeHotSpot',[8,8]);
