function LoadClutTest(whichScreen)
% LoadClutTest([whichScreen])
% 
% Usually, you'll call this with no arguments, to test all screens.
% 
% Tests LoadClut, which loads the hardware CLUT of any video card, even
% those with more-than-8-bit DACs. Most video cards have 8-bit DACs. The
% Radius Thunder and ATI Radeon have 10-bit DACs. The CRS Ltd BITS++ has
% 14-bit DACs.
% 
% This test detects errors in the current (6/25/02) ATI Radeon 7000
% driver. There is optional code in LoadClut, which you may wish to
% enable, to partially compensate for the driver bug. See LoadClut. As of
% 7/31/02 ATI is considering a ROM upgrade for the 7000 to fix this bug.
% web http://psychtoolbox.org/mac.html#drivers ;
% 
% LoadClutTest and ClutTest are closely related. LoadClutTest assesses
% accuracy of the LoadClut function, which is the highest-level user
% interface we provide. ClutTest is aimed one step lower, assessing
% performance of the various driver calls, especially cscSetEntries,
% cscDirectSetEntries, cscSetGamma, and cscGetEntries, and does a rigorous
% test with random numbers in both the color and gamma tables.
%
% See also LoadClut and ClutTest.

% 1998           Written by Jack Nachmias.
% 10/16/98  dhb  Modified.
% 10/30/98  dhb  Added three-D gamma test, based on email
%                with Steve Engel.
% 2/25/99   dhb  Took out call to GetClut, no longer needed.
% 4/9/99    dhb  Modified to be cleaner, given my better understanding
%                of how the radius driver behaves.
% 5/8/99    dhb  Added 8-bit support.  Not tested for the measurement portion.
%                Indeed, the measurement portion has not been retested for any
%                mode after the change, although unless I made a typo it should
%                definitely work for 32-bit mode and probably for 8.
% 2/102     dhb  Change to use OpenWindow/SetClut.
% 4/17/02   dgp  Quit unless user has at least two screens.
% 4/18/02   dhb  Allow it to run with one screen by giving better prompts.
% 4/19/02   dgp  Cosmetic. Distinguish bits in DAC from pixelSize.
% 4/19/02   dgp  Speak when screen is too dark. Abort if two screens are needed.
% 4/24/02   awi  Exit on PC with message.
% 6/6/02    dgp  Renamed LoadClutTest and extensively revised. Dropped the visual tests.
% 6/25/02   dgp  Cleaned up for release.
% 7/31/02   dgp  Enhanced to test the extra bits (beyond 8).

if strcmp('PCWIN',computer)
	error('Win: LoadClutTest not yet supported.');
end

if nargin==0
	fprintf('LoadClutTest\n');
	RestoreScreen;
	PrepareScreen;
	DescribeComputer;
	for whichScreen = Screen('Screens')
		DescribeScreen(whichScreen);
		DescribeScreenPrefs(whichScreen);
		LoadClutTest(whichScreen);
	end
	DescribeScreen(-1);
	return
end

w=Screen(whichScreen,'OpenWindow');

DescribeScreen(-2);
for bits=unique([8 ScreenDacBits(whichScreen)])
	for pixelSize=Screen(w,'PixelSizes')
		Screen(w,'PixelSize',pixelSize);
		% Write and read CLUT, and compare.
		clutSize=ScreenClutSize(whichScreen);
		r=floor(bitshift((clutSize+1)*(0:clutSize-1)',bits)/clutSize/clutSize);
		g=flipud(r);
		b=floor(rand(size(r))*2.^bits);
		clut1=[r g b];
		LoadClut(w,clut1,0,bits);
		clut2=Screen(w,'GetClut',bits);
		fprintf('%2d-bit gamma table. ',bits);
		fprintf('pixelSize %2d. ',Screen(whichScreen,'PixelSize'));
		if isempty(clut2)
			fprintf('GetClut n/a.\n');
		else
			err=max(max(abs(clut1-clut2)));
			if ~err
				fprintf('Success! GetClut==LoadClut at %d bits.\n',bits);
			else
				fprintf('Failed! Values read differed (by up to %d) from what was written:\n',err);
				rows=0;
				for row=1:size(clut1,1)
					if any(clut1(row,:)-clut2(row,:)) & rows<5
						fprintf('%3d: LoadClut:[%5d %5d %5d] vs. GetClut:[%5d %5d %5d]\n',row-1,clut1(row,:),clut2(row,:))
						rows=rows+1;
					end
				end
			end
		end
	end
end
Screen(w,'Close');
