function uu = update_points( ax, u, e, enh )
% (c) 2012-04-13, Martin Matousek
% Last change: $Date::                            $
%              $Revision$

if( numel( ax ) == 1 )
  set( 0, 'currentfigure', get( ax, 'parent' ) );
  set( gcf, 'currentaxes', ax );
else
  image( ax )
  axis image
end


if( isempty( enh ) )
  enhl = true( size( u, 2 ), 1 );
else
  enhl = false( size( u, 2 ), 1 );
  enhl( enh ) = true;
end

set( gcf, 'keypressfcn', @handle_key );

h = ishold;
if( ~h ), hold on; end

for i = 1:size(u,2)
  [~, h2] = one_pt( u(1,i), u(2,i), i );
  if( ~enhl( i ) )
    set( h2, 'visible', 'off' );
  end
end

for i = 1:size(e,2)
  one_edge( u(:,e(1,i)), u(:,e(2,i)), e(1,i), e(2,i) );
end

if( ~h ), hold off; end

set( ax, 'userdata', size( u, 2) );
set( findobj( ax, 'type', 'image' ), 'buttondownfcn', @add_pt );

if( nargout > 0 )
  input( 'Adjust the points and press enter...\n' );
  
  h = findobj( ax, 'tag', 'POINT' );
  
  x = get( h, 'xdata' );
  y = get( h, 'ydata' );
  i = get( h, 'userdata' );
  i = [i{:}];
  uu = [ x{i}; y{i} ];  
end

function [h h2] = one_pt( x, y, i )
  h = plot( x, y, 'rx', 'markersize', 10, 'ButtonDownFcn', @edit_pt, ...
        'tag', 'POINT', 'userdata', i );
  set( h, 'zdata', 1 );
  h2 = text( x, y-5, sprintf( '%i', i ), ...
        'verticalalign', 'bottom', 'horizontalalign', 'center', ...
        'backgroundcolor', [1 1 0.8], 'tag', 'LABEL', 'userdata', i );

function one_edge( u1, u2, i1, i2 )
  h = plot( [ u1(1) u2(1) ], [ u1(2) u2(2) ], 'y-', 'userdata', [i1; i2], ...
        'tag', 'EDGE', 'ButtonDownFcn', @edit_edge );
  set( h, 'zdata', [0 0] );
  
function add_pt( a, ~ )
  switch( get( gcf, 'selectiontype') )
    case 'normal'

      ax = get(a,'parent' );
      pt = get(ax, 'currentpoint' );
      i = get(ax, 'userdata' ) + 1;
      
      one_pt( pt(1), pt(3), i );
      set( ax, 'userdata', i );
      fprintf( 'Added point %i\n', i );
  end
     
function handle_key(~, key)
  switch( key.Character )
    case '.'
      h = findall( gcf, 'tag', 'POINT' );
      set( h, 'marker', '.', 'color', 'b' );
      h = findall( gcf, 'tag', 'LABEL' );
      set( h, 'visible', 'off' );
    case 'x'
      h = findall( gcf, 'tag', 'POINT' );
      set( h, 'marker', 'x', 'color', 'r' );
      h = findall( gcf, 'tag', 'LABEL' );
      set( h, 'visible', 'on' );
    case 'e'
      refresh_edges
  end

function refresh_edges
  h = findall( gcf, 'tag', 'EDGE' );
  
  e = get( h, 'userdata' );
  e = [ e{:} ];
  e = sort( e );
  e = unique( e', 'rows' )';

  delete( findall( gca, 'tag', 'EDGE' ) );
  
  for i = 1:size(e,2)
    h1 = findobj( gca, 'tag', 'POINT', 'userdata', e(1,i) );
    h2 = findobj( gca, 'tag', 'POINT', 'userdata', e(2,i) );
    one_edge( [ get( h1, 'xdata' ); get( h1, 'ydata' ) ], ...
              [ get( h2, 'xdata' ); get( h2, 'ydata' ) ], ...
              e(1,i), e(2,i) );
  end
  
function edit_edge( a, ~ )
  switch( get( gcf, 'selectiontype') )
    case 'normal'
      delete(a);
  end
  
function edit_pt( a, ~ )
  ax = get(a,'parent' );

  switch( get( gcf, 'selectiontype') )
    case 'normal'

      l = findobj( gca, 'tag', 'LABEL', 'userdata', get(a, 'userdata' ) );
      set( a, 'visible', 'off' );
      set( l, 'visible', 'off' );
      
      [x, y] = ginput(1);
      
      set( a, 'xdata', x );
      set( a, 'ydata', y );
      
      set( l, 'pos', [x y-5 0] );
      
      set( [a l], 'visible', 'on' );
      
    case 'alt'
      i1 = get( a, 'userdata');
      setappdata( ax, 'first', i1 );
      setappdata( ax, 'firstu', [ get( a, 'xdata'); get( a, 'ydata') ] );
      fprintf( 'Edge point 1 = %i\n', i1 );
    case 'extend'
      i1 = getappdata( ax, 'first' );
      if( ~isempty( i1 ) )
        u1 = getappdata( ax, 'firstu' );
        i2 = get( a, 'userdata' );
        u2 = [get( a, 'xdata' ); get( a, 'ydata' ) ];
        one_edge( u1, u2, i1, i2 );
      end
  end
  
      
      