function tabs = enumeratelrtabs(lambda,mu,nu,visflag)

% ENUMERATELRTABS
%
% function tabs = enumeratelrtabs(lambda,mu,nu,visflag)
%
% An implementation of the littlewood-richardson rule.
% lambda,mu,nu are partitions written out as row vectors
% where |lambda|=|mu|+|nu|.
%
% tabs is a table of size height(lambda)x height(lambda)
% where each row represents a single legal LR tableau.
%
% reshape(tabs(t,:),length(lambda),length(lambda))' gives
% a table where the ij entry is the number of js in row i
%
% Jonathan Huang

if ~exist('visflag','var')
	visflag = false;
else
	visflag = true;
end

if length(mu) > length(lambda) || length(nu) > length(lambda)
	tabs = [];
	return;
end

mu = [mu zeros(1,length(lambda)-length(mu))];
nu = [nu zeros(1,length(lambda)-length(nu))];
if length(find(lambda-mu<0))>0
	tabs = [];
	return;
end
n = sum(lambda);
p = sum(mu);
q = sum(nu);
if n ~= p+q
	tabs = [];
	return;
end

if length(lambda) == 1
	tabs = nu;
	return;
end

tabs = enumsubtabs(1,lambda,mu,nu);

legal = zeros(size(tabs,1),1);
for t=1:size(tabs,1)
	curr = reshape(tabs(t,:),length(lambda),length(lambda))';
	% check content constraints
	if length(find(nu == sum(curr))) == length(nu)
		% check tableau constraints
		c_tableau = 1;
		for i=2:length(lambda) % i goes down rows
			for j=1:i % j goes across possible values
				if mu(i)+sum(curr(i,1:j))>mu(i-1)+sum(curr(i-1,1:(j-1)))
					% tableau constraint violation
					c_tableau = 0;
					break;
				end
			end
		end
		if c_tableau
			% check reverse lattice constraints
			c_lattice = 1;
			for j=2:length(lambda)
				for i=j:length(lambda)	
					if sum(curr(1:i,j))>sum(curr(1:(i-1),j-1))
						% reverse lattice word constraint violation
						c_lattice = 0;
						break;
					end
				end
			end
			if c_lattice
				legal(t) = 1;
	
				% visualize tableau for good luck
				if visflag 
					lrtabvis(lambda,mu,curr);
					disp(' ');
				end
			end
		end
	end
end
tabs = tabs(find(legal == 1),:);
return;

% this function is called assuming that lambda, mu, nu are the
% same length as arrays, but with nonzeros `left-justified'
function tabs = enumsubtabs(level,lambda,mu,nu)

if level == length(lambda)
	Rtmp = enumRows(level,lambda(level)-mu(level));
	tabs = zeros(size(Rtmp,1),length(lambda));
	tabs(:,1:size(Rtmp,2)) = Rtmp;
	return;
end
if sum(nu) == 0
	tabs = zeros(1,length(lambda)*(length(lambda)-level+1));
	return;
end
Rtmp = enumRows(level,lambda(level)-mu(level));
R = zeros(size(Rtmp,1),length(lambda));
R(:,1:size(Rtmp,2)) = Rtmp;

tabs = [];
for i=1:size(R,1)
	nusub = nu - R(i,:);
	if length(find(nusub<0))==0
		subtabs = enumsubtabs(level+1,lambda,mu,nusub);
		tabs = [tabs; repmat(R(i,:),size(subtabs,1),1) subtabs];
	end
end

% s = lambda_j-mu_j
% j is the highest thing that things can be
function R = enumRows(j,s) 
if s == 0
	R = zeros(1,j);
	return;
end
if j==1
	R = s;
	return;
end
R = [];
for i=0:s
	A = enumRows(j-1,s-i);
	B = [i*ones(size(A,1),1) A];
	R = [R; B];
end



