function [ v_num, v, v_p ] = pariomino_variants ( mp, np, p_num, p, d )

%*****************************************************************************80
%
%% pariomino_variants() finds variants of pariominoes in an array.
%
%  Discussion:
%
%    We are supplied with an array P of pariominoes.  We wish to "tile" a
%    region R, using, for each I, D(I) copies of pariomino P(I).
%    We are asked to return an array containing all the variants of these 
%    polynomials that can be generated by rotation and reflection.
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    02 May 2020
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    integer MP, NP, the rows and columns in the representation of the pariomino P.
%
%    integer P_NUM, the number of pariominoes.
%
%    integer P(MP,NP,P_NUM), for each value K, P(:,:,K) is a matrix of 
%    -1's, 0's and 1's representing the K-th pariomino.  Each matrix should be 
%    "top-left tight", that is, there should be a nonzero in row 1, and in 
%    column 1.  However, there may be trailing rows and columns of zeros.
%
%    integer D(P_NUM), the number of copies of each pariomino that
%    may be used.  If D(I) <= 0, no variants of pariomino I will be generated.
%
%  Output:
%
%    integer V_NUM, the number of variants found.
%
%    integer V(MP,NP,V_NUM), the variants.
%
%    integer V_P(V_NUM); if V(:,:,I) is a variant of the pariomino
%    P(:,:,L), then V_P(I) is set to L.
%
  v_num = 0;
  v = [];
  v_p = [];

  for l = 1 : p_num
%
%  Only use pariominoes for which the user has set D to at least 1.
%
    if ( 1 <= d(l) )
%
%  Make a condensed version of the pariomino called "Q".
%
      q = pariomino_condense ( p(1:mp,1:np,l) );

      [ mq, nq ] = size ( q );
%
%  Generate all variants.
%
      for reflect = 0 : 1
        for rotate = 0 : 4

          s = pariomino_transform ( q, rotate, reflect );

          [ ms, ns ] = size ( s );
%
%  Only proceed if this variant S will fit in [MP,NP].
%
          if ( ms <= mp & ns <= np )
%
%  Expand S to an [MP,NP] array T.
%
            t = zeros(mp,np);
            t(1:ms,1:ns) = s;
%
%  Compare T to all previous variants.
%
            different = true;
            for k = 1 : v_num
              if ( t(1:mp,1:np) == v(1:mp,1:np,k) )
                different = false;
                break;
              end
            end

            if ( different )
              v_num = v_num + 1;
              v(1:mp,1:np,v_num) = t(1:mp,1:np);
              v_p(v_num) = l;
            end

          end

        end
      end

    end

  end

  return
end
