function [b, ecode] = genpoly2b(genpoly,m,prim_poly)
% GENPOLY2B Check the validity of RS generator polynomial and compute the corresponding b
%    [B, ECODE] = GENPOLY2B(GEN_POLY) returns B corresponding to the row
%    vector of Galois field (GF) object GEN_POLY, and ECODE which specifies
%    whether GEN_POLY is a valid generator polynomial. B is -1 when
%    GEN_POLY is invalid.
%
%    [B, ECODE] = GENPOLY2B(X, M, PRIM_POLY) formulates the row vector of
%    Galois field (GF) object, GENPOLY, by performing gf(X, M, PRIM_POLY)
%    implicitly. PRIM_POLY is the primitive polynomial of the Galois field
%    which is of order 2^M.
% 
%    Meaning of ECODE value:
%       0 : Valid GEN_POLY
%       1 : Invalid GEN_POLY as its # of roots doesn't match its degree
%       2 : Invalid GEN_POLY as it's not monic
%       3 : Invalid GEN_POLY as it contains zeros
%   
%   See also GF.

% Copyright 1996-2021 The MathWorks, Inc.

% Initial checks
if nargin~=1 && nargin~=3
    error(message('comm:genpoly2b:InvalidNoOfInputs'));
end

if(any(genpoly == 0))
    ecode = 3;
    b = 0;
    return
end
    
if ~isa(genpoly, 'gf')
    narginchk(3,3);
    genpoly = gf(genpoly,m,prim_poly);
end

gpOne = genpoly(1);
if ~isequal(gpOne.x,1)
    ecode = 2;
    b = [];
    return;
end

% Ensure number of roots equals deg(genpoly)
roots_int = roots(genpoly);   % column vector
t2 = length(roots_int);
if t2==0 || length(roots_int) ~= length(genpoly)-1
    ecode = 1;
    b = -1;
    return
end
roots_power = int2pow(roots_int');              % gf object, row vector
roots_power = sort(double(roots_power.x));      % sorted; double
b = min(roots_power);

% Check if roots_power are consecutive numbers
if ~isequal(roots_power, (b:b+t2-1))
    % Check if roots_power is the mod of consecutive numbers
	b_new = roots_power(find(roots_power-(b:b+t2-1), 1, 'first'));
	b_new_pos = find(roots_power-(b:b+t2-1), 1, 'first');
	roots_power(1:b_new_pos-1) = roots_power(1:b_new_pos-1)+2^m-1;
    if ~isequal(sort(roots_power), (b_new:b_new+t2-1))
        ecode = 1;      % invalid genpoly
    else
        ecode = 0;      % genpoly ok
        b = b_new;
    end
else
    ecode = 0;          % genpoly ok
end

end

function gf_pow = int2pow(gf_int)

[~, gf_pow] = gftuple((int2bit(double(gf_int.x),gf_int.m,false)'), ...
                       int2bit(double(gf_int.prim_poly),ceil(log2(double(gf_int.prim_poly)+1)),false)');
gf_pow = gf(gf_pow', gf_int.m,gf_int.prim_poly);

end

% [EOF]