function [ top, btri, bedg, triangle_node, triangle_neighbor ] = swapec ( ...
  i, top, btri, bedg, node_num, node_xy, triangle_num, triangle_node, ...
  triangle_neighbor, work )

%*****************************************************************************80
%
%% swapec() swaps diagonal edges until all triangles are Delaunay.
%
%  Discussion:
%
%    The routine swaps diagonal edges in a 2D triangulation, based on
%    the empty circumcircle criterion, until all triangles are Delaunay,
%    given that I is the index of the new vertex added to the triangulation.
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    07 February 2005
%
%  Author:
%
%    Original FORTRAN77 version by Barry Joe,
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Barry Joe,
%    GEOMPACK - a software package for the generation of meshes
%    using geometric algorithms,
%    Advances in Engineering Software,
%    Volume 13, pages 325-331, 1991.
%
%  Input:
%
%    integer I, the index of the new vertex.
%
%    integer TOP, the index of the top of the stack.
%
%    integer BTRI, BEDG; if positive, are the
%    triangle and edge indices of a boundary edge whose updated indices
%    must be recorded. 
%
%    integer NODE_NUM, the number of node.
%
%    real NODE_XY(2,NODE_NUM), the coordinates of
%    the points.
%
%    integer TRIANGLE_NUM, the number of triangles.
%
%    integer TRIANGLE_NODE(3,TRIANGLE_NUM), the triangle incidence list.  
%
%    integer TRIANGLE_NEIGHBOR(3,TRIANGLE_NUM), the triangle neighbor list; 
%    negative values are used for links of the counter-clockwise linked 
%    list of boundary edges;
%      LINK = -(3*I + J-1) where I, J = triangle, edge index.
%
%    integer WORK(MAXST); entries 1 through TOP
%    contain the indices of initial triangles (involving vertex I)
%    put in stack; the edges opposite I should be in interior;  entries
%    TOP+1 through MAXST are used as a stack.
%
%  Output:
%
%    integer TOP, is zero.
%
%    integer BTRI, BEDG; updated because of swaps.
%
%    integer TRIANGLE_NODE(3,TRIANGLE_NUM), updated because of swaps.
%
%    integer TRIANGLE_NEIGHBOR(3,TRIANGLE_NUM), updated on output because of swaps.
%

%
%  Determine whether triangles in stack are Delaunay, and swap
%  diagonal edge of convex quadrilateral if not.
%
  x = node_xy(1,i);
  y = node_xy(2,i);

  while ( true )

    if ( top <= 0 )
      break
    end

    t = work(top);
    top = top - 1;

    if ( triangle_node(1,t) == i )
      e = 2;
      b = triangle_node(3,t);
    elseif ( triangle_node(2,t) == i )
      e = 3;
      b = triangle_node(1,t);
    else
      e = 1;
      b = triangle_node(2,t);
    end

    a = triangle_node(e,t);
    u = triangle_neighbor(e,t);

    if ( triangle_neighbor(1,u) == t )
      f = 1;
      c = triangle_node(3,u);
    elseif ( triangle_neighbor(2,u) == t )
      f = 2;
      c = triangle_node(1,u);
    else
      f = 3;
      c = triangle_node(2,u);
    end

    swap = diaedg ( x, y, node_xy(1,a), node_xy(2,a), node_xy(1,c), node_xy(2,c), ...
      node_xy(1,b), node_xy(2,b) );

    if ( swap == 1 )

      em1 = i4_wrap ( e - 1, 1, 3 );
      ep1 = i4_wrap ( e + 1, 1, 3 );
      fm1 = i4_wrap ( f - 1, 1, 3 );
      fp1 = i4_wrap ( f + 1, 1, 3 );

      triangle_node(ep1,t) = c;
      triangle_node(fp1,u) = i;
      r = triangle_neighbor(ep1,t);
      s = triangle_neighbor(fp1,u);
      triangle_neighbor(ep1,t) = u;
      triangle_neighbor(fp1,u) = t;
      triangle_neighbor(e,t) = s;
      triangle_neighbor(f,u) = r;

      if ( 0 < triangle_neighbor(fm1,u) )
        top = top + 1;
        work(top) = u;
      end

      if ( 0 < s )

        if ( triangle_neighbor(1,s) == u )
          triangle_neighbor(1,s) = t;
        elseif ( triangle_neighbor(2,s) == u )
          triangle_neighbor(2,s) = t;
        else
          triangle_neighbor(3,s) = t;
        end

        top = top + 1;

        if ( node_num < top )
          fprintf ( 1, '\n' );
          fprintf ( 1, 'SWAPEC - Fatal error!\n' );
          fprintf ( 1, '  Exceeded stacksize.\n' );
          error ( 'SWAPEC - Fatal error!' );
        end

        work(top) = t;

      else

        if ( u == btri && fp1 == bedg )
          btri = t;
          bedg = e;
        end

        l = - ( 3 * t + e - 1 );
        tt = t;
        ee = em1;

        while ( 0 < triangle_neighbor(ee,tt) )

          tt = triangle_neighbor(ee,tt);

          if ( triangle_node(1,tt) == a )
            ee = 3;
          elseif ( triangle_node(2,tt) == a )
            ee = 1;
          else
            ee = 2;
          end

        end

        triangle_neighbor(ee,tt) = l;

      end

      if ( 0 < r )

        if ( triangle_neighbor(1,r) == t )
          triangle_neighbor(1,r) = u;
        elseif ( triangle_neighbor(2,r) == t )
          triangle_neighbor(2,r) = u;
        else
          triangle_neighbor(3,r) = u;
        end

      else

        if ( t == btri && ep1 == bedg )
          btri = u;
          bedg = f;
        end

        l = - ( 3 * u + f - 1 );
        tt = u;
        ee = fm1;

        while ( 0 < triangle_neighbor(ee,tt) )

          tt = triangle_neighbor(ee,tt);

          if ( triangle_node(1,tt) == b )
            ee = 3;
          elseif ( triangle_node(2,tt) == b )
            ee = 1;
          else
            ee = 2;
          end

        end

        triangle_neighbor(ee,tt) = l;

      end

    end

  end

  return
end
