function [ x, done ] = r8vec_mirror_ab_next ( m, a, b, x, done )

%*****************************************************************************80
%
%% R8VEC_MIRROR_AB_NEXT steps through "mirrored" versions of vector X.
%
%  Discussion:
%
%    X is an M component vector contained in a rectangle described by A and B,
%    that is, for each index I, we have
%      A(I) <= X(I) <= B(I).
%
%    "Mirrored" versions of the vector X have one or more components
%    reflected about the A or B limit.  
%
%    As long as each component of X is strictly between the limits A and B,
%    this means there will be 3^M possible versions of the vector.
%
%    If one component of X is equal to one limit or the other, this 
%    suppresses mirroring across that limit.  If one component of
%    X, A and B are equal, then no mirroring is done at all in that component.
% 
%  Example:
%
%      A = 0, 0, 0
%      X = 1, 1, 1
%      B = 2, 2, 2
%      results in the following sequence of 3x3x3 values:
%
%      0  0  0
%      0  0  1
%      0  0  2
%      0  1  0
%      0  1  1
%      .......
%      2  1  1
%      2  1  2
%      2  2  0
%      2  2  1
%      2  2  2
%
%    A = 0 1 0
%    X = 1 1 1
%    B = 2 2 2
%    results in the following sequence of 3x2x3 values:
%
%      0 1 0
%      0 1 1
%      0 1 2
%      0 2 0
%      0 2 1
%      0 2 2
%      1 1 0
%      1 1 1
%      1 1 2
%      1 2 0
%      1 2 1
%      1 2 2
%      2 1 0
%      2 1 1
%      2 1 2
%      2 2 0
%      2 2 1
%      2 2 2
%
%    A = 0 1 0
%    X = 1 1 1
%    B = 2 1 2
%    results in the following sequence of 3x1x3 values:
%
%      0 1 0
%      0 1 1
%      0 1 2
%      1 1 0
%      1 1 1
%      1 1 2
%      2 1 0
%      2 1 1
%      2 1 2
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    03 August 2016
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    integer M, the number of entries in the vector.
%
%    real A(M), B(M), the lower and upper limits.
%
%    real X(M), the vector to be manipulated.
%
%    logical DONE.  On first call, DONE should be TRUE, and
%    A(I) <= X(I) <= B(I) for each index I. 
%
%  Output:
%
%    real X(M), the manipulated vector.
%
%    logical DONE.  If DONE is TRUE,
%    then the returned value is the last entry in the sequence.
%

%
%  First call:
%
  if ( done )
%
%  Ensure all A(I) <= X(I) <= B(I).
%
    if ( any ( x(1:m) < a(1:m) ) )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'R8VEC_MIRROR_AB_NEXT - Fatal error!\n' );
      fprintf ( 1, '  Not every A(I) <= X(I).\n' );
      error ( 'R8VEC_MIRROR_AB_NEXT - Fatal error!' );
    end

    if ( any ( b(1:m) < x(1:m) ) )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'R8VEC_MIRROR_AB_NEXT - Fatal error!\n' );
      fprintf ( 1, '  Not every X(I) <= B(I).\n' );
      error ( 'R8VEC_MIRROR_AB_NEXT - Fatal error!' );
    end
%
%  Set first element of sequence.
%
    x(1:m) = 2.0 * a(1:m) - x(1:m);
%
%  Unless A = B, our sequence is not done.
%
    if ( all ( a(1:m) == b(1:m) ) )
      done = true;
    else
      done = false;
    end
%
%  Subsequent calls.
%
  else
%
%  Initialize index to last.
%  loop
%    if index < 1, set DONE = true and return.
%    if the index-th value is below B, increment it and return;
%    otherwise reset index-th value to A.
%    decrement the index.
%
    i = m;

    while ( 1 <= i )

      if ( x(i) < a(i) )
        x(i) = 2.0 * a(i) - x(i);
        return
      elseif ( x(i) < b(i) )
        x(i) = 2.0 * b(i) - x(i);
        return
      else
        x(i) = x(i) - 2.0 * ( b(i) - a(i) );
      end

      i = i - 1;

    end

    done = true;

  end


  return
end

