function palette(action),
%PALETTE Create Your Own Color Map function-tool
%	PALETTE allows to create a new colormap or a colormap based on Matlab
%	standard, plain, custom, or any other colormaps created before.
%
%	To start: type function name without any argument
%	The code allows to save two variables (MyColor, MyColorMap) defining 
%	the colormap into a mat-file.
%
%	To use newly created colormat, change current colormap to your own:
%	1. load mat-file with your colormap 
%	2. redefine the colormap property by typing: >> colormap(MyColorMap)
%
%       Acknowledgement:
%
%       This program is written by Svetlana V. Panasyuk, while at MIT, EAPS
%	                			    Last update August 1997
%			      Correspond to panasyuk@alum.mit.edu

%============================================================================
if nargin < 1,% set up the input graphical window
%============================================================================
  oldFigNumber = watchon;
  figNumber = figure( ...
    'Units','Normalized', ...
    'Position',[0.46 0.6 0.52 0.35], ...
    'Name','Create your own Color Map', ...
    'NumberTitle','off', ...
    'Visible','off');
  set(figNumber,'ColorMap',hsv);
  MaaxHndl = axes( ...
    'Units','normalized', ...
    'Position',[0 0 1 1], ...
    'Visible','off');
%----------------------------------------------------------------------------- 
% Information for the general descriptive and the immediate action buttons: 
%-----------------------------------------------------------------------------

%^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% The descriptive texts/help button:
%
  text(0.01,0.95,'Choose colormap type:');
  text(0.01,0.75,'color controls:');
  helpHndl = uicontrol( ...
    'Style','push', ...
    'Units','normalized', ...
    'Position',[0.9 0.88 0.09 0.1], ...
    'String','Help', ...
    'Callback','palette(''help'');');
%^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% The Color Map Type button
%
  typeHndl = uicontrol( ...
    'Style','Popup', ...
    'Units','normalized', ...
    'Position',[0.01 0.8 0.15 0.1], ...
    'String','hsv|jet|hot|cool|bone|copper|pink|prism|flag|gray|user from', ...
    'Callback','palette(''type'');',...
    'Value',1);
%^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% The Custom ColorMap File Input button
%
  inpuHndl = uicontrol( ...
    'Style','Edit', ...
    'Units','normalized', ...
    'Position',[0.16 0.8 0.23 0.1], ...
    'String','FileIn.mat', ...
    'CallBack','palette(''input'');',...
    'BackGroundColor','k');
%^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% The Color Control button
%
  contHndl = uicontrol( ...
    'Style','Popup', ...
    'Units','normalized', ...
    'Position',[0.01 0.6 0.15 0.1], ...
    'String','hue|saturation|value|red|green|blue', ...
    'Callback','palette(''control'');', ...
    'Value',1,'UserData',hsv);
%^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% The Color Control Slide button
%
  slidHndl = uicontrol( ...
    'Style','Slider', ...
    'Units','normalized', ...
    'Position',[0.16 0.6 0.23 0.1], ...
    'Max',1,'Min',-1, ...
    'CallBack','palette(''slide'');', ...
    'Value',0);
%^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% The Process button
%
  procHndl = uicontrol( ...
    'Style','pushbutton', ...
    'Units','normalized', ...
    'Position',[0.01 0.4 0.15 0.1], ...
    'String','Process CM', ...
    'CallBack','palette(''process'');');
%^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% The Save button
%
  saveHndl = uicontrol( ...
    'Style','pushbutton', ...
    'Units','normalized', ...
    'Position',[0.01 0.3 0.15 0.1], ...
    'String','Save CM to', ...
    'Callback','palette(''save'');');
%^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% The Castom ColorMap File Output button
%
  outpHndl = uicontrol( ...
    'Style','Edit', ...
    'Units','normalized', ...
    'Position',[0.16 0.3 0.23 0.1], ...
    'String','FileOut.mat');
%^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% The Close button
%
  closHndl = uicontrol( ...
    'Style','push', ...
    'Units','normalized', ...
    'Position',[0.9 0.3 0.09 0.1], ...
    'String','Close', ...
    'Callback','close(gcf)');
%----------------------------------------------------------------------------
% The axes for the plots.
% SqaxHndl == the Color Square axis Handle, where you pick up the color
% FiaxHndl, SeaxHndl == first and second axes to build & display the ColorMap
%----------------------------------------------------------------------------
  SqaxHndl = axes('Position',[0.4 0.3 0.49 0.68]);
  imagHndl = image(spiral(8));
  set(imagHndl,'ButtonDownFcn','palette(''image'');');
  set(SqaxHndl,'XTick',[],'YTick',[],'UserData',[0 0 0]);

  FiaxHndl = axes('Position',[0.01 0.17 0.98 0.1]);
  patcHndl = patch([1 65 65 1],[0 0 1 1],[0 0 0]);
  set(patcHndl,'FaceColor','none','ButtonDownFcn','palette(''patch'');');
  set(FiaxHndl,'UserData',NaN*ones(64,3), ...
    'XLim',[0.9 65.1],'YLim',[-0.1 1.1], ...
    'XTick',[2:2:64],'YTick',[],'FontSize',[10],'Box','on');

  SeaxHndl = axes('Position',[0.01 0.01 0.98 0.1]);
  set(SeaxHndl,'XLim',[0.9 65.1],'YLim',[-0.1 1.1], ...
    'XTick',[],'YTick',[],'Box','on');
   
%---------------------------------------------------------------------------
% Uncover the figure: 1-5 BtnHndl, 6-9 AxesHndl, 10-13  Parameters    
%---------------------------------------------------------------------------
  hndlList = [typeHndl contHndl slidHndl procHndl saveHndl MaaxHndl ...
     SqaxHndl FiaxHndl SeaxHndl imagHndl patcHndl inpuHndl outpHndl];
  set(figNumber,'Visible','on','UserData',hndlList);

  watchoff(oldFigNumber);
  figure(figNumber);
%^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% Where to find the information in 'UserData':
% 	gcf		hndlList
%	contHndl	colormap	[current colormap]
%	SqaxHndl	color		[(1,3) of currently pickted color]
%	FiaxHndl	MyColor		[(64,3) with NaNs and reals]
% 	SeaxHndl	MyColorMap 	[(64,3) of created colormap]

%===========================================================================
else % To recall all graphical information:
%===========================================================================
  hndlList = get(gcf,'UserData');
  typeHndl = hndlList(1);contHndl = hndlList(2);slidHndl = hndlList(3);
  procHndl = hndlList(4);saveHndl = hndlList(5);MaaxHndl = hndlList(6);
  SqaxHndl = hndlList(7);FiaxHndl = hndlList(8);SeaxHndl = hndlList(9);
  imagHndl = hndlList(10);patcHndl = hndlList(11);
  inpuHndl = hndlList(12);outpHndl = hndlList(13);

%===========================================================================
  if strcmp(action,'type'), % To choose the type of colormap
%===========================================================================
    MapNames = get(typeHndl,'String');
    MapNum = get(typeHndl,'Value');
    axes(SqaxHndl);
    if MapNum < 11,
      set(inpuHndl,'BackgroundColor','k');
      CMN = abs(MapNames(MapNum,:));
      CMN(find((CMN==0)|(CMN==32))) = [];
      eval(['set(gcf,''colormap'',' setstr(CMN) ');']);
      set(contHndl,'UserData',colormap);
    else set(inpuHndl,'BackgroundColor',[.5 .5 .5]);
      palette('input');
    end;
%===========================================================================
  elseif strcmp(action,'input'), % To choose the type of colormap
%===========================================================================
    FileIn = get(inpuHndl,'String');
    if isempty(FileIn),
      set(inpuHndl,'BackgroundColor','y');
    else 
      if 1-isempty(findstr(FileIn,' ')),
        FileIn(findstr(FileIn,' ')) = [];
      end;
      if isempty(FileIn),
        set(inpuHndl,'BackgroundColor','y');
      else fid = fopen(FileIn);
        if fid == -1,
	  set(inpuHndl,'BackgroundColor','y');
        else eval(['load ' FileIn ';']);
	  set(inpuHndl,'BackgroundColor',[.5 .5 .5]);
	  set(gcf,'colormap',MyColorMap);
	  set(contHndl,'UserData',colormap);
	  set(FiaxHndl,'UserData',MyColor);
	  addr = find(1-isnan(MyColor(:,1)));
	  axes(FiaxHndl);cla;
	  patcHndl = patch([1 65 65 1],[0 0 1 1],[0 0 0]);
	  set(patcHndl,'FaceColor','none', ...
	    'ButtonDownFcn','palette(''patch'');');
	  for ii = addr.',
	    patch([0 1 1 0]+ii,[0 0 1 1],MyColor(ii,:));
	  end
	  fclose('all');
	end;
      end;
    end;
%===========================================================================
  elseif strcmp(action,'control'), % To change colors in ColorSquare
%===========================================================================
    set(slidHndl,'Value',0); 
    set(gcf,'colormap',get(contHndl,'UserData'));
%===========================================================================
  elseif strcmp(action,'slide'), % To interpret slide action
%===========================================================================
    CM = get(contHndl,'UserData');
    what2control = get(contHndl,'Value');
    slide = get(slidHndl,'Value');
    if what2control >3,
      CMvar = CM;
      rgb = 1;
      what2control = what2control - 3;
    else CMvar = rgb2hsv(CM);
      rgb = 0;
    end;
    change=CMvar(:,what2control)*(1-slide*(-1)^(slide<0))+slide*(slide>0);
    CMvar(:,what2control) = change;
    if 1-rgb,
      set(gcf,'colormap',hsv2rgb(CMvar));
    else set(gcf,'colormap',CMvar);
    end;
    set(typeHndl,'Value',11);
%===========================================================================
  elseif strcmp(action,'process'), % To process MyColorMap from MyColor
%===========================================================================
    MyColor = get(FiaxHndl,'UserData');
    addr = find(1-isnan(MyColor(:,1)));la = length(addr);
    for ii = 1:3,
      junk = interp1(addr,MyColor(addr,ii),[addr(1):addr(la)]);
      MyColorMap(:,ii) = junk(:);
    end;
    MyColorMap = [ones(addr(1)-1,1)*MyColor(addr(1),:); ...
      MyColorMap;ones(64-addr(la),1)*MyColor(addr(la),:)];
    axes(SeaxHndl);cla;
    for ii = 1:64,
      patch([0 1 1 0]+ii,[0 0 1 1],MyColorMap(ii,:));
    end;
    set(SeaxHndl,'UserData',MyColorMap);
    axes(FiaxHndl);cla;
    patcHndl = patch([1 65 65 1],[0 0 1 1],[0 0 0]);
    set(patcHndl,'FaceColor','none', ...
      'ButtonDownFcn','palette(''patch'');');
    for ii = addr.',
      patch([0 1 1 0]+ii,[0 0 1 1],MyColor(ii,:));
    end
%===========================================================================
  elseif strcmp(action,'save'), % To save the MyColor and MyColorMap
%===========================================================================
    MyColor = get(FiaxHndl,'UserData');
    MyColorMap = get(SeaxHndl,'UserData');
    FileOut = get(outpHndl,'String');
    eval(['save ' FileOut ' MyColor MyColorMap']);
%===========================================================================
  elseif strcmp(action,'image'), %to interpret cursor while on ColorSquare
%===========================================================================
    axes(SqaxHndl);
    CM = get(gcf,'colormap');junk = spiral(8);
    addr = floor(ginput(1)+0.5);
    if (addr(1)>=.5)&(addr(1)<=8.5)&(addr(2)>=.5)&(addr(2)<=8.5),
      set(contHndl,'UserData',CM);
      set(SqaxHndl,'UserData',CM(junk(addr(2),addr(1)),:));
    end;
%===========================================================================
  elseif strcmp(action,'patch'), %to interpret cursor while on FirstAxis
%===========================================================================
    axes(FiaxHndl);
    [x y b] = ginput(1);addr=floor(x);
    if b == 1,
      color = get(SqaxHndl,'UserData');
    else color = [0 0 0];
    end;
    patch([0 1 1 0] + addr,[0 0 1 1],color);
    MyColor = get(FiaxHndl,'UserData');
    if b == 1,
      MyColor(addr,:) = color;
    else MyColor(addr,:) = NaN*color;
    end;
    set(FiaxHndl,'UserData',MyColor);
%===========================================================================
  elseif strcmp(action,'help'), % help
%===========================================================================
    ttlStr = 'How to Create your own Color Map';
    hlpStr = ...
       ['                                                              '
	' How to create new color map:                                 '
	' The idea: The Colorful Spiral (CS) at the center of graphical'
	' window gives you currently available colors to build your own'
	' colormap (CM). You can pick up any displayed color by double-'
	' clicking any mouse-button while cursor is placed over the    '
	' desirable color.                                             '
	' The Building Board (BB) is a ruler beneath the CS.           '
	' The numbers on BB represent the place of the color in the    '
	' colormap (from 1 to 64). You apply the choosen color by the  '
	' second-click of the left mouse button, while the cursor is   '
	' placed over the desirable place.The second click by the right'
	' (or central) mouse button deletes the underneath color.      '
	' Once you have at least two colors on the BB, you can obtain  '
	' your own colormap by pressing ''Process CM''.   That will take '
	' all colors from the BB, linearly interpolate/extrapolate them'
	' to the full-sized CM, and display your own colormap in the   '
	' very bottom box.To save the colormap, type in the output file'
	' name and press the ''Save CM to'' gray box.                    '
	'                                                              '
	' How to change CS colors:                                     '
	' 1. Choose colormap type: press top-left gray box in graphical'
	' window to display a standard type of the colormap (first 10  '
	' options), or to display a customized colormap (last option,  '
	' and for that you have to have a *.mat file in the directory  '
	' already).                                                    '
	' 2. Currently displayed colors in CS can be changed in several'
	' ways: press gray box beneath the sign:''color controls:''.     '
	' The slide-bar on the right allows you to change hsv/rgb      '
	' properties from 0 (left limit) to 1 (right limit).           '
	'                                                              '
	' Hints:                                                       '
	' 1. Everytime you click on CS you fix the current colormap as '
	' ''working'' CM, and it becomes a customized CM (note change    '
	' in the colormap type gray box).                              '
	' 2. Once you load ''User''s'' colormap, you load the choosen     '
	' colors into BB (therefore your previous choice will be       '
	' replaced by customized in BB).                               '
	' 3. Yellow color of the load-in box tells you that the input- '
	' file does not exist.                                         '
	'                                                              '
	' Acknowledgement:                                             '
	'            This program was written by Svetlana V. Panasyuk, '
	'       while at Massachussetts Institute of Technology, EAPS. '
	'                                      Last update August 1997 '
	'                          Correspond to panasyuk@alum.mit.edu '];
    helpfun(ttlStr,hlpStr);
  end; 
end;
