function varargout=align(Action,varargin)
%ALIGN Align uicontrols and axes.
%   ALIGN brings up an alignment tool to interactively align 
%   uicontrols and axes.  ALIGN(HandleList) will align the handles
%   specified in HandleList.  Calling the tool as 
%   ALIGN(HandleList,HorizontalAlignment,VerticalAlignment) will
%   automatically align the objects in the handle list without opening the
%   alignment tool.  Adding a left hand argument to this calling syntax
%   will cause the updated positions of the objects to be returned while
%   the position of the objects on the figure does not change.
%   Finally, calling the alignment tool with
%   Positions=ALIGN(CurPositions,HorizontalAlignment,VerticalAlignment)
%   will return the updated position matrix from the initial position
%   matrix without opening the alignment tool.
%
%   Possible values for HorizontalAlignment are:
%     None, Left, Center, Right, Distribute, Fixed
%
%   Possible values for VerticalAlignment are:
%     None, Top, Middle, Bottom, Distribute, Fixed
%
%   All alignment options will align the objects within the
%   bounding box that encloses the objects.  Distribute and Fixed
%   will align objects to the bottom left of the bounding box. Distribute
%   evenly distributes the objects while Fixed distributes the objects
%   with a fixed distance (in points) between them.
%
%   If Fixed is used for HorizontalAlignment or VerticalAlignment, then
%   the distance must be passed in as an extra argument.   
%   
%   ALIGN(HandleList,HorizontalAlignment,Distance,VerticalAlignment)
%   ALIGN(HandleList,HorizontalAlignment,VerticalAlignment,Distance)
%
%   
%   See also GUIDE, CBEDIT, CTLPANEL, MENUEDIT, PROPEDIT.

%   Loren Dean
%   Copyright (c) 1984-98 by The MathWorks, Inc.
%   $Revision: 1.16 $ $Date: 1998/06/19 12:34:20 $

AlignFig=findall(0,'Tag','Guide Alignment Tool');

Data=[];WatchFlag=1;
if ~isempty(AlignFig),
  Data=get(AlignFig,'UserData');
  if ~isempty(Data),  
    Data=get(Data.All.DataHandle,'UserData');      
    if nargin==1 & strcmp(Action,'Resize'),    
      [Data,WatchFlag]=setwatch('on',Data,1);
    else,      
      [Data,WatchFlag]=setwatch('on',Data);
    end      
  end    
end  

% Wrap try catch around the callback area
%try, 

switch nargin,
  %%%%%%%%%%%%%%%%%%%%%%%%
  %%% Peform an action %%%
  %%%%%%%%%%%%%%%%%%%%%%%%
  case 1,
    if isstr(Action),
      switch Action,
        %%%%%%%%%%%%%
        %%% Apply %%%
        %%%%%%%%%%%%%
        case 'Apply',
          Data=LocalApply(Data);
          Data=guide('PropertyUpdate',Data);
          
        %%%%%%%%%%%%%%%%%%%%%%%%% 
        %%% BrowserButtonDown %%%
        %%%%%%%%%%%%%%%%%%%%%%%%%        
        case 'BrowserButtonDown',
          Data=objbrwser('ButtonDown',Data, ...
                         Data.AlignFig.ListboxHandle,AlignFig,'Square');
          
        %%%%%%%%%%%%%%%%%%%%%%%%
        %%% ChooseHorizontal %%%
        %%%%%%%%%%%%%%%%%%%%%%%%
        case 'ChooseHorizontal',
          Data=LocalChooseHorizontal(Data);          
          
        %%%%%%%%%%%%%%%%%%%%%%
        %%% ChooseVertical %%%
        %%%%%%%%%%%%%%%%%%%%%%
        case 'ChooseVertical',
          Data=LocalChooseVertical(Data);          
       
        %%%%%%%%%%%%%
        %%% Close %%%
        %%%%%%%%%%%%%
        case 'Close',
          CancelFlag=logical(0);        
          if (Data.AlignFig.ChangeModeH|Data.AlignFig.ChangeModeV) & ...   
             length(Data.AlignFig.CurrentHandles)>1,
            Answer=questdlg(['Do you want to Apply these settings ' ...
                             'before closing?'], ...
                             'Apply Settings in Alignment Tool');
            if strcmp(Answer,'Yes'),
              LocalAlign(Data.AlignFig.CurrentHandles, ...
                            Data.AlignFig.Horizontal , ...
                            Data.AlignFig.Vertical,1   ...
                           );
            elseif strcmp(Answer,'Cancel'),
              CancelFlag=logical(1);              
            end
          end % if
          
          if ~CancelFlag,          
            Data=guide('ToolUpdate',Data,AlignFig,'delete');
          end            
          
        %%%%%%%%%%%%
        %%% Help %%%
        %%%%%%%%%%%%
        case 'Help',
          helpfun('Alignment Tool',Data)        
          
        %%%%%%%%%%%%%%%%
        %%% MenuCall %%%
        %%%%%%%%%%%%%%%%        
        case 'MenuCall',
          helpfun(get(gcbo,'Label'),Data);
          
        %%%%%%%%%%%%%%
        %%% Resize %%%
        %%%%%%%%%%%%%%
        case 'Resize',
          LocalResize(Data,AlignFig);        
          
        %%%%%%%%%%%%%%
        %%% Revert %%%
        %%%%%%%%%%%%%%
        case 'Revert',
          set(Data.AlignFig.CurrentHandles, ...
             {'Position'},Data.AlignFig.OrigPositions ...
             );
          Data=LocalChooseHorizontal(Data,Data.AlignFig.RevertHorizontal);
          Data=LocalChooseVertical(Data,Data.AlignFig.RevertVertical);
                    
          Data=guide('PropertyUpdate',Data);
          
        %%%%%%%%%%%%%%%%%%%%%
        %%% ToolsMenuCall %%%
        %%%%%%%%%%%%%%%%%%%%%        
        case 'ToolsMenuCall',
          Data=gnrlfun('ToolsMenuCall',Data);        
          
        %%%%%%%%%%%%%%
        %%% Update %%%
        %%%%%%%%%%%%%%
        case 'Update',
          Data=LocalUpdateTool(Data,AlignFig);        
          
      end % switch Action

    %%%%%%%%%%%%%%%%%%
    %%% Initialize %%%
    %%%%%%%%%%%%%%%%%%
    else,
      HandleList=Action;          
      
      Data=LocalInitFig(HandleList,~nargout,0,AlignFig);
    end % if isstr
          

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%% Alignment Tool does not open %%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  case 3,
    HorizontalAlignment=varargin(1);  
    VerticalAlignment=varargin(2);  
    if strcmp(lower(HorizontalAlignment{:}),'fixed'),
      HorizontalAlignment={'Fixed',0};
    end      
    if strcmp(lower(VerticalAlignment{:}),'fixed'),
      VerticalAlignment={'Fixed',0};
    end      
    HandleList=Action;
    Position=LocalAlign(HandleList,HorizontalAlignment, ...
                        VerticalAlignment,~nargout);
    
    if nargout,varargout(1)={Position};end
    

  %%%%%%%%%%%%%%%%%%
  %%% Initialize %%%
  %%%%%%%%%%%%%%%%%%
  case 0,
    if nargout, 
      error(['No output arguments allowed for 0 ' ...
             'input arguments to ALIGN.']);
    else,
      HandleList=gnrlfun('InitializeHandleList',Data);    
      Data=LocalInitFig(HandleList,1,0,AlignFig);
    end      

  %%%%%%%%%%%%%%%%%%
  %%% Initialize %%%
  %%%%%%%%%%%%%%%%%%
  case 2,
    HandleList=Action;
    Data=LocalInitFig(HandleList,~nargout,varargin{1},AlignFig);

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%% Alignment Tool does not open %%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  case 4,
    if isstr(varargin{2}),    
      HorizontalAlignment=varargin(1);  
      VerticalAlignment=varargin(2:3);
    else,
      HorizontalAlignment=varargin(1:2);  
      VerticalAlignment=varargin(3);
    end
            
    HandleList=Action;
    Position=LocalAlign(HandleList,HorizontalAlignment, ...
                        VerticalAlignment,~nargout);
    
    if nargout,varargout(1)={Position};end

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%% Alignment Tool does not open %%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  case 5,
    HorizontalAlignment=varargin(1:2);  
    VerticalAlignment=varargin(3:4);  
    HandleList=Action;
    Position=LocalAlign(HandleList,HorizontalAlignment, ...
                        VerticalAlignment,~nargout);
    
    if nargout,varargout(1)={Position};end
    

  %%%%%%%%%%%%%
  %%% Error %%%
  %%%%%%%%%%%%%
  otherwise,
    Data=setwatch('off',WatchFlag,Data);
    set(Data.All.DataHandle,'UserData',Data);
    error('Wrong number of input arguments for ALIGN');

end % switch nargin

%catch,
%  Data=gnrlfun('CatchErrors',Data);  
%end % try catch

Data=setwatch('off',WatchFlag,Data);

if ~isempty(Data),
  set(Data.All.DataHandle,'UserData',Data);
end


%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalApply %%%%%
%%%%%%%%%%%%%%%%%%%%%%
function Data=LocalApply(Data);
% Update the Alignment Tool
LocalAlign(Data.AlignFig.CurrentHandles,Data.AlignFig.Horizontal , ...
           Data.AlignFig.Vertical,1);
Data.AlignFig.ChangeModeH=0;
Data.AlignFig.ChangeModeV=0;
set([Data.AlignFig.HorizHandles(1:5) ...
     Data.AlignFig.VertHandles(1:5)], ...
   'Value',0);
set([Data.AlignFig.HorizHandles(6) ...
     Data.AlignFig.VertHandles(6)],'Enable','off');

set(Data.AlignFig.RevertHandle,'Enable','on');
set(Data.AlignFig.ApplyHandle,'Enable','off');

Data.AlignFig.RevertHorizontal=Data.AlignFig.Horizontal;           
Data.AlignFig.RevertVertical=Data.AlignFig.Vertical;           
Data.AlignFig.Horizontal={'None'};           
Data.AlignFig.Vertical={'None'};           

%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalUpdateTool %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=LocalUpdateTool(Data,AlignFig);
% Update the Alignment Tool

NewHandles=LocalGetValidHandles(Data.All.HandleList);          
HandleLoc=find(ismember(NewHandles,Data.AlignFig.CurrentHandles));
if length(NewHandles)~=length(Data.AlignFig.CurrentHandles)| ...
   length(HandleLoc)~=length(NewHandles)|isempty(NewHandles),
  if length(NewHandles)>1,       
    Message=' ';
    set([Data.AlignFig.RevertHandle Data.AlignFig.ApplyHandle], ...
        {'Enable'},{'off';'on'} ...
       );
    btnctrl('on',[Data.AlignFig.HorizHandles(1:5) ...
         Data.AlignFig.VertHandles(1:5)]);
        
  else,
    Message='Two or more uicontrols or axes must be selected.';
    set([Data.AlignFig.RevertHandle ...
         Data.AlignFig.ApplyHandle ...
         Data.AlignFig.HorizHandles(1:5) ...
         Data.AlignFig.VertHandles(1:5)],'Enable','off');
    btnctrl('off',[Data.AlignFig.HorizHandles(1:5) ...
         Data.AlignFig.VertHandles(1:5)]);
      
   Data.AlignFig.Vertical={'None'};
   Data.AlignFig.Horizontal={'None'};

  end % if length
            
  set([Data.AlignFig.HorizHandles(1:5) Data.AlignFig.VertHandles(1:5)], ...
      'Value',0);
         
  set([Data.AlignFig.HorizHandles(6) Data.AlignFig.VertHandles(6)], ...
      'Enable','off');
  
  Data.AlignFig.CurrentHandles=NewHandles;
  Data.AlignFig.OrigPositions=get(NewHandles,{'Position'});
  
  statmsg(AlignFig,Message);

end % if ~all                  

%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalAlign %%%%%
%%%%%%%%%%%%%%%%%%%%%%
function varargout= LocalAlign(HandleList,HorizontalAlignment, ...
                                VerticalAlignment,SetFlag);
% Calculate alignment

%%% set all units to points
if all(ishandle(HandleList))&~isempty(HandleList), % Handles passed in
  AllHandles=HandleList;
  HandleList=LocalGetValidHandles(AllHandles);
  NumObjs=size(HandleList,1);
  HandleFlag=1;
  Units=get(HandleList,{'Units'});
  set(HandleList,'Units','points');
  Pos=get(HandleList,{'Position'});
  Position=cat(1,Pos{:});

else,
  NumObjs=size(HandleList,1);
  HandleFlag=0;
  Position=HandleList;

end % if all

if ~isempty(Position),
  HPos=LocalGetHorizontalPosition(Position,HorizontalAlignment);   
  VPos=LocalGetVerticalPosition(Position,VerticalAlignment);   
  Position=[HPos(:,1) VPos(:,2) HPos(:,3) VPos(:,4)];
end % if ~isempty

if HandleFlag,
  if ~SetFlag,
    OldPos=get(HandleList,{'Position'});
  end % if ~SetFlag
  
  %% convert from matrix to cell array
  TempPos=num2cell(Position,2);
  set(HandleList,{'Position'},TempPos);
  
  %%% set all units back to previous value and get new position matrix
  set(HandleList,{'Units'},Units);

  Pos=get(HandleList,{'Position'});Position=cat(1,Pos{:});

  if ~SetFlag,
    clear Position
    Pos=get(HandleList,{'Position'});Position=cat(1,Pos{:});
    %%% This line sets units to points, replaces the original positions
    %%% and then sets the units back to the original value.
    set(HandleList,'Units','points',{'Position'},OldPos,{'Units'},Units);
  end % if ~SetFlag
  
end % if HandleFlag

if nargout, 
  varargout(1)={Position};
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalGetValidHandles %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function NewHandles=LocalGetValidHandles(HandleList);          
% Make sure all handles are valid

NewHandles=HandleList(ishandle(HandleList));
if ~isempty(NewHandles),  
  TypeList=get(NewHandles,{'Type'});
  Loc=[strmatch('axes',TypeList);strmatch('uicontrol',TypeList)];
  NewHandles=NewHandles(Loc);  
end  

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalChooseHorizontal %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=LocalChooseHorizontal(Data,Alignment)
% Make a horizontal alignment selection
NoneFlag=0;
if nargin==1,
  Handle=gcbo;
else,  
  Handle=findobj(Data.AlignFig.HorizHandles,'Tag',Alignment{1});
end  

if isempty(Handle),
  NoneFlag=1;
else,    
  EditFlag=0;  
  Row=find(Data.AlignFig.HorizHandles==Handle);
  Handle=Data.AlignFig.HorizHandles(Row);  
  if Handle==Data.AlignFig.HorizHandles(6),
    EditFlag=1;Row=Row-1;
    Handle=Data.AlignFig.HorizHandles(5);
  end  
  
  Horizontal=get(Handle,{'Tag'});
  if ~EditFlag & strcmp(Horizontal{:},Data.AlignFig.Horizontal{1}),
    Data.AlignFig.Horizontal={'None'};
    Data.AlignFig.ChangeModeH=0;
    NoneFlag=1;    
  else,
    Data.AlignFig.Horizontal=Horizontal;
    Data.AlignFig.ChangeModeH=1;
  end
  
  if strcmp(Data.AlignFig.Horizontal{:},'Fixed'),
    Data.AlignFig.Horizontal= ...
        {'Fixed',eval(get(Data.AlignFig.HorizHandles(6),'String'))};
  end % if
  
  Data.AlignFig.OrigPositions=get(Data.AlignFig.CurrentHandles,{'Position'});

end    
  
set(Data.AlignFig.HorizHandles(1:5),'Value',0);

if ~NoneFlag,
  set(Data.AlignFig.HorizHandles(Row),'Value',1);
  if Handle==Data.AlignFig.HorizHandles(5),
    set(Data.AlignFig.HorizHandles(6),'Enable','on'); 
  else
    set(Data.AlignFig.HorizHandles(6),'Enable','off');
  end  

else,
    set(Data.AlignFig.HorizHandles(6),'Enable','off');
end  

if length(Data.AlignFig.CurrentHandles)>1,
  set(Data.AlignFig.ApplyHandle,'Enable','on');
  set(Data.AlignFig.RevertHandle,'Enable','off');
end  

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalChooseVertical %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Data=LocalChooseVertical(Data,Alignment)
% Make a vertical alignment selection
NoneFlag=0;
if nargin==1,
  Handle=gcbo;
else,  
  Handle=findobj(Data.AlignFig.VertHandles,'Tag',Alignment{1});
end

if isempty(Handle),
  NoneFlag=1;
else,    
  EditFlag=0;  
  Row=find(Data.AlignFig.VertHandles==Handle);
  Handle=Data.AlignFig.VertHandles(Row);
  if Handle==Data.AlignFig.VertHandles(6),
    EditFlag=1;Row=Row-1;
    Handle=Data.AlignFig.VertHandles(5);
  end  
  Vertical=get(Handle,{'Tag'});
  if ~EditFlag & strcmp(Vertical{:},Data.AlignFig.Vertical{1}),
    Data.AlignFig.Vertical={'None'};
    Data.AlignFig.ChangeModeV=0;
    NoneFlag=1;    
  else,
    Data.AlignFig.Vertical=Vertical;
    Data.AlignFig.ChangeModeV=1;
  end
  
  if strcmp(Data.AlignFig.Vertical{:},'Fixed'),
    Data.AlignFig.Vertical= ...
        {'Fixed',eval(get(Data.AlignFig.VertHandles(6),'String'))};
  end % if  
  
  Data.AlignFig.OrigPositions=get(Data.AlignFig.CurrentHandles,{'Position'});
end    
  
set(Data.AlignFig.VertHandles(1:5),'Value',0);
if ~NoneFlag,
  set(Data.AlignFig.VertHandles(Row),'Value',1);

  if Handle==Data.AlignFig.VertHandles(5),
    set(Data.AlignFig.VertHandles(6),'Enable','on');
  else
    set(Data.AlignFig.VertHandles(6),'Enable','off');
  end  
  
else,
    set(Data.AlignFig.VertHandles(6),'Enable','off');
end  


if length(Data.AlignFig.CurrentHandles)>1,
  set(Data.AlignFig.ApplyHandle,'Enable','on');
  set(Data.AlignFig.RevertHandle,'Enable','off');
end  


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalGetHorizontalPosition %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Position=LocalGetHorizontalPosition(Position,Alignment)
% Determine new horizontal positions
Align=Alignment{1};

switch lower(Align),
  case 'left',
    Position(:,1)=min(Position(:,1));
    
  case 'center',
    MinVal=min(Position(:,1));
    MaxVal=max(sum(Position(:,[1 3])'));
    CtrVal=(MinVal+MaxVal)/2;
    Position(:,1)=CtrVal-Position(:,3)/2;
    
  case 'right',
    MaxVal=max(sum(Position(:,[1 3])'));
    Position(:,1)=MaxVal-Position(:,3);
    
  case 'distribute',
    Gap=LocalCalcGap(Position,1);
    Position=LocalCalcPos(Position,Gap,1);
      
  case 'fixed',
    Gap=Alignment{2};
    Position=LocalCalcPos(Position,Gap,1);
            
end % switch

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalGetVerticalPosition %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Position=LocalGetVerticalPosition(Position,Alignment)
% Determine new vertical positions

Align=Alignment{1};

switch lower(Align),
  case 'top',
    MaxVal=max(sum(Position(:,[2 4])'));
    Position(:,2)=MaxVal-Position(:,4);
    
  case 'middle',
    MinVal=min(Position(:,2));
    MaxVal=max(sum(Position(:,[2 4])'));
    CtrVal=(MinVal+MaxVal)/2;
    Position(:,2)=CtrVal-Position(:,4)/2;
    
  case 'bottom',
    Position(:,2)=min(Position(:,2));
    
  case 'distribute',
    Gap=LocalCalcGap(Position,2);
    Position=LocalCalcPos(Position,Gap,2);
      
  case 'fixed',
    Gap=Alignment{2};
    Position=LocalCalcPos(Position,Gap,2);
      
end % switch

%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalCalcPos %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%
function NewPosition=LocalCalcPos(Position,Gap,HV);
% Calculate compress gaps positions

[TempPos,Index]=sortrows(Position,HV);
NumObjs=size(TempPos,1);
%% V5 LPD This could be sped up
for ObjLp=2:NumObjs,
  TempPos(ObjLp,HV)=sum(TempPos(ObjLp-1,[HV HV+2])')+Gap;
end
[junk,UnsortIndex]=sort(Index);
NewPosition=TempPos(UnsortIndex,:);

%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalCalcGap %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%
function Gap=LocalCalcGap(Position,HV)
% Calculate distribute gaps positions

MinVal=min(Position(:,HV));
MaxVal=max(sum(Position(:,[HV HV+2])'));
NumObjs=size(Position,1);
Width=sum(Position(:,HV+2));
Gap=(MaxVal-MinVal-Width)/(NumObjs-1);



%%%%%%%%%%%%%%%%%%% 
%%% LocalResize %%%
%%%%%%%%%%%%%%%%%%%        
function LocalResize(Data,AlignFig)

AlignFigChild=findall(AlignFig);
StatusHandle=findobj(AlignFigChild,'flat','Tag','Status');
ListHandle=findobj(AlignFigChild,'flat','Tag','Square');

set([AlignFig StatusHandle Data.AlignFig.ButtonHandles ListHandle ...
     Data.AlignFig.TextHandles ...
     Data.AlignFig.HorizHandles Data.AlignFig.VertHandles], ...
    'Units','points');

FigPos=get(AlignFig,'Position');
TempFigPos=FigPos;

StatusPos=get(StatusHandle,'Position');
ListPos=get(ListHandle,'Position');

ButtonPos=get(Data.AlignFig.ButtonHandles,{'Position'});
ButtonPos=cat(1,ButtonPos{:});

HRadioPos=get(Data.AlignFig.HorizHandles,{'Position'});
HRadioPos=cat(1,HRadioPos{:});

VRadioPos=get(Data.AlignFig.VertHandles,{'Position'});
VRadioPos=cat(1,VRadioPos{:});

TextPos=get(Data.AlignFig.TextHandles,{'Position'});
TextPos=cat(1,TextPos{:});

HOffset=max(1,StatusPos(1));
VOffset=max(1,StatusPos(2));

ButtonWidth=min(Data.AlignFig.ButtonWidth,(FigPos(3)-5*HOffset)/4);
ButtonHeight=Data.AlignFig.ButtonHeight;

StatusPos(4)=ButtonHeight;

ButtonPos(end,1)=sum(StatusPos(1,[1 3]))-ButtonWidth;
ButtonPos(:,2)=sum(StatusPos(1,[2 4]))+VOffset;
ButtonPos(:,3)=ButtonWidth;
ButtonPos(:,4)=ButtonHeight;
ButtonPos=align(ButtonPos,'Distribute','None');

HRadioPos(1:5,2)=sum(ButtonPos(1,[2 4]))+VOffset;
HRadioPos(1:5,3:4)=Data.AlignFig.RadioHeight;
HRadioPos(6:7,2)=sum(HRadioPos(1,[2 4]))-ButtonHeight;
HRadioPos(6:7,4)=ButtonHeight;

VRadioPos(1:5,2)=sum(HRadioPos(1,[2 4]))+VOffset;
VRadioPos(1:5,3:4)=HRadioPos(1,4);
VRadioPos(6:7,2)=sum(VRadioPos(1,[2 4]))-ButtonHeight;
VRadioPos(6:7,4)=ButtonHeight;

TextPos(:,2)=sum(VRadioPos(1,[2 4]));
TextPos(:,4)=ButtonHeight;

ListPos(2)=sum(TextPos(1,[2 4]))+VOffset;
ListPos(4)=max(50,FigPos(4)-VOffset-ListPos(2));

ButtonPos=num2cell(ButtonPos,2);
HRadioPos=num2cell(HRadioPos,2);
VRadioPos=num2cell(VRadioPos,2);
TextPos=num2cell(TextPos,2);

set(StatusHandle,'Position',StatusPos);
set(ListHandle,'Position',ListPos);
set(Data.AlignFig.HorizHandles,{'Position'},HRadioPos);
set(Data.AlignFig.VertHandles,{'Position'},VRadioPos);
set(Data.AlignFig.ButtonHandles,{'Position'},ButtonPos);
set(Data.AlignFig.TextHandles,{'Position'},TextPos);

set([StatusHandle Data.AlignFig.ButtonHandles ListHandle ...
     Data.AlignFig.TextHandles ...
     Data.AlignFig.HorizHandles Data.AlignFig.VertHandles], ...
     'Units','normalized');

%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalInitFig %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%
function Data=LocalInitFig(HandleList,SetFlag,CustomList,AlignFig)

[HandleFlag,Data]=gnrlfun('InitializeHandles',AlignFig,HandleList);

if strcmp(studio,'on'),
  warning('Alignment Tool must be initialized from Layout Menu on figure');
  delete(Data.All.HiddenFigure);
  return
end % if strcmp java

if HandleFlag==2,Data=guide('HandleUpdate',Data);return;end

CustomFlag=0;
CustomList={};

% Set up colors
White=[1 1 1];Black=[0 0 0];

%%% Set up positions
Offset=3;
FigWidth=200;

AlignDir=which('align');
AlignDir=AlignDir(1:end-8);
load(fullfile(AlignDir,'private','algnbtn'))

RadioHeight=1;
RadioWidth=1;
for tlp=1:length(AlignData),
  CurSize=size(AlignData(tlp).data);
  RadioHeight=max(RadioHeight,CurSize(1)+6);
  RadioWidth=max(RadioWidth,CurSize(2)+6);
end

ButtonHeight=20;
ButtonWidth=50;

StatusPos=[Offset Offset 0 ButtonHeight];
ButtonPos=[StatusPos(1) sum(StatusPos(1,[2 4]))+Offset ...
           ButtonWidth ButtonHeight];
ButtonPos=ButtonPos(ones(4,1),:);
ButtonPos([2 3],1)=ButtonPos([2 3],1)+[1;2];
RadioPos=[ButtonPos(1,1) sum(ButtonPos(1,[2 4]))+Offset ...
          RadioWidth     RadioHeight
         ];
RadioPos=RadioPos(ones(7,1),:);
RadioPos(6:7,3)=RadioWidth;
RadioPos(2:end,1)=10000;
RadioPos(1:3,:)=align(RadioPos(1:3,:),'Fixed',0,'Bottom');
RadioPos(3:5,:)=align(RadioPos(3:5,:),'Fixed',3*Offset,'Bottom');
RadioPos(5:7,:)=align(RadioPos(5:7,:),'Fixed',0,'Bottom');
RadioPos=[RadioPos;RadioPos];
RadioPos(8:end,2)=sum(RadioPos(1,[2 4]))+Offset;

TextPos=zeros(3,4);
TextPos(:,1)=RadioPos([1 4 5],1);
TextPos(:,2)=sum(RadioPos(end,[2 4]));
TextPos(:,3)=[3*RadioWidth;RadioWidth;3*RadioWidth];
TextPos(:,4)=ButtonHeight;
TextPos(2,1)=sum(TextPos(1,[1 3]))-5;
TextPos(2,3)=diff(TextPos([2 3],1))+10;
ListPos=[RadioPos(1,1) sum(TextPos(1,[2 4]))+Offset 0 115];
 
GapPos=RadioPos([6 7 13 14],:);
GapPos(:,2)=GapPos(:,2)+GapPos(:,4)-ButtonHeight;
GapPos(:,4)=ButtonHeight;
RadioPos([6 7 13 14],:)=[];


FigHeight=sum(ListPos(1,[2 4]))+Offset;
[FigHoriz,FigVert]=gnrlfun('GetFigPos',FigHeight,Data);
FigWidth=sum(GapPos(end,[1 3]))+Offset;
FigPos=[FigHoriz FigVert FigWidth FigHeight];

StatusPos(3)=FigWidth-2*Offset;
ListPos(3)=StatusPos(3);
ButtonPos(4,1)=FigWidth-ButtonWidth-Offset;
ButtonPos=align(ButtonPos,'Distribute','None');


%%% Other Info
FigColor=get(0,'defaultuicontrolbackgroundcolor');

          
FontSize=get(0,'FactoryUIControlFontSize');
ButtonTags={'Help';'Revert';'Apply';'Close'};
ButtonTips={'';'';'';''};
ButtonStrings=ButtonTags;

ButtonInfo.Style='pushbutton';
ButtonInfo.BackGroundColor=FigColor;
ButtonInfo.Units='points';
ButtonInfo.HandleVisibility='off';
ButtonInfo.ForeGroundColor=Black;
ButtonInfo.BusyAction='queue';
ButtonInfo.FontSize=FontSize; 
ButtonInfo.HorizontalAlignment='center';
            
ButtonCall={'align Help' ;'align Revert'
            'align Apply';'align Close'};

StatusInfo=ButtonInfo;
StatusInfo.Style='text';
StatusInfo.BackgroundColor=White;

StatusTag='Status';
StatusTip='';

TextInfo=ButtonInfo;TextInfo.FontSize=FontSize+2;
TextStrings={'Align';'Distribute';'Set Spacing'};
TextTags={'AlignText';'DistributeText';'SpacingText'};
TextTips={'';'';''};

ListInfo=ButtonInfo;
ListInfo.Max=2;
ListInfo.FontName='FixedWidth';

ListInfo.Style='listbox';
ListInfo.BackgroundColor=FigColor;
ListInfo.HorizontalAlignment='left';

GapInfo=ButtonInfo;
GapInfo.HorizontalAlignment='left';
GapStyle={'edit'      ;'text'};
GapStyle=[GapStyle;GapStyle];
GapStrings={'0';'points';'0';'points'};
GapTags={'Horizontal Value';'Horizontal Text'
         'Vertical Value'  ;'Vertical Text'};
GapTips={'';'';'';''};
GapCall={'align ChooseHorizontal';'';'align ChooseVertical';''};


RadioInfo=GapInfo;
RadioInfo.String='';
RadioInfo.Style='togglebutton';
           
RadioGroup={'Horizontal';'Horizontal';'Horizontal';'Horizontal';'Horizontal'
            'Vertical';'Vertical';'Vertical';'Vertical';'Vertical'
           };
RadioTags={'Left';'Center';'Right' ;'Distribute';'Fixed'
               'Top' ;'Middle';'Bottom';'Distribute';'Fixed'
          };
RadioTips={'Horizontal Align Left'   ;'Horizontal Align Center'
           'Horizontal Align Right'  ;'Horizontal Distribution'
           'Horizontal Fixed Spacing'
           'Vertical Align Bottom'   ;'Vertical Align Middle'
           'Vertical Align Top'      ;'Vertical Distribution'
           'Vertical Fixed Spacing'
           };
for RLp=1:size(RadioGroup,1),
  RadioCall{RLp,1}=['align Choose' RadioGroup{RLp,1}];
end % for

NumClr=size(AlignMap,1);
Index=ismember(AlignMap,FigColor,'rows');
if ~any(Index),
  NumClr=NumClr+1;
  AlignMap=[AlignMap;FigColor];
  Index=size(AlignMap,1);  
end  
DisableMap=linspace(.6,.4,NumClr)';
DisableMap=DisableMap(:,ones(1,3));
DisableMap(Index,:)=FigColor;

Map=[AlignMap;DisableMap];

% set up tool
MenuBar='none';

MenuInfo.HandleVisibility='off';
MenuInfo.Interruptible='off';
MenuInfo.BusyAction='queue';
         
%%% Create the menu options
MenuFileLabels={'File'               
               '>Close Alignment Tool'
               };
MenuFileTags={'MenuFile'
              'MenuFileCloseTool'
             };
             
MenuFileCalls=[{''};{'align Close'}];

[MenuToolsLabels,MenuToolsCalls,MenuToolsTags]= ...
    gnrlfun('AddToolsMenu','Alignment Tool');

[MenuHelpLabels,MenuHelpCalls,MenuHelpTags]= ...
    gnrlfun('AddHelpMenu','Alignment Tool');

MenuInfoLabels=[MenuFileLabels ;MenuToolsLabels;MenuHelpLabels];
MenuInfoTags  =[MenuFileTags   ;MenuToolsTags;MenuHelpTags];
MenuInfoCalls =[MenuFileCalls  ;MenuToolsCalls;MenuHelpCalls];
             
MenuInfoLabels=char(MenuInfoLabels);
MenuInfoTags=char(MenuInfoTags);
MenuInfoCalls=char(MenuInfoCalls);

drawnow  
AlignFig=figure(                 ...
               'Color'          ,FigColor              , ...
               'CreateFcn'      ,''                    , ...
               'IntegerHandle'  ,'off'                 , ...
               'CloseRequestFcn','align Close'         , ...
               'MenuBar'        ,MenuBar               , ...
               'Name'           ,'Guide Alignment Tool', ...
               'Tag'            ,'Guide Alignment Tool', ...
               'NumberTitle'    ,'off'                 , ...
               'Units'          ,'points'              , ...
               'Position'       ,FigPos                , ...
               'Resize'         ,'on'                  , ...
               'UserData'       ,[]                    , ...
               'Colormap'       ,Map                   , ...
               'Visible'        ,'off'                   ...
               );

MenuHandles=makemenu(AlignFig,MenuInfoLabels,MenuInfoCalls,MenuInfoTags);
set(MenuHandles,MenuInfo);
set(MenuHandles(end-11),'Enable','off');

StatusHandle=uicontrol(StatusInfo, ...
                      'Parent'        ,AlignFig        , ...
                      'Position'      ,StatusPos       , ...
                      'TooltipString' ,StatusTip       , ...
                      'Tag'           ,StatusTag         ...
                      );


for BLp=1:size(ButtonTags,1),
  ButtonHandles(BLp)=uicontrol(ButtonInfo     , ...
                              'Parent'        ,AlignFig            , ...
                              'Position'      ,ButtonPos(BLp,:)    , ...
                              'Tag'           ,ButtonTags{BLp,1}   , ...
                              'TooltipString' ,ButtonTips{BLp,1}  , ...
                              'Callback'      ,ButtonCall{BLp,1}   , ...
                              'String'        ,ButtonStrings{BLp,1}  ...
                              );
end % BLp
set(ButtonHandles(2),'Enable','off')
for RLp=1:size(RadioTags,1),
  ImageData=gnrlfun('Ind2RGB',AlignData(RLp).data,Map);
  
  RadioHandles(RLp)=uicontrol( ...
                             'Parent'       ,AlignFig           , ...
                              RadioInfo     , ...
                             'Position'     ,RadioPos(RLp,:)    , ...
                             'CData'        ,ImageData          , ....
                             'Tag'          ,RadioTags{RLp,1}   , ...
                             'TooltipString',RadioTips{RLp,1}   , ...
                             'UserData'     ,AlignData(RLp).data, ...
                             'Callback'     ,RadioCall{RLp,1}     ...
                             );
end

for GLp=1:size(GapTags,1),
  GapHandles(GLp)=uicontrol(GapInfo   , ...
                           'Parent'   ,AlignFig           , ...
                           'Style'    ,GapStyle{GLp,1}    , ...
                           'Position' ,GapPos(GLp,:)      , ...
                           'String'   ,GapStrings{GLp,1}  , ...
                           'Callback' ,GapCall{GLp,1}     , ...
                           'TooltipString' ,GapTips{GLp,1}, ...
                           'Tag'      ,GapTags{GLp,1}       ...
                           );
end % GLp
set(GapHandles([1 3]), ...
   'Enable'          ,'off' , ...
   'BackgroundColor' ,White   ...
   );

for TLp=1:size(TextTags,1),
  TextHandles(TLp)=uicontrol(TextInfo      , ...
                            'Parent'       ,AlignFig           , ...
                            'Style'        ,'text'             , ...
                            'Position'     ,TextPos(TLp,:)     , ...
                            'String'       ,TextStrings{TLp,1} , ...
                            'Tag'          ,TextTags{TLp,1}      ...
                            );
end % TLp
FigHandles=allchild(AlignFig);
FigHandles(1:3)=FigHandles([2 1 3]); % Reorder so Distribute appears on MAC
set(AlignFig,'Children',FigHandles);

ListHandle=uicontrol(ListInfo     , ...
                    'Parent'      ,AlignFig                    , ...
                    'Position'    ,ListPos(1,:)                , ...
                    'String'      ,' '                         , ...      
                    'Callback'    ,'align BrowserButtonDown'   , ...
                    'TooltipString',''                         , ...
                    'Tag'         ,'Square'                      ...
                    );

set([ListHandle GapHandles ButtonHandles  ...
     StatusHandle TextHandles RadioHandles],'Units','normalized');

% Common UserData Settings
if isempty(Data.All.DataHandle),
  Data.All.DataHandle=AlignFig;
end  

Data.All.CustomFlag=CustomFlag;
Data.All.CustomList=CustomList;
 
Data.All.Browser.Handles=[Data.All.Browser.Handles;ListHandle];
Data.All.Browser.Square=[Data.All.Browser.Square;ListHandle];

Data.AlignFig.ButtonWidth=ButtonWidth;
Data.AlignFig.ButtonHeight=ButtonHeight;
Data.AlignFig.ButtonHandles=ButtonHandles;
Data.AlignFig.ListboxHandle=ListHandle;
Data.AlignFig.ChangeModeH=0;
Data.AlignFig.ChangeModeV=0;
Data.AlignFig.CurrentHandles=[];
Data.AlignFig.OrigPositions={};
Data.AlignFig.Horizontal={'None'};
Data.AlignFig.Vertical={'None'};
Data.AlignFig.RadioOffset=Offset;
Data.AlignFig.RadioHeight=RadioHeight;
Data.AlignFig.RadioWidth=RadioWidth;
Data.AlignFig.RevertHorizontal={'None'};
Data.AlignFig.RevertVertical={'None'};
Data.AlignFig.RevertHandle=ButtonHandles(2);
Data.AlignFig.TextHandles=TextHandles;
Data.AlignFig.ApplyHandle=ButtonHandles(3);
Temp=[RadioCall RadioCall RadioCall];
Data.AlignFig.ButtonDown=Temp(:);

Data.AlignFig.HorizHandles=[RadioHandles(1:5),GapHandles(1:2)];
Data.AlignFig.VertHandles=[RadioHandles(6:10),GapHandles(3:4)];

set(AlignFig,'HandleVisibility','off');

Data=guide('ToolUpdate',Data,AlignFig,'add');
if Data.All.DataHandle~=AlignFig,
  DataFig.All.DataHandle=Data.All.DataHandle;
  set(AlignFig,'UserData',DataFig);
  if length(Data.All.Browser.Complete)<1,% No other tool with a complete 
                                         % browser is open
    Data=objbrwser('CreateInitialMapping',Data);
  else,
    Data=objbrwser('SetBrowserString',Data,'Square');
  end    
else, % This is the first open tool  
  Data=objbrwser('CreateInitialMapping',Data);
  Data=gnrlfun('TakeGeneralControl',Data);
end

set(AlignFig,'Visible','on');
drawnow
set(AlignFig,'ResizeFcn','align Resize');

if HandleFlag,
  Data=guide('SelectionUpdate',Data,[]);
else,
  set(Data.All.DataHandle,'UserData',Data);  
  align Update  
end  
