function [varargout]=nic_rest_sliceviewer(AOperation, varargin)
% Show a brain's slice. "rest_sliceviewer" can be opened more than one instance like MRIcro, and supports multi-slice, overlay and so on. by Xiao-Wei Song
%Usage: hFig =nic_rest_sliceviewer('ShowImage', AFilename, CallBack);
%           nic_rest_sliceviewer('Delete', AFigHandle);
%Detailed usage is the code file "nic_rest_sliceviewer.m"
%------------------------------------------------------------------------------------------------------------------------------
%	Copyright(c) 2007~2010
%	State Key Laboratory of Cognitive Neuroscience and Learning in Beijing Normal University
%	Written by Xiao-Wei Song 
%	http://resting-fmri.sourceforge.net
% 	Mail to Authors:  <a href="Dawnwei.Song@gmail.com">Xiaowei Song</a>; <a href="ycg.yan@gmail.com">Chaogan Yan</a> 
%	Version=1.3;
%	Release=20080808;
%   Revised by YAN Chao-Gan 080610: NIFTI compatible
%   Modified by Yan Chao-Gan 080808: also support NIFTI (.img/.hdr) images.
%   Last Modified by Yan Chao-Gan 080903: also support NIFTI (.nii) images.
%--------------------------------------------------------------------------
%   Copyright (C) 2009 Neuroimage Computing Group, State Key Laboratory of
%   Cognitive Neuroscience and Learning
%	Revised by Gwen Chen
%	Update date: 20090918
%-----------------------------------------------------------

if nargin<1, %No param Launch, 20070918
% 	help(mfilename);
	if nargout>=1,
		varargout{1}=nic_rest_sliceviewer('ShowImage','');	%by Default, I show a black brain image
	else
		nic_rest_sliceviewer('ShowImage','');	%by Default, I show a black brain image
	end
	return; 
end

%Initializitation
persistent nic_rest_sliceviewer_Cfg; % run-time persistent config
%if isempty(nic_rest_sliceviewer_Cfg), disp('ko'); end
if ~mislocked(mfilename),mlock; end
%For further Debug, 20070915, to make sure the Config variable exist
% if isempty(nic_rest_sliceviewer_Cfg), 
	% nic_rest_sliceviewer_Cfg =getappdata(0, 'nic_rest_sliceviewer_Cfg');
% else
	% setappdata(0, 'nic_rest_sliceviewer_Cfg', nic_rest_sliceviewer_Cfg);
% end

try
	switch upper(AOperation),
	case 'SHOWIMAGE',	%ShowImage
		if nargin==2,
			%nic_rest_sliceviewer('ShowImage', theBrainMap); %reho_gui.m 989
			AFilename =varargin{1};
			ACallback ='';		
            nic_rest_sliceviewer_Cfg.convertToZ=0;
            nic_rest_sliceviewer_Cfg.returnValue=2;
	    elseif nargin==3,
			%nic_rest_sliceviewer('ShowImage', theBrainMap, [theCallback cmdClearVar], 'Power Spectrum');%reho_gui.m 1010
			AFilename =varargin{1};
			ACallback =varargin{2};
            if(isstruct(ACallback) && isfield(ACallback,'convertToZ'))
                nic_rest_sliceviewer_Cfg.convertToZ=1;
            else
                nic_rest_sliceviewer_Cfg.convertToZ=0;
            end
            if(isstruct(ACallback) && isfield(ACallback,'returnValue'))
                nic_rest_sliceviewer_Cfg.returnValue=ACallback.returnValue;
            else
                nic_rest_sliceviewer_Cfg.returnValue=2;
            end
		else
			error(sprintf('Usage: hFig =nic_rest_sliceviewer(''ShowImage'', AFilename); \n\t hFig =nic_rest_sliceviewer(''ShowImage'', AFilename, ACallback);')); 
		end
	    
		%Let current handle of the figure be a GUID for the current SliceViewer
		% theFig =ExistDisplayFigure(nic_rest_sliceviewer_Cfg, AFilename);
		% isExistFig =nic_rest_misc( 'ForceCheckExistFigure' , theFig);	%Force check whether the figure exist
		% if ~isExistFig
			%the specific image didn't exist, so I create one
			nic_rest_sliceviewer_Cfg.Config(1+GetDisplayCount(nic_rest_sliceviewer_Cfg)) =InitControls(AFilename, ACallback);
			%To Force display following the end of this if-clause
			theFig =nic_rest_sliceviewer_Cfg.Config(GetDisplayCount(nic_rest_sliceviewer_Cfg)).hFig;
            
            nic_rest_sliceviewer_Cfg.Config(GetDisplayCount(nic_rest_sliceviewer_Cfg)).convertToZ=nic_rest_sliceviewer_Cfg.convertToZ;
            nic_rest_sliceviewer_Cfg.Config(GetDisplayCount(nic_rest_sliceviewer_Cfg)).returnValue=nic_rest_sliceviewer_Cfg.returnValue;
            nic_rest_sliceviewer_Cfg.Config(GetDisplayCount(nic_rest_sliceviewer_Cfg)).Overlay.Colormap	=icatb_getColormap(1,nic_rest_sliceviewer_Cfg.returnValue,0);%jet(64);
			
			%I don't display the information defaultly
			ToggleInfoDisplay(nic_rest_sliceviewer_Cfg.Config(GetDisplayCount(nic_rest_sliceviewer_Cfg)));
		% end
		figure(theFig);	
		varargout{1} =theFig;
			
	case 'UPDATECALLBACK', 		%UpdateCallback
		if nargin==2, 
			AFigHandle =varargin{1};
			ACallback ='';	
			ACallbackCaption='';
		elseif nargin==3, 
			AFigHandle =varargin{1};
			ACallback =varargin{2};	
			ACallbackCaption='';
		elseif nargin==4, 
			AFigHandle =varargin{1};
			ACallback =varargin{2};	
			ACallbackCaption=varargin{3};	
		else
			error('Usage: nic_rest_sliceviewer(''UpdateCallback'', AFigureHandle, ACallback, ACallbackCaption);'); 
		end
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =UpdateCallback(nic_rest_sliceviewer_Cfg.Config(theCardinal), ACallback, ACallbackCaption);
			ResizeFigure(nic_rest_sliceviewer_Cfg.Config(theCardinal));
		end
		
		
	case 'DELETE', % Delete specific figure
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''Delete'', AFigHandle);'); end
		AFigHandle =varargin{1};
		nic_rest_sliceviewer_Cfg =DeleteFigure(nic_rest_sliceviewer_Cfg, AFigHandle);
		
		if ~GetDisplayCount(nic_rest_sliceviewer_Cfg),
			nic_rest_sliceviewer('QuitAllSliceViewer');
		end
		
	case {'CLICKPOSITION', 'SETPOSITION'},		%ClickPosition	%SetPosition
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''ClickPosition'', AFigHandle); or nic_rest_sliceviewer(''SetPosition'', AFigHandle);'); end
		AFigHandle =varargin{1};
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0
			if strcmpi(AOperation, 'ClickPosition'),	% for Mouse click
				if strcmpi(nic_rest_sliceviewer_Cfg.Config(theCardinal).ViewMode, 'Orthogonal'),
					nic_rest_sliceviewer_Cfg.Config(theCardinal) =ClickPositionCrossHair(nic_rest_sliceviewer_Cfg.Config(theCardinal));		
				elseif strcmpi(nic_rest_sliceviewer_Cfg.Config(theCardinal).ViewMode, 'Sagittal'),
					nic_rest_sliceviewer_Cfg.Config(theCardinal) =ClickPositionInSagittalMode(nic_rest_sliceviewer_Cfg.Config(theCardinal));
				elseif strcmpi(nic_rest_sliceviewer_Cfg.Config(theCardinal).ViewMode, 'Coronal'),
					nic_rest_sliceviewer_Cfg.Config(theCardinal) =ClickPositionInCoronalMode(nic_rest_sliceviewer_Cfg.Config(theCardinal));
				elseif strcmpi(nic_rest_sliceviewer_Cfg.Config(theCardinal).ViewMode, 'Transverse'),
					nic_rest_sliceviewer_Cfg.Config(theCardinal) =ClickPositionInTransverseMode(nic_rest_sliceviewer_Cfg.Config(theCardinal));
				end
			elseif strcmpi(AOperation, 'SetPosition'), % for [x y z] manual input
				nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetPositionCrossHair(nic_rest_sliceviewer_Cfg.Config(theCardinal));
			end		
					
			
			%If yoke, then update all yoked image
			isSelfYoked =get(nic_rest_sliceviewer_Cfg.Config(theCardinal).hYoke, 'Value');
			if isSelfYoked ,
				theDistanceFromOrigin =(nic_rest_sliceviewer_Cfg.Config(theCardinal).LastPosition -nic_rest_sliceviewer_Cfg.Config(theCardinal).Origin) .* nic_rest_sliceviewer_Cfg.Config(theCardinal).VoxelSize;
				%Dawnsong 20071102 Revise to make sure the left image/Right brain is +
				theDistanceFromOrigin =[-1, 1, 1].* theDistanceFromOrigin;
				
				for x=1:GetDisplayCount(nic_rest_sliceviewer_Cfg), 
					if x~=theCardinal ,
						isYoked =get(nic_rest_sliceviewer_Cfg.Config(x).hYoke, 'Value');
						if isYoked, 							
							nic_rest_sliceviewer('SetPhysicalPosition', nic_rest_sliceviewer_Cfg.Config(x).hFig, theDistanceFromOrigin);
						end
					end
				end
			end	
			
			%Execute the Callback
			nic_rest_sliceviewer('RunCallback', AFigHandle);			
		end
		
	case 'SETPHYSICALPOSITION',		%SetPhysicalPosition, for Yoke, the physical position(mm) from the origin
		if nargin~=3, error('Usage: nic_rest_sliceviewer(''SetPhysicalPosition'', AFigHandle, ADistanceFromOrigin);'); end
		AFigHandle =varargin{1};
		ADistanceFromOrigin =varargin{2};
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			%Dawnsong 20071102 Revise to make sure the left image/Right brain is +
			ADistanceFromOrigin =[-1, 1, 1].* ADistanceFromOrigin;

			nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetDistanceFromOrigin(nic_rest_sliceviewer_Cfg.Config(theCardinal), ADistanceFromOrigin);
			
			%Execute the Callback
			nic_rest_sliceviewer('RunCallback', AFigHandle);	
		end		
	case 'RUNCALLBACK', 			%RunCallback	, 20070625
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''RunCallback'', AFigHandle);'); end
		AFigHandle =varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0		
			% Run the Callback
			if ~isempty(nic_rest_sliceviewer_Cfg.Config(theCardinal).Callback) 
				if ischar(nic_rest_sliceviewer_Cfg.Config(theCardinal).Callback),
					eval(nic_rest_sliceviewer_Cfg.Config(theCardinal).Callback); %run callback for caller
				elseif isa(nic_rest_sliceviewer_Cfg.Config(theCardinal).Callback, 'function_handle')
					%I give 2 parameters, 20070624
					%1) position: X, Y , Z, 
					%2) and 3-dim: XSize, YSize, ZSize
					thePos =nic_rest_sliceviewer_Cfg.Config(theCardinal).LastPosition;
					theSize=size(nic_rest_sliceviewer_Cfg.Config(theCardinal).Volume);
					nic_rest_sliceviewer_Cfg.Config(theCardinal).Callback(thePos, theSize);
				end
			end		
		end
		
		
	case 'GETPOSITION', 		%GetPosition, return Absolute	position where current cross-hair stay
		if nargin~=2, error('Usage: Position =nic_rest_sliceviewer(''GetPosition'', AFigHandle);'); end
		AFigHandle =varargin{1};
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0
			varargout{1}=nic_rest_sliceviewer_Cfg.Config(theCardinal).LastPosition;	 
		end
		
	case 'GETPHYSICALPOSITION', 		%GetPhysicalPosition return Coordinate .* VoxelSize	(mm)
		if nargin~=2, error('Usage: DistanceFromOrigin =nic_rest_sliceviewer(''GetPhysicalPosition'', AFigHandle);'); end
		AFigHandle =varargin{1};
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0
			thePosition =nic_rest_sliceviewer_Cfg.Config(theCardinal).LastPosition;	 
			theOrigin  	=nic_rest_sliceviewer_Cfg.Config(theCardinal).Origin;
			theVoxelSize=nic_rest_sliceviewer_Cfg.Config(theCardinal).VoxelSize;
			varargout{1} =(thePosition - theOrigin) * theVoxelSize;
		end	

	case 'SETMESSAGE',			%SetMessage, update the Message, I don't contain the Copyright any more , 20070915
		if nargin~=3, error('Usage: nic_rest_sliceviewer(''SetMessage'', AFigHandle, AMessage);'); end
		AFigHandle 	=varargin{1};
		AMessage	=varargin{2};
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0
			nic_rest_sliceviewer_Cfg.Config(theCardinal).Message =AMessage;
			SetMessage(nic_rest_sliceviewer_Cfg.Config(theCardinal));
			ResizeFigure(nic_rest_sliceviewer_Cfg.Config(theCardinal));
		end	
		
	case 'MAGNIFY', 		%Magnify, x0.5 -x1 -x2 -x3 -x4 -x5 -x6
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''Magnify'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));			
		end	
		
	case 'QUITALLSLICEVIEWER',		%QuitAllSliceViewer
		if nargin~=1, error('Usage: nic_rest_sliceviewer(''QuitAllSliceViewer'');'); end
		for x=GetDisplayCount(nic_rest_sliceviewer_Cfg):-1:1, % DawnSong, revised 20070625
			nic_rest_sliceviewer('DELETE', nic_rest_sliceviewer_Cfg.Config(x).Filename);
		end
		if mislocked(mfilename),munlock; end
		clear nic_rest_sliceviewer_Cfg;
		
	case 'MONTAGE', 		%Montage	
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''Montage'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			prompt ={'Across: (i.e. the number of columns)', 'Down: (i.e. the number of rows)', 'Spacing(voxels): ', 'Whether to show coordinate''s label: (1=yes and 0=no.)'};
			def	={	int2str(nic_rest_sliceviewer_Cfg.Config(theCardinal).Montage.Across), ...
					int2str(nic_rest_sliceviewer_Cfg.Config(theCardinal).Montage.Down), ...
					int2str(nic_rest_sliceviewer_Cfg.Config(theCardinal).Montage.Spacing), ...
					int2str(nic_rest_sliceviewer_Cfg.Config(theCardinal).Montage.WantLabel)};
			answer =inputdlg(prompt, 'Montage Set', 1, def);
			if numel(answer)==4,
				theVal =abs(round(str2num(answer{1})));
				if theVal==0, theVal=1; end
				nic_rest_sliceviewer_Cfg.Config(theCardinal).Montage.Across = theVal;
				theVal =abs(round(str2num(answer{2})));
				if theVal==0, theVal=1; end
				nic_rest_sliceviewer_Cfg.Config(theCardinal).Montage.Down =theVal;
				
				nic_rest_sliceviewer_Cfg.Config(theCardinal).Montage.Spacing = abs(round(str2num(answer{3})));
				nic_rest_sliceviewer_Cfg.Config(theCardinal).Montage.WantLabel = abs(round(str2num(answer{4})));
				%Update Image Display
				nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));
			end
		end;

	case 'ORTHOGONALVIEW', 		%OrthogonalView
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''OrthogonalView'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			nic_rest_sliceviewer_Cfg.Config(theCardinal).ViewMode ='Orthogonal';
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));
		end;	
		
	case 'TRANSVERSEVIEW', 		%TransverseView
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''TransverseView'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			nic_rest_sliceviewer_Cfg.Config(theCardinal).ViewMode ='Transverse';
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));
		end;
			
	case 'SAGITTALVIEW', 		%SagittalView
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''SagittalView'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			nic_rest_sliceviewer_Cfg.Config(theCardinal).ViewMode ='Sagittal';
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));
		end;

	case 'CORONALVIEW', 		%CoronalView
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''CoronalView'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			nic_rest_sliceviewer_Cfg.Config(theCardinal).ViewMode ='Coronal';
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));
		end;

	case 'REPAINT',		%Repaint	
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''Repaint'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,		
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));
		end;
	case 'MNI/TALAIRACH',		%MNI/Talairach
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''Repaint'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,		
			Transforming_MNI_Talairach(nic_rest_sliceviewer_Cfg.Config(theCardinal));
			nic_rest_sliceviewer('SetPosition', AFigHandle);
		end;
		
	case 'CHANGEUNDERLAY', 		%ChangeUnderlay
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''ChangeUnderlay'', AFigHandle);'); end
		AFigHandle 	=varargin{1};
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			%Get the changed Underlay file
			theNewUnderlay =get(nic_rest_sliceviewer_Cfg.Config(theCardinal).hUnderlayFile, 'String');
			% if exist(theNewUnderlay,'file')==2,
			% if ~all(isspace(theNewUnderlay)),	%20070918
				%Set the current underlay
				nic_rest_sliceviewer_Cfg.Config(theCardinal).Filename =theNewUnderlay;
				nic_rest_sliceviewer_Cfg.Config(theCardinal) =InitUnderlay(nic_rest_sliceviewer_Cfg.Config(theCardinal));
				nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));
				set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hUnderlayFile, 'String', theNewUnderlay, 'TooltipString', theNewUnderlay);
			% end
		end;
		
	case 'UNDERLAYSELECTION', 		%UnderlaySelection	
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''UnderlaySelection'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,			
			[filename, pathname] = uigetfile({'*.img', 'ANALYZE or NIFTI files (*.img)';'*.nii','NIFTI files (*.nii)'}, ...
															'Pick one brain map');
			if any(filename~=0) && ischar(filename) && length(filename)>4 ,	% not canceled and legal			
				if ~strcmpi(pathname(end), filesep)%revise pathname to add \ or /
					pathname = [pathname filesep];
				end
				theBrainMap =[pathname filename];
				set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hUnderlayFile, 'String', theBrainMap);
				nic_rest_sliceviewer('ChangeUnderlay', AFigHandle);
			end			
		end;
        
     case 'UNDERLAYFILE', 		%UnderlaySelection	
		if nargin~=3, error('Usage: nic_rest_sliceviewer(''UnderlayFile'',filePath, AFigHandle);'); end
        theBrainMap 	= varargin{1};
		AFigHandle 	= varargin{2};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,			
				set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hUnderlayFile, 'String', theBrainMap);
				nic_rest_sliceviewer('ChangeUnderlay', AFigHandle);		
		end;
	case 'CLICKRECENTUNDERLAY', 	%ClickRecentUnderlay
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''ClickRecentUnderlay'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,			
			theIndex =get(nic_rest_sliceviewer_Cfg.Config(theCardinal).hUnderlayRecent, 'Value');
			if theIndex>1,
				theBrainMap =nic_rest_sliceviewer_Cfg.Config(theCardinal).Recent.Underlay{theIndex-1};
				set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hUnderlayFile, 'String', theBrainMap);
				set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hUnderlayRecent, 'Value', 1);
				nic_rest_sliceviewer('ChangeUnderlay', AFigHandle);				
			end
		end;
		
	case 'CHANGEOVERLAY', 		%ChangeOverlay
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''ChangeOverlay'', AFigHandle);'); end
		AFigHandle 	=varargin{1};
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			%Get the changed Overlay file
			theNewOverlay =get(nic_rest_sliceviewer_Cfg.Config(theCardinal).hOverlayFile, 'String');
			% if exist(theNewOverlay,'file')==2,
			% if ~all(isspace(theNewOverlay)),
				%Set the current Overlay
				nic_rest_sliceviewer_Cfg.Config(theCardinal) =LoadOverlay(nic_rest_sliceviewer_Cfg.Config(theCardinal), theNewOverlay);
				set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hSeeOverlay, 'Value', 1);
				nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));
				set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hOverlayFile, 'String', theNewOverlay, 'TooltipString', theNewOverlay);
			% end
		end;
		
	case 'OVERLAYSELECTION', 		%OverlaySelection	
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''UnderlaySelection'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,		
			[filename, pathname] = uigetfile({'*.img', 'ANALYZE or NIFTI files (*.img)';'*.nii','NIFTI files (*.nii)'}, ...
															'Pick one brain map');
			if any(filename~=0) && ischar(filename) && length(filename)>4 ,	% not canceled and legal			
				if ~strcmpi(pathname(end), filesep)%revise pathname to add \ or /
					pathname = [pathname filesep];
				end
				theBrainMap =[pathname filename];
				set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hOverlayFile, 'String', theBrainMap);
				nic_rest_sliceviewer('ChangeOverlay', AFigHandle);
			end		
		end;
    case 'OVERLAYFILE', 		%OverlaySelection	
		if nargin~=3, error('Usage: nic_rest_sliceviewer(''UnderlaySelection'',filePath, AFigHandle);'); end
        theBrainMap=varargin{1};	
		AFigHandle 	=varargin{2};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,					
				set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hOverlayFile, 'String', theBrainMap);
				nic_rest_sliceviewer('ChangeOverlay', AFigHandle);	
		end;
	case 'CLICKRECENTOVERLAY', 	%ClickRecentOverlay
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''ClickRecentOverlay'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,			
			theIndex =get(nic_rest_sliceviewer_Cfg.Config(theCardinal).hOverlayRecent, 'Value');
			if theIndex>1,
				theBrainMap =nic_rest_sliceviewer_Cfg.Config(theCardinal).Recent.Overlay{theIndex-1};
				set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hOverlayFile, 'String', theBrainMap);
				set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hOverlayRecent, 'Value', 1);
				nic_rest_sliceviewer('ChangeOverlay', AFigHandle);
			end
		end;
		
	case 'OVERLAY_SETTHRDABSVALUE',		%Overlay_SetThrdAbsValue, %Change from the Absolute value Edit control
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''Overlay_SetThrdAbsValue'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			nic_rest_sliceviewer_Cfg.Config(theCardinal).Overlay.ValueThrdAbsolute =SetThrdAbsValue(nic_rest_sliceviewer_Cfg.Config(theCardinal));
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =ThresholdOverlayVolume(nic_rest_sliceviewer_Cfg.Config(theCardinal));
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));			
        end	
    case 'OVERLAY_SETTHRESHOLDVALUE',		%Overlay_SetThrdAbsValue, %Change from the Absolute value Edit control
		if nargin~=3, error('Usage: nic_rest_sliceviewer(''Overlay_SetThresholdValue'',thresholdValue, AFigHandle);'); end
		 thresholdValue = varargin{1};	
		 AFigHandle =varargin{2};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
% 			nic_rest_sliceviewer_Cfg.Config(theCardinal).Overlay.ValueThrdAbsolute =SetThrdAbsValue(nic_rest_sliceviewer_Cfg.Config(theCardinal));
            set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hEdtThrdValue, 'String', num2str(thresholdValue));
% 			nic_rest_sliceviewer_Cfg.Config(theCardinal) =ThresholdOverlayVolume(nic_rest_sliceviewer_Cfg.Config(theCardinal));
% 			nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));	
            set(AFigHandle,'CurrentObject',nic_rest_sliceviewer_Cfg.Config(theCardinal).hEdtThrdValue);
            nic_rest_sliceviewer('Overlay_SetThrdAbsValue', AFigHandle);
        end	 
	case 'OVERLAY_SETTHRDCLUSTERSIZE', 		%Overlay_SetThrdClusterSize
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''Overlay_SetThrdClusterSize'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			theConfig =nic_rest_sliceviewer_Cfg.Config(theCardinal);
			prompt ={'Set Cluster Size(voxel) must be GREATER than: ', 'Set Cluster Raidus(mm) must be GREATER than: (this value would be transformed to Cluster Size according to the Overlay''s size and its voxel''s size)'};
			def	={num2str(theConfig.Overlay.ClusterSizeThrd) ,...
				  num2str(theConfig.Overlay.ClusterRadiusThrd)};
			answer =inputdlg(prompt, 'Threshold by cluster size ', 1, def);
			if numel(answer)==2,
				theVal =abs(str2num(answer{1}));				
				theConfig.Overlay.ClusterSizeThrd =round(theVal);
				
				theVal =abs(str2num(answer{2}));
				theConfig.Overlay.ClusterRadiusThrd =round(theVal);
				
				nic_rest_sliceviewer_Cfg.Config(theCardinal) =theConfig;
				nic_rest_sliceviewer_Cfg.Config(theCardinal) =ThresholdOverlayVolume(nic_rest_sliceviewer_Cfg.Config(theCardinal));
				nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));
			end			
		end	
	case 'OVERLAY_MISC', 		%Overlay_Misc
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''Overlay_Misc'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =Overlay_Misc(nic_rest_sliceviewer_Cfg.Config(theCardinal));
			nic_rest_sliceviewer('Repaint', AFigHandle);
		end	
	case 'OPEN_TEMPLATE', 		%Open_Template
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''Overlay_Misc'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =Open_Template(nic_rest_sliceviewer_Cfg.Config(theCardinal));			
			nic_rest_sliceviewer('Repaint', AFigHandle);	
		end	
	
	case 'CURRENTCLUSTER2MASK',			%CurrentCluster2Mask
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''CurrentCluster2Mask'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			theConfig =nic_rest_sliceviewer_Cfg.Config(theCardinal);
			theMask =CurrentCluster2Mask(nic_rest_sliceviewer_Cfg.Config(theCardinal));
			if ~isempty(theMask),
				[filename, pathname] = uiputfile('*.img','Save current point''s cluster: ');
				if isequal(filename,0) | isequal(pathname,0),
				else
					if length(filename)>4,						
						if strcmpi(filename(end-3:end), '.img')
						  filename = filename(1:end-4);
						end
					end
					theMaskFile =fullfile(pathname, filename);	
                    theConfig.Overlay.Header.Origin=theConfig.Overlay.Origin; %%Yan 080610
					rest_writefile(theMask, theMaskFile, size(theConfig.Overlay.Volume), ...
								theConfig.Overlay.VoxelSize, theConfig.Overlay.Header,'int16'); %%Yan 080610
					theConfig.LastSavedMask =[theMaskFile ,'.img'];
					if ~isempty(theConfig.Callback.Save2Mask),
						eval(theConfig.Callback.Save2Mask);
					end
				end				
				nic_rest_sliceviewer('Repaint', AFigHandle);
			else
				errordlg(sprintf('No cluster found at (%s)', ...
					num2str(Pos_Underlay2Overlay(theConfig, theConfig.LastPosition) -theConfig.Overlay.Origin)));
			end
			
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =theConfig;
		end	
	
	case 'SAVERECENT',		%SaveRecent		
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''SaveRecent'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
% 			SaveRecent(nic_rest_sliceviewer_Cfg.Config(theCardinal), 'RecentOverlay');
% 			SaveRecent(nic_rest_sliceviewer_Cfg.Config(theCardinal), 'RecentUnderlay');
		end
		
	case 'CHANGECOLORELEMENT', 		%ChangeColorElement
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''ChangeColorElement'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetColorElements(nic_rest_sliceviewer_Cfg.Config(theCardinal));
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));
		end
		
	case 'TOGGLEINFODISPLAY', 		%ToggleInfoDisplay
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''ToggleInfoDisplay'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			ToggleInfoDisplay(nic_rest_sliceviewer_Cfg.Config(theCardinal));
		end
	
	case 'UPDATECALLBACK_SAVE2MASK',	%UpdateCallback_Save2Mask
		if nargin~=3, error('Usage: nic_rest_sliceviewer(''UpdateCallback_Save2Mask'', AFigHandle, ACallback);'); end
		AFigHandle 	=varargin{1};	
		ACallback   =varargin{2};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			nic_rest_sliceviewer_Cfg.Config(theCardinal).Callback.Save2Mask =ACallback;			
		end
	case 'GETSAVEDMASKFILENAME',		%GetSavedMaskFilename
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''GetSavedMaskFilename'', AFigHandle);'); end
		AFigHandle 	=varargin{1};			
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			varargout{1} =nic_rest_sliceviewer_Cfg.Config(theCardinal).LastSavedMask;
		else
			varargout{1} ='';
		end
		
	case 'SHOWOVERLAY',	%ShowOverlay
		if nargin>3, error('Usage: nic_rest_sliceviewer(''ShowOverlay'', AOverlay); or nic_rest_sliceviewer(''ShowOverlay'', AFigHandle, AOverlay);'); end
		AFigHandle 	=varargin{1};
		if ~ischar(AFigHandle),
			AOverlay    =varargin{2};
			theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
			if theCardinal>0,
				set(nic_rest_sliceviewer_Cfg.Config(theCardinal).hOverlayFile, 'String', AOverlay);
				nic_rest_sliceviewer('ChangeOverlay', AFigHandle);
			end
		else	%I will create a new slice-viewer
			AOverlay    =varargin{1};
			theFig = nic_rest_sliceviewer; %I can't write "()" considering Matlab 6.5 compatiable
			nic_rest_sliceviewer('ShowOverlay', theFig, AOverlay);
			varargout{1} =theFig;
		end
	
	case 'ONKEYPRESS',		%OnKeyPress
		if nargin~=2, error('Usage: nic_rest_sliceviewer(''OnKeyPress'', AFigHandle);'); end
		AFigHandle 	=varargin{1};	
		theCardinal =ExistViewer(nic_rest_sliceviewer_Cfg, AFigHandle);
		if theCardinal>0,
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =OnKeyPress(nic_rest_sliceviewer_Cfg.Config(theCardinal));
			%For Updating
			nic_rest_sliceviewer_Cfg.Config(theCardinal) =SetImage(nic_rest_sliceviewer_Cfg.Config(theCardinal));
			%For Yoke
			nic_rest_sliceviewer('SetPosition', AFigHandle);
		end
		
	otherwise
	end
catch
	nic_rest_misc( 'DisplayLastException');
end	

function Result =InitControls(AFilename, ACallback)	
	%Initialization 20070525
	theFig =figure('Units', 'pixel', 'Toolbar', 'none', 'MenuBar', 'none', ...
				'NumberTitle', 'off', 'Name', AFilename, 'DoubleBuffer', 'on');
	set(theFig, 'DeleteFcn', sprintf('nic_rest_sliceviewer(''Delete'', %g);', theFig)  );
	set(theFig, 'KeyPressFcn', sprintf('nic_rest_sliceviewer(''OnKeyPress'', %g);', theFig)  );
	
	MarginX =10; MarginY =10;
	OffsetX =MarginX;
	OffsetY =MarginY +200;			
	
	%Create Slice View options
	%Create uicontrols to config Yoke or [X Y Z] position to set current cross-hair to locate the voxel
	theLeft =OffsetX; theBottom =OffsetY;
	hFrameSetPos=uicontrol(theFig, 'Style','Frame', 'Units','pixels', ...
							'BackgroundColor', get(theFig,'Color'), ...
							'Position', [theLeft,theBottom,150,180]);	
	uicontrol(theFig, 'Style','pushbutton', 'Units','pixels', ...
			'String', 'Slice Viewer', ... %'BackgroundColor', get(theFig,'Color'), ...
			'Callback', 'nic_rest_sliceviewer', ...
			'Position', [theLeft+35,theBottom+172,80,20]);	
	
	theLeft =OffsetX+MarginX; theBottom =OffsetY+MarginY+20 +20+MarginY/2 +10 +MarginY;
	hYoke =uicontrol(theFig, 'Style','checkbox', 'Units','pixels', ...
					'String', 'Yoke', ...
					'BackgroundColor', get(theFig,'Color'), ...
					'Position',[theLeft, theBottom+75, 80,18]);
	theLeft =OffsetX+MarginX+56+MarginX; theBottom =OffsetY+MarginY+20 +20+MarginY/2 +10 +MarginY;	
	hCrosshair =uicontrol(theFig, 'Style','checkbox', 'Units','pixels', ...
					'String', 'Crosshair', 'Value', 1,...
					'Callback', sprintf('nic_rest_sliceviewer(''Repaint'', %g);',theFig) , ...
					'BackgroundColor', get(theFig,'Color'), ...
					'Position',[theLeft, theBottom+75, 70,18]);
	
	
	theEditCallbackFcn =sprintf('nic_rest_sliceviewer(''SetPosition'', %g);', theFig);
	theLeft =OffsetX+MarginX-5; theBottom =OffsetY+MarginY+35+MarginY/2;
	uicontrol(theFig, 'Style','text', 'Units','pixels', ...
			  'String', 'X(mm)', ...
			  'BackgroundColor', get(theFig,'Color'), ...			  
			  'Position',[theLeft, theBottom+85, 46,15]);
	theLeft =OffsetX+MarginX-5; theBottom =OffsetY+MarginY+20;		  
	hEditPositionX =uicontrol(theFig, 'Style','edit', 'Units','pixels', ...
							  'String', '0', ...
							  'BackgroundColor', 'white', ...
							  'Callback', theEditCallbackFcn, ...
							  'Position',[theLeft, theBottom+85, 46,20]);
		  
	theLeft =OffsetX+MarginX+36+MarginX-5; theBottom =OffsetY+MarginY+35+MarginY/2;					  
	uicontrol(theFig, 'Style','text', 'Units','pixels', ...
			  'String', 'Y(mm)', ...
			  'BackgroundColor', get(theFig,'Color'), ...
			  'Position',[theLeft, theBottom+85, 46,15]);
	theLeft =OffsetX+MarginX+36+MarginX-5; theBottom =OffsetY+MarginY+20;			  
	hEditPositionY =uicontrol(theFig, 'Style','edit', 'Units','pixels', ...
							  'String', '0', ...
							  'BackgroundColor', 'white', ...
							  'Callback', theEditCallbackFcn, ...
							  'Position',[theLeft, theBottom+85, 46,20]);
			
	theLeft =OffsetX+MarginX+36+MarginX+36+MarginX-5; theBottom =OffsetY+MarginY+35+MarginY/2;		
	uicontrol(theFig, 'Style','text', 'Units','pixels', ...
			  'String', 'Z(mm)', ...
			  'BackgroundColor', get(theFig,'Color'), ...
			  'Position',[theLeft, theBottom+85, 46,15]);
	theLeft =OffsetX+MarginX+36+MarginX+36+MarginX-5; theBottom =OffsetY+MarginY+20;		  
	hEditPositionZ =uicontrol(theFig, 'Style','edit', 'Units','pixels', ...
							  'String', '0', ...
							  'BackgroundColor', 'white', ...
							  'Callback', theEditCallbackFcn, ...
							  'Position',[theLeft, theBottom+85, 46,20]);
	
	theLeft =OffsetX+MarginX-5; theBottom =OffsetY+MarginY+20;
	hMagnify =uicontrol(theFig, 'Style','popupmenu', 'Units','pixels', ...
						'String', {'x0.5', 'x1', 'x2', 'x3'}, ...
						'Value', 2, ...
						'BackgroundColor', get(theFig,'Color'), ...
						'Enable', 'off', ...
						'Callback', sprintf('nic_rest_sliceviewer(''Magnify'', %g);',theFig), ...
						'Position',[theLeft, theBottom+70, 50,20]);
	if license('test','image_toolbox')
		set(hMagnify, 'Enable', 'on');
	else
		warning('image_toolbox not valid');
	end
	
	theLeft =OffsetX+MarginX+40+MarginX-5; theBottom =OffsetY+MarginY+20;
	hMniTal =uicontrol(theFig, 'Style','popupmenu', 'Units','pixels', ...
						'String', {'MNI/Talairach Coordinates', 'Talairach to MNI', 'MNI to Talairach'}, ...
						'Value', 1, ...
						'BackgroundColor', get(theFig,'Color'), ...
						'Enable', 'on', ...
						'Callback', sprintf('nic_rest_sliceviewer(''MNI/Talairach'', %g);',theFig), ...
						'Position',[theLeft, theBottom+70, 90,20]);
	
	
	%OffsetY =OffsetY +30;%20070911, for complete information display	
	theLeft =OffsetX+MarginX; theBottom =OffsetY+MarginY;
	hVoxelIntensity=uicontrol(theFig, 'Style','text', 'Units','pixels', ...
						  'String', '', 'TooltipString', 'Intensity of the current point', ...
						  'BackgroundColor', get(theFig,'Color'), ...
						  'HorizontalAlignment', 'left', ...  % 'Visible', 'off', ...						  
						  'Position',[theLeft-5, theBottom+42, 110,32]);
			  
	%Create a Message label to display some specific message, dawnsong 20070526
	theLeft =OffsetX+MarginX; theBottom =OffsetY +120 +MarginY;
	hMsgLabel =uicontrol(theFig, 'Style','text', 'Units','pixels', ...
			  'String', sprintf(''), ...
			  'BackgroundColor', get(theFig,'Color'), ...
			  'HorizontalAlignment', 'left', 'Enable', 'inactive',...
			  'ButtonDownFcn', sprintf('nic_rest_sliceviewer(''ToggleInfoDisplay'', %g);',theFig), ...
			  'Position',[theLeft, theBottom, 130,10]);	
			  
	% Create a Callback Button to do sth.
	theLeft =OffsetX+MarginX; theBottom =OffsetY +100 +MarginY +10;
	% hDoCallbackBtn =-1;
	% if ~isempty(ACallback) && ischar(ACallback)
		% hDoCallbackBtn =uicontrol(theFig, 'Style','pushbutton',  ...
							  % 'Units','pixels', 'String', 'Do sth.', ...
							  % 'Callback', ACallback, ...
							  % 'Position',[theLeft, theBottom, 130,10]);
	% end
	%View Buttons
	theLeft =OffsetX+MarginX-4; theBottom =OffsetY +MarginY-2;
	theIcon =imread(fullfile(nic_rest_misc( 'WhereIsREST'), 'icoTransverse.jpg'));
	hViewTransverse =uicontrol(theFig, 'Style','pushbutton',  ...
							  'Units','pixels', ...
							  'Callback', sprintf('nic_rest_sliceviewer(''TransverseView'', %g);',theFig) , ...
							  'CData', theIcon,...
							  'Position',[theLeft, theBottom, 34,36]);
	theLeft =OffsetX+MarginX+30; theBottom =OffsetY +MarginY-2;
	theIcon =imread(fullfile(nic_rest_misc( 'WhereIsREST'), 'icoSagittal.jpg'));
	hViewSagittal =uicontrol(theFig, 'Style','pushbutton',  ...
							  'Units','pixels', ...
							  'Callback', sprintf('nic_rest_sliceviewer(''SagittalView'', %g);',theFig) , ...
							  'CData', theIcon,...
							  'Position',[theLeft, theBottom, 34,36]);
	theLeft =OffsetX+MarginX+34+30; theBottom =OffsetY +MarginY-2;
	theIcon =imread(fullfile(nic_rest_misc( 'WhereIsREST'), 'icoCoronal.jpg'));
	hViewCoronal =uicontrol(theFig, 'Style','pushbutton',  ...
							  'Units','pixels', ...
							  'Callback', sprintf('nic_rest_sliceviewer(''CoronalView'', %g);',theFig) , ...
							  'CData', theIcon,...
							  'Position',[theLeft, theBottom, 34,36]);
	theLeft =OffsetX+MarginX+34+34+30; theBottom =OffsetY +MarginY-2;
	theIcon =imread(fullfile(nic_rest_misc( 'WhereIsREST'), 'icoOrthogonal.jpg'));
	hViewOrthogonal =uicontrol(theFig, 'Style','pushbutton',  ...
							  'Units','pixels', ...
							  'Callback', sprintf('nic_rest_sliceviewer(''OrthogonalView'', %g);',theFig) , ...
							  'CData', theIcon,...
							  'Position',[theLeft, theBottom, 34,36]);
	theLeft =OffsetX+MarginX+34+30; theBottom =OffsetY +MarginY+34;	
	hViewMontage =uicontrol(theFig, 'Style','pushbutton',  ...
							  'Units','pixels', ...
							  'Callback', sprintf('nic_rest_sliceviewer(''Montage'', %g);',theFig) , ...
							  'String', 'Montage','TooltipString', 'Montage: Multislice',...
							  'Position',[theLeft, theBottom, 72,20]);
							  
	
	
	%Add Underlay file selection directly
	theLeft =OffsetX; theBottom =MarginY+180;
	hUnderlayRecent =uicontrol(theFig, 'Style','popupmenu', 'Units','pixels', ...
			  'String', {'Underlay: '}, 'Value', 1, ...
			  'Callback', sprintf('nic_rest_sliceviewer(''ClickRecentUnderlay'', %g);',theFig), ...
			  'BackgroundColor', get(theFig,'Color'), ...			  
			  'Position',[theLeft, theBottom, 75,20]);	 
	theLeft =OffsetX; theBottom =MarginY+160;
	hUnderlayFile =uicontrol(theFig, 'Style','edit', 'Units','pixels', ...
							  'String', '', ...
							  'BackgroundColor', 'white', ...
                              'HorizontalAlignment', 'left', ...
							  'Callback', sprintf('nic_rest_sliceviewer(''ChangeUnderlay'', %g);',theFig), ...
							  'Position',[theLeft, theBottom, 150,20]);
	theLeft =OffsetX+116; theBottom =MarginY+180;
	uicontrol(theFig, 'Style','pushbutton', 'Units','pixels', ...
		  'Callback', sprintf('nic_rest_sliceviewer(''UnderlaySelection'', %g);',theFig) , ...
		  'String', '...', 'FontWeight', 'bold', ...
		  'Position',[theLeft, theBottom, 34,15]);
	%Add Overlay file selection directly
	theLeft =OffsetX; theBottom =MarginY+140;
	hOverlayRecent =uicontrol(theFig, 'Style','popupmenu', 'Units','pixels', ...
			  'String', {'Overlay: '}, 'Value', 1, ...
			  'Callback', sprintf('nic_rest_sliceviewer(''ClickRecentOverlay'', %g);',theFig), ...
			  'BackgroundColor', get(theFig,'Color'), ...			  
			  'Position',[theLeft, theBottom, 75,20]);	 
	theLeft =OffsetX; theBottom =MarginY+120;
	hOverlayFile =uicontrol(theFig, 'Style','edit', 'Units','pixels', ...
					  'String', '', ...					  
					  'BackgroundColor', 'white', ...
                      'HorizontalAlignment', 'left', ...
					  'Callback', sprintf('nic_rest_sliceviewer(''ChangeOverlay'', %g);',theFig), ...
					  'Position',[theLeft, theBottom, 150,20]);
	theLeft =OffsetX+116; theBottom =MarginY+140;
	uicontrol(theFig, 'Style','pushbutton', 'Units','pixels', ...
		  'Callback', sprintf('nic_rest_sliceviewer(''OverlaySelection'', %g);',theFig) , ...
		  'String', '...','FontWeight', 'bold', ...
		  'Position',[theLeft, theBottom, 34,15]); 
	%Add Overlay  Options, 20070913
	theLeft =OffsetX; theBottom =MarginY;
	hFrameOverlay=uicontrol(theFig, 'Style','Frame', 'Units','pixels', ...
							'BackgroundColor', get(theFig,'Color'), ...
							'Position', [theLeft,theBottom,150,100]);	
	hSeeOverlay =uicontrol(theFig, 'Style','checkbox', 'Units','pixels', ...
					'String', 'See Overlay', ...
					'Callback', sprintf('nic_rest_sliceviewer(''Repaint'', %g);',theFig), ...
					'BackgroundColor', get(theFig,'Color'), ...
					'Position',[theLeft+35, theBottom+95, 80,15],'Visible','off');
	uicontrol(theFig, 'Style','text', 'Units','pixels', ...
			'String', 'Threshold', ...								
			 'BackgroundColor', get(theFig,'Color'), ...
			'Position',[theLeft+5, theBottom+75, 50,18]);
	hEdtThrdValue =uicontrol(theFig, 'Style','edit', 'Units','pixels', ...
					'String', '', ...					
					'Callback', sprintf('nic_rest_sliceviewer(''Overlay_SetThrdAbsValue'', %g);',theFig), ...	
					 'BackgroundColor', 'white', ...
					'Position',[theLeft+75, theBottom+75, 70,18]);	
	
	hSliderThrdValue =uicontrol(theFig, 'Style','slider', 'Units','pixels', ...
					'TooltipString', 'Absolute Value for thresholding the overlay', ...
					'Callback', sprintf('nic_rest_sliceviewer(''Overlay_SetThrdAbsValue'', %g);',theFig), ...
					'BackgroundColor', get(theFig,'Color'), ...
					'Position',[theLeft+5, theBottom+56, 140,15]);	
	uicontrol(theFig, 'Style','pushbutton', 'Units','pixels', ...
			'String', 'Clusterize', ...
			'Callback', sprintf('nic_rest_sliceviewer(''Overlay_SetThrdClusterSize'', %g);',theFig),...			
			'Position',[theLeft+75, theBottom+30, 70,24],'');
	hOverlayMisc =uicontrol(theFig, 'Style','popupmenu', 'Units','pixels', ...
					'String', {'Misc', 'Set Overlay''s Opacity', ...
					'Range of Threshold', 'Label Color', 'Color bar'}, ...
					'Value', 1, ...
					'BackgroundColor', get(theFig,'Color'), ...
					'Enable', 'on', ...
					'Callback', sprintf('nic_rest_sliceviewer(''Overlay_Misc'', %g);',theFig), ...
					'Position',[theLeft+5, theBottom+30, 70,24],'Visible','off');
	hTemplate =uicontrol(theFig, 'Style','popupmenu', 'Units','pixels', ...
					'String', {'Template', 'Open AAL', 'Open Brodmann','Open Ch2'}, ...
					'Value', 1, ...
					'BackgroundColor', get(theFig,'Color'), ...
					'Enable', 'on', ...
					'Callback', sprintf('nic_rest_sliceviewer(''Open_Template'', %g);',theFig), ...
					'Position',[theLeft+5, theBottom+5, 70,24],'Visible','off');
	uicontrol(theFig, 'Style','pushbutton', 'Units','pixels', ...
			'String', 'Save2Mask', ...
			'Callback', sprintf('nic_rest_sliceviewer(''CurrentCluster2Mask'', %g);',theFig),...			
			'Position',[theLeft+75, theBottom+5, 70,24],'Visible','off');
	
	%Colorbar for overlay, do as AFNI, 20070921
	theAxesButtonDownFcn =sprintf('nic_rest_sliceviewer(''ChangeColorElement'', %g);',theFig);
	hAxesColorbar =axes('Parent', theFig, 'Box', 'on', ...
				  'Units', 'pixel', 'DrawMode','fast', 'Visible', 'off', ...
				  'Position', [1 1 1 1], ...
				  'YDir','normal', 'XTickLabel',[],'XTick',[], ...
				  'YTickLabel',[],'YTick',[], ...
				  'ButtonDownFcn', theAxesButtonDownFcn);
	hImageColorbar =image('Tag','OverlayColorbar',  'Parent', hAxesColorbar);
	set(hAxesColorbar,'YDir','normal','ButtonDownFcn', theAxesButtonDownFcn, 'XTickLabel',[],'XTick',[], 'YTickLabel',[],'YTick',[]);
	
	clear theLeft theBottom;
		
	%Save to config
	AConfig.hFig			=theFig;			%handle of the config
	
	%Save parameters handles
	AConfig.hFrameSetPos   =hFrameSetPos;
	AConfig.hYoke 		   =hYoke;
	AConfig.hCrosshair	   =hCrosshair;
	AConfig.hMagnify	   =hMagnify;
	AConfig.hMniTal		   =hMniTal;	
	AConfig.hEditPositionX =hEditPositionX;
	AConfig.hEditPositionY =hEditPositionY;
	AConfig.hEditPositionZ =hEditPositionZ;
	%Save Voxel intensity label handle
	AConfig.hVoxelIntensity=hVoxelIntensity;
	%Save message handle
	AConfig.hMsgLabel =hMsgLabel;
	AConfig.Message	 ='';
	%Save Do Callback button's handle
	% AConfig.hDoCallbackBtn =hDoCallbackBtn;
			
	%Save important variables
	AConfig.Filename =AFilename;	%Default for underlay
	%AConfig.Callback =ACallback;	%Default for click callback	
	%Callback define series, 20070924
	AConfig.Callback.ChangingPosition =ACallback;
	AConfig.Callback.Save2Mask ='';
	
	%View Mode, 20070911
	AConfig.ViewMode ='Orthogonal';	%Default View mode
	AConfig.ViewSeries =[];			%Default no any view series
	AConfig.Montage.Across =1;
	AConfig.Montage.Down   =1;
	AConfig.Montage.Spacing=3;
	AConfig.Montage.WantLabel=1;	
	
	%Underlay and Overlay, handles
	AConfig.hUnderlayFile =hUnderlayFile;
	AConfig.hUnderlayRecent =hUnderlayRecent;
	AConfig.hOverlayFile  =hOverlayFile;
	AConfig.hOverlayRecent =hOverlayRecent;
	
	AConfig.hSeeOverlay =hSeeOverlay;
	AConfig.hSliderThrdValue =hSliderThrdValue;
	AConfig.hEdtThrdValue =hEdtThrdValue;	
	AConfig.hOverlayMisc =hOverlayMisc;
	AConfig.hTemplate =hTemplate;	
	AConfig.hFrameOverlay  =hFrameOverlay;
	
	AConfig.hAxesColorbar  =hAxesColorbar;
	AConfig.hImageColorbar =hImageColorbar;	
	
	%Overlay Configuration
	%Data for Overlay
	AConfig.Overlay.Filename ='';
	AConfig.Overlay.Volume	 =zeros(61, 73, 61);
	AConfig.Overlay.VolumeThrd =AConfig.Overlay.Volume;%Volume Thresholded by Cluster Size	
	AConfig.Overlay.VoxelSize=[3 3 3];
	AConfig.Overlay.Origin	 =[31 43 25];
	%Overlay's Info - statistics
	Result.Overlay.MinNegative =-Inf;
	Result.Overlay.MaxNegative =0;
	Result.Overlay.MinPositive =0;
	Result.Overlay.MaxPositive =Inf;
	Result.Overlay.AbsMin =0;
	Result.Overlay.AbsMax =Inf;
	%Options for Overlay	
	AConfig.Overlay.Colormap	=icatb_getColormap(1,1,0);%jet(64);
	AConfig.Overlay.ColorbarCmd	='jet(64)';	
	%[0 0 1;1 0 0];	%Pure Blue and Pure Red
	%[0 0 0.5625;0 0 0.875;0 0 1;1 0 0;0.875 0 0;0.5 0 0];	
	AConfig.Overlay.Opacity  =1;	%Default, 50% Opacity	
	AConfig.Overlay.LabelColor ='white';
	AConfig.Overlay.ValueThrdAbsolute =0; %Default, show all
	AConfig.Overlay.ValueThrdMin = -Inf; %Default, show all, not absolute, may be negative
	AConfig.Overlay.ValueThrdMax = Inf; %Default, show all, not absolute , may be negative, this allows me to set a range such as showing negative values only or positives only
	AConfig.Overlay.ValueThrdSeries = NaN; %Default, show all
	AConfig.Overlay.ClusterSizeThrd =0; %Default, 0 voxels, for not confining cluster-size
	AConfig.Overlay.ClusterRadiusThrd =0; %Default radius(mm) for Cluster size definition
	AConfig.Overlay.InfoAal='None';	%AAL descriptions
		
	%Load Recent Images/brains
	AConfig =InitRecent(AConfig);
	
	%Save Axes's handles
	AConfig.hAxesSagittal 	=-1;
	AConfig.hAxesCoronal 	=-1;
	AConfig.hAxesTransverse =-1;
	%Save Images' handles
	AConfig.hImageSagittal	 =-1;
	AConfig.hImageCoronal 	 =-1;
	AConfig.hImageTransverse =-1;
	%Save Lines' handles
	AConfig.hXLineSagittal   =-1;		%x
	AConfig.hYLineSagittal   =-1;		%y
	AConfig.hXLineCoronal	 =-1;		%x
	AConfig.hYLineCoronal	 =-1;		%y
	AConfig.hXLineTransverse =-1;		%x
	AConfig.hYLineTransverse =-1;		%y
	AConfig.LastPosition =[90 126 72];	%Default
	AConfig.LastAxes	 ='Transverse';	%For slice previous/next by pressing up/down left/right j/k ... on keyboard
	AConfig.LastSavedMask ='';			%For ROI define callback
	
	AConfig =InitUnderlay(AConfig);
	
	
	%Move Auto-Balance out of initialization just for speeding up for starting this slice-viewer
	%Save Maping Image parameters, Auto balance 20070911 revised
	% theSatMin=0; theSatMax =0; nBins=2^16;	%Satuation Min/Max
	% theMaxVal=max(AConfig.Volume(:));	
	% if theMaxVal<257, 
		% nBins =256; 
	% else
		% nBins =theMaxVal; 
	% end
	% theSum =histc(AConfig.Volume(:), [1:nBins]);
	% theSum =cumsum(theSum);
	% theCdf =theSum/theSum(end);
	% if nic_rest_misc('GetMatlabVersion')>=7.3
		% idxSatMin =find(theCdf>0.01, 1, 'first');
		% idxSatMax =find(theCdf>=0.99, 1, 'first');
	% else
		% idxSatMin =find(theCdf>0.01);
		% idxSatMin =idxSatMin(1);
		% idxSatMax =find(theCdf>=0.99);
		% idxSatMax =idxSatMax(1);		
	% end
	% idxSatMin =find(theCdf>0.01, 1, 'first');
	% idxSatMax =find(theCdf>=0.99, 1, 'first');
	% theSatMin =(idxSatMin-1)/(nBins-1) *theMaxVal;
	% theSatMax =(idxSatMax-1)/(nBins-1) *theMaxVal;	
	% AConfig.Contrast.GrayDepth =256;
	% AConfig.Contrast.SatMax =theSatMax;
	% AConfig.Contrast.SatMin =theSatMin;
	%20070911, AutoBalance for contrast
	% AConfig.Contrast.WindowWidth =theSatMax -theSatMin;
	% AConfig.Contrast.WindowCenter=(theSatMax +theSatMin)/2;
	%For debugging, 20070911
	% disp(AConfig.Contrast);
	
    	
	%%Update the figure, the follow function called order shouldn't change
	%Display Images
	AConfig =SetImage(AConfig);
	AConfig.convertToZ=0;
    AConfig.returnValue=1;
	Result =AConfig;	
	return;

function Result =DeleteFigure(AGlobalConfig, AFigHandle)
	x =ExistViewer(AGlobalConfig, AFigHandle);
	if x>0,			
		theDisplayCount =GetDisplayCount(AGlobalConfig);
		isExistFig =nic_rest_misc( 'ForceCheckExistFigure' , AGlobalConfig.Config(x).hFig);
		if isExistFig,
			%Save the recent menu
			nic_rest_sliceviewer('SaveRecent', AFigHandle);
			
			%Delete the figure and rearrange the queue
			delete(AGlobalConfig.Config(x).hFig);
			if theDisplayCount>x
				for y=x:theDisplayCount-1
					AGlobalConfig.Config(x) =AGlobalConfig.Config(x+1);
                end
            end	
            AGlobalConfig.Config(theDisplayCount)=[];
		end	
	end
	Result =AGlobalConfig;
	
function Result =GetDisplayCount(AGlobalConfig)
%Get the Count of display, this program allow multi-view of brain like MRIcro
	if isempty(AGlobalConfig) || ~isfield(AGlobalConfig,'Config') || isempty(AGlobalConfig.Config),
		Result =0;		
	else
		Result =length(AGlobalConfig.Config);
	end
	return;
	
function Result =ListViewerFigure(AGlobalConfig, AFilename)
    Result =[];
	if (isstruct(AGlobalConfig) && isstruct(AGlobalConfig.Config))
		for x=1:length(AGlobalConfig.Config)
			if strcmpi( AGlobalConfig.Config(x).Filename, AFilename)
				Result =[Result; AGlobalConfig.Config(x).hFig];
            end
        end        
	else
		return;
	end	
	
function Result =ExistViewer(AGlobalConfig, AFigureHandle)
	Result =0;
	if (isstruct(AGlobalConfig) && isstruct(AGlobalConfig.Config))
		for x=1:length(AGlobalConfig.Config)
			if AGlobalConfig.Config(x).hFig==AFigureHandle,
				Result =x;
				return;
            end
        end        
	else				
		return;
	end	

function Result =SetImage(AConfig)
	if strcmpi(AConfig.ViewMode, 'Orthogonal'),
		Result =SetView_Orthogonal(AConfig);
	elseif strcmpi(AConfig.ViewMode, 'Transverse'),
		Result =SetView_Transverse(AConfig);
	elseif strcmpi(AConfig.ViewMode, 'Sagittal'),
		Result =SetView_Sagittal(AConfig);
	elseif strcmpi(AConfig.ViewMode, 'Coronal'),
		Result =SetView_Coronal(AConfig);
	end
	
	%Draw the color bar
	Result =DrawColorbar(Result);
	
	set(AConfig.hFig, 'Name', sprintf('Slice Viewer'));
	%Display Underlay Filename
	set(AConfig.hUnderlayFile, 'String', sprintf('%s', AConfig.Filename));
	%Display Overlay Filename	
	set(AConfig.hOverlayFile, 'String', sprintf('%s', AConfig.Overlay.Filename));
	
	%Show Voxel's position [x y z]
	ShowPositionInEdit(AConfig);	
	%Update the message
	SetMessage(AConfig);	
	%Resize figure width and height
	ResizeFigure(AConfig);
	
	
function Result =SetView_Orthogonal(AConfig)	
	%Underlay Image manuplication, 20070913
	theSagittalImg =GetGrayImage('Sagittal', AConfig.Volume, AConfig.LastPosition(1));	%x
	theCoronalImg =GetGrayImage('Coronal', AConfig.Volume, AConfig.LastPosition(2));		%y	
	theTransverseImg =GetGrayImage('Transverse', AConfig.Volume, AConfig.LastPosition(3));%z
	
	%Auto balance	
	theSagittalImg =SaturateContrast(theSagittalImg, AConfig.Contrast.SatMin, AConfig.Contrast.SatMax);
	theCoronalImg =SaturateContrast(theCoronalImg, AConfig.Contrast.SatMin, AConfig.Contrast.SatMax);
	theTransverseImg =SaturateContrast(theTransverseImg, AConfig.Contrast.SatMin, AConfig.Contrast.SatMax);
	
	%Calculate the Result Image after Magnifying
	theMagnifyCoefficient =GetMagnifyCoefficient(AConfig);
	if license('test','image_toolbox')==1 && theMagnifyCoefficient~=1, 
		theSagittalImg	=imresize(theSagittalImg, theMagnifyCoefficient);
		theCoronalImg	=imresize(theCoronalImg, theMagnifyCoefficient);
		theTransverseImg=imresize(theTransverseImg, theMagnifyCoefficient);
	end	
	
	% Revise the Axes position to make it comfort to Magnify
	theFramePosParamSet =get(AConfig.hFrameSetPos, 'Position');
	theLeft 	=theFramePosParamSet(1) +theFramePosParamSet(3) +5;
	theBottom 	=10; %theFramePosParamSet(2);
	theLeftTransverse =theLeft;
	theLeftCoronal 	  =theLeftTransverse;
	theLeftSagittal   =theLeftCoronal  +size(theCoronalImg,2)+	2;
	theBottomTransverse =theBottom;
	theBottomCoronal	=theBottomTransverse +size(theTransverseImg,1) +2;
	theBottomSagittal	=theBottomCoronal;
	
	thePosTransverse 	=[theLeftTransverse, theBottomTransverse, size(theTransverseImg,2), size(theTransverseImg,1)];
	thePosCoronal		=[theLeftCoronal, theBottomCoronal, size(theCoronalImg,2), size(theCoronalImg,1)];
	thePosSagittal		=[theLeftSagittal, theBottomSagittal, size(theSagittalImg,2), size(theSagittalImg,1)];
	clear theFramePosParamSet theLeft theBottom 
	clear theLeftTransverse theLeftCoronal theLeftSagittal
	clear theBottomTransverse theBottomCoronal theBottomSagittal
	
	% Show Images
	%Clear Text labels first
	ClearTextLabels(AConfig);	
	
	%Set Default color map for only Underlay
	%colormap(gray(AConfig.Contrast.GrayDepth));	
	%Map images to true color
	theSagittalImg =repmat(theSagittalImg, [1 1 3]);
	theCoronalImg =repmat(theCoronalImg, [1 1 3]);
	theTransverseImg =repmat(theTransverseImg, [1 1 3]);
	
	%Add Overlay Images
	if SeeOverlay(AConfig),
		theSagittalImg =AddOverlay('Sagittal' ,AConfig, theSagittalImg);
		theCoronalImg =AddOverlay('Coronal', AConfig, theCoronalImg);
		theTransverseImg =AddOverlay('Transverse', AConfig, theTransverseImg);
	end
	
	%Sagittal	
	set(AConfig.hImageSagittal, 'CData', (theSagittalImg), 'HitTest', 'off','Visible', 'on');	
	set(AConfig.hAxesSagittal,'Visible', 'on', ...
		'XLim', [1 size(theSagittalImg,2)], ...
		'YLim', [1 size(theSagittalImg,1)] , ...
		'Position', thePosSagittal);
	set(AConfig.hXLineSagittal, 'HitTest','off','Visible', IsCrosshairChecked(AConfig), ...		
		'XData', [1 size(theSagittalImg,2)] , ...
		'YData', [1 1]*AConfig.LastPosition(3) * theMagnifyCoefficient);%Parallel to X-axis
	set(AConfig.hYLineSagittal, 'HitTest','off','Visible', IsCrosshairChecked(AConfig), ...		
		'XData', [1 1]*AConfig.LastPosition(2) * theMagnifyCoefficient, ...
		'YData', [1 size(theSagittalImg,1)] );%Parallel to Y-axis
	
	%Coronal		 
	set(AConfig.hImageCoronal, 'CData', (theCoronalImg), 'HitTest', 'off','Visible', 'on');
	%colormap(gray(AConfig.Contrast.GrayDepth));	
	set(AConfig.hAxesCoronal, 'Visible', 'on',...
		'XLim', [1 size(theCoronalImg,1)], ...
		'YLim', [1 size(theCoronalImg,2)], ...
		'Position', thePosCoronal);
	set(AConfig.hXLineCoronal, 'HitTest','off','Visible', IsCrosshairChecked(AConfig), ...		
		'XData', [1 size(theCoronalImg,2)] , ...
		'YData', [1 1]*AConfig.LastPosition(3) * theMagnifyCoefficient );%Parallel to X-axis
	set(AConfig.hYLineCoronal, 'HitTest','off','Visible', IsCrosshairChecked(AConfig), ...		
		'XData', [1 1]*AConfig.LastPosition(1) * theMagnifyCoefficient , ...
		'YData', [1 size(theCoronalImg,1)] );%Parallel to Y-axis
	
	%Transverse		 
	set(AConfig.hImageTransverse, 'CData', (theTransverseImg), 'HitTest', 'off','Visible', 'on');
	% colormap(gray(AConfig.Contrast.GrayDepth));	
	set(AConfig.hAxesTransverse,'Visible', 'on', ...
		'XLim', [1 size(theTransverseImg,2)], ...
		'YLim', [1 size(theTransverseImg,1)], ...
		'Position', thePosTransverse);
	set(AConfig.hXLineTransverse, 'HitTest','off','Visible', IsCrosshairChecked(AConfig), ...		
		'XData', [1 size(theTransverseImg,2)] , ...
		'YData', [1 1]*AConfig.LastPosition(2) * theMagnifyCoefficient );%Parallel to X-axis
	set(AConfig.hYLineTransverse, 'HitTest','off','Visible', IsCrosshairChecked(AConfig), ...		
		'XData', [1 1]*AConfig.LastPosition(1) * theMagnifyCoefficient , ...
		'YData', [1 size(theTransverseImg,1)] );%Parallel to Y-axis
	
	%Reset View Series
	AConfig.ViewSeries =[];
	Result =AConfig;

function Result =SetView_Transverse(AConfig)
	[nDim1 nDim2 nDim3] =size(AConfig.Volume);
	theCenterZ =AConfig.LastPosition(3);
	theCount   =AConfig.Montage.Across *AConfig.Montage.Down ;
	
	theZSeries =theCenterZ -([(floor(theCount/2)) : -1 :(ceil(-theCount/2))]) *AConfig.Montage.Spacing;
	while ~isempty(find(theZSeries<=0)),
		theZSeries(find(theZSeries<=0)) = theZSeries(find(theZSeries<=0)) +nDim3;
	end
	while ~isempty(find(theZSeries>nDim3)),
		theZSeries(find(theZSeries>nDim3)) = theZSeries(find(theZSeries>nDim3)) -nDim3;
	end
	
	theTransverseImg = zeros(nDim2 * AConfig.Montage.Down, nDim1 *AConfig.Montage.Across);
	for theRow=AConfig.Montage.Down:-1:1,
		for theCol=1:AConfig.Montage.Across,
			%I don't draw the last image because it is used to indicate the positions				
			theZIndex = theZSeries((theRow-1)*AConfig.Montage.Across +theCol);
			theTransverseImg((theRow-1)*nDim2 +(1:nDim2), (theCol-1)*nDim1+(1:nDim1)) =GetGrayImage('Transverse', AConfig.Volume, theZIndex);
			%Write the Z Coordinates to the left-down corner
			%I have to move this code to the end of Setting Axis by using TEXT function
			
			%Save the Center image's Row and Col for CrossHair-line displaying
			if theZIndex==theCenterZ,
				theCenterZ_Row =theRow;
				theCenterZ_Col =theCol;
			end
		end
	end		

	%Save View Series
	AConfig.ViewSeries = theZSeries;
	%Auto balance	
	theTransverseImg =SaturateContrast(theTransverseImg, AConfig.Contrast.SatMin, AConfig.Contrast.SatMax);
	
	%Calculate the Result Image after Magnifying
	theMagnifyCoefficient =GetMagnifyCoefficient(AConfig);
	if license('test','image_toolbox')==1 && theMagnifyCoefficient~=1, 		
		theTransverseImg=imresize(theTransverseImg, theMagnifyCoefficient);
	end
	
	% Revise the Axes position to make it comfort to Magnify
	theFramePosParamSet =get(AConfig.hFrameSetPos, 'Position');
	theLeft 	=theFramePosParamSet(1) +theFramePosParamSet(3) +5;
	theBottom 	=10; %theFramePosParamSet(2);	
	thePosTransverse 	=[theLeft, theBottom, size(theTransverseImg,2), size(theTransverseImg,1)];
	
	%Map images to true color	
	theTransverseImg =repmat(theTransverseImg, [1 1 3]);
	
	%Add overlay
	if SeeOverlay(AConfig),
		theTransverseImg =AddOverlaySeries(AConfig, theTransverseImg);
	end
	
	% Show Images
	%Sagittal		
	set(AConfig.hAxesSagittal, 'Visible','off');
	set(AConfig.hImageSagittal,'Visible','off');
	set(AConfig.hXLineSagittal, 'Visible','off');
	set(AConfig.hYLineSagittal, 'Visible','off');	
	%Coronal		 
	set(AConfig.hAxesCoronal, 'Visible','off');
	set(AConfig.hImageCoronal,'Visible','off');
	set(AConfig.hXLineCoronal, 'Visible','off');
	set(AConfig.hYLineCoronal, 'Visible','off');	
	
	%Transverse
	%theTransverseImg =repmat(theTransverseImg, [1, 1, 3])/AConfig.Contrast.GrayDepth; % For true color display
	set(AConfig.hImageTransverse, 'CData', (theTransverseImg), 'HitTest', 'off', 'Visible','on');
	%colormap(gray(AConfig.Contrast.GrayDepth));	
	set(AConfig.hAxesTransverse, 'Visible','on', ...
		'XLim', [1 size(theTransverseImg,2)], ...
		'YLim', [1 size(theTransverseImg,1)], ...
		'Position', thePosTransverse);	
	set(AConfig.hXLineTransverse, 'HitTest','off','Visible', IsCrosshairChecked(AConfig), ...		
		'XData', ([1 nDim1] +(theCenterZ_Col-1)*nDim1 )* theMagnifyCoefficient, ...
		'YData', ([1 1]*AConfig.LastPosition(2) + (theCenterZ_Row-1)*nDim2) *theMagnifyCoefficient);%Parallel to X-axis
	set(AConfig.hYLineTransverse, 'HitTest','off','Visible', IsCrosshairChecked(AConfig), ...		
		'XData', ([1 1]*AConfig.LastPosition(1)+(theCenterZ_Col-1)*nDim1) * theMagnifyCoefficient , ...
		'YData', ([1 nDim2]+(theCenterZ_Row-1)*nDim2)* theMagnifyCoefficient );%Parallel to Y-axis
	
	
	%Clear Text labels first
	ClearTextLabels(AConfig);
	
	%Write text label to indicate the Z value
	if AConfig.Montage.WantLabel,
		for theRow=AConfig.Montage.Down:-1:1,
			for theCol=1:AConfig.Montage.Across,
				%I don't draw the last image because it is used to indicate the positions				
				theZIndex = theZSeries((theRow-1)*AConfig.Montage.Across +theCol);
				theZIndex = theZIndex -AConfig.Origin(3);
												
				%Transform to Physical distance 20071102
				theZIndex = AConfig.VoxelSize(3) *theZIndex;
						
				
				theY =(theRow)*nDim2* theMagnifyCoefficient;
				theX =(theCol-1)*nDim1* theMagnifyCoefficient;
				
				text( theX,theY,sprintf('%+gmm',theZIndex), 'Parent', AConfig.hAxesTransverse, 'Color', AConfig.Overlay.LabelColor, 'HitTest', 'off', 'VerticalAlignment', 'top', 'Units', 'pixels');			
			end
		end	
	end
	
	Result =AConfig;
	
function Result =SetView_Sagittal(AConfig)
	[nDim1 nDim2 nDim3] =size(AConfig.Volume);
	theCenterX =AConfig.LastPosition(1);
	theCount   =AConfig.Montage.Across *AConfig.Montage.Down ;
	
	theXSeries =theCenterX -([floor(theCount/2) : -1 :ceil(-theCount/2)]) *AConfig.Montage.Spacing;	
	while ~isempty(find(theXSeries<=0)),
		theXSeries(find(theXSeries<=0)) = theXSeries(find(theXSeries<=0)) +nDim1;
	end
	while ~isempty(find(theXSeries>nDim1)),
		theXSeries(find(theXSeries>nDim1)) = theXSeries(find(theXSeries>nDim1)) -nDim1;
	end
	
	theSagittalImg = zeros(nDim3 * AConfig.Montage.Down, nDim2 *AConfig.Montage.Across);
	for theRow=AConfig.Montage.Down:-1:1,
		for theCol=1:AConfig.Montage.Across,
			%I don't draw the last image because it is used to indicate the positions				
			theXIndex = theXSeries((theRow-1)*AConfig.Montage.Across +theCol);
			theSagittalImg((theRow-1)*nDim3 +(1:nDim3), (theCol-1)*nDim2+(1:nDim2)) =GetGrayImage('Sagittal', AConfig.Volume, theXIndex);
			%Write the X Coordinates to the left-down corner
			%I have to move this code to the end of Setting Axis by using TEXT function
			
			%Save the Center image's Row and Col for CrossHair-line displaying
			if theXIndex==theCenterX,
				theCenterX_Row =theRow;
				theCenterX_Col =theCol;
			end
		end
	end		
	%Save View Series
	AConfig.ViewSeries = theXSeries;
	%Auto balance	
	theSagittalImg =SaturateContrast(theSagittalImg, AConfig.Contrast.SatMin, AConfig.Contrast.SatMax);
	
	%Calculate the Result Image after Magnifying
	theMagnifyCoefficient =GetMagnifyCoefficient(AConfig);
	if license('test','image_toolbox')==1 && theMagnifyCoefficient~=1, 		
		theSagittalImg=imresize(theSagittalImg, theMagnifyCoefficient);
	end
	
	% Revise the Axes position to make it comfort to Magnify
	theFramePosParamSet =get(AConfig.hFrameSetPos, 'Position');
	theLeft 	=theFramePosParamSet(1) +theFramePosParamSet(3) +5;
	theBottom 	=10; %theFramePosParamSet(2);	
	thePosSagittal 	=[theLeft, theBottom, size(theSagittalImg,2), size(theSagittalImg,1)];
	
	%Map images to true color	 
	theSagittalImg =repmat(theSagittalImg, [1 1 3]);
	
	%Add overlay
	if SeeOverlay(AConfig),
		theSagittalImg =AddOverlaySeries(AConfig, theSagittalImg);	
	end
	
	% Show Images
	%Transverse			
	set(AConfig.hAxesTransverse, 'Visible','off');
	set(AConfig.hImageTransverse,'Visible','off');
	set(AConfig.hXLineTransverse, 'Visible','off');
	set(AConfig.hYLineTransverse, 'Visible','off');
	%Coronal		 
	set(AConfig.hAxesCoronal, 'Visible','off');
	set(AConfig.hImageCoronal,'Visible','off');
	set(AConfig.hXLineCoronal, 'Visible','off');
	set(AConfig.hYLineCoronal, 'Visible','off');	
	
	%Transverse
	%theTransverseImg =repmat(theTransverseImg, [1, 1, 3])/AConfig.Contrast.GrayDepth; % For true color display
	set(AConfig.hImageSagittal, 'CData', (theSagittalImg), 'HitTest', 'off', 'Visible','on');
	%colormap(gray(AConfig.Contrast.GrayDepth));	
	set(AConfig.hAxesSagittal, 'Visible','on', ...
		'XLim', [1 size(theSagittalImg,2)], ...
		'YLim', [1 size(theSagittalImg,1)], ...
		'Position', thePosSagittal);	
	set(AConfig.hXLineSagittal, 'HitTest','off','Visible', IsCrosshairChecked(AConfig), ...		
		'XData', ([1 nDim2] +(theCenterX_Col-1)*nDim2 )* theMagnifyCoefficient, ...
		'YData', ([1 1]*AConfig.LastPosition(3) + (theCenterX_Row-1)*nDim3) *theMagnifyCoefficient);%Parallel to X-axis
	set(AConfig.hYLineSagittal, 'HitTest','off','Visible', IsCrosshairChecked(AConfig), ...		
		'XData', ([1 1]*AConfig.LastPosition(2)+(theCenterX_Col-1)*nDim2) * theMagnifyCoefficient , ...
		'YData', ([1 nDim3]+(theCenterX_Row-1)*nDim3)* theMagnifyCoefficient );%Parallel to Y-axis
		
	%Clear Text labels first
	ClearTextLabels(AConfig);	
	%Write text label to indicate the Z value
	if AConfig.Montage.WantLabel,
		for theRow=AConfig.Montage.Down:-1:1,
			for theCol=1:AConfig.Montage.Across,							
				theXIndex = theXSeries((theRow-1)*AConfig.Montage.Across +theCol);
				theXIndex = theXIndex -AConfig.Origin(1);
				
				%Transform to Physical distance 20071102
				theXIndex = AConfig.VoxelSize(1) *theXIndex;
				%Dawnsong 20071102 Revise to make sure the left image/Right brain is +
				theXIndex =(-1) *theXIndex;
							
				
				theY =(theRow)*nDim3* theMagnifyCoefficient;
				theX =(theCol-1)*nDim2* theMagnifyCoefficient;
				text( theX,theY,sprintf('%+gmm',theXIndex), 'Parent', AConfig.hAxesSagittal, 'Color', AConfig.Overlay.LabelColor, 'HitTest', 'off', 'VerticalAlignment', 'top', 'Units', 'pixels');			
			end
		end	
	end
			
	Result =AConfig;
	
function Result =SetView_Coronal(AConfig)
	[nDim1 nDim2 nDim3] =size(AConfig.Volume);
	theCenterY =AConfig.LastPosition(2);
	theCount   =AConfig.Montage.Across *AConfig.Montage.Down ;
	
	theYSeries =theCenterY -([floor(theCount/2) : -1 :ceil(-theCount/2)]) *AConfig.Montage.Spacing;	
	while ~isempty(find(theYSeries<=0)),
		theYSeries(find(theYSeries<=0)) = theYSeries(find(theYSeries<=0)) +nDim2;
	end
	while ~isempty(find(theYSeries>nDim2)),
		theYSeries(find(theYSeries>nDim2)) = theYSeries(find(theYSeries>nDim2)) -nDim2;
	end
	
	theCoronalImg = zeros(nDim3 * AConfig.Montage.Down, nDim1 *AConfig.Montage.Across);
	for theRow=AConfig.Montage.Down:-1:1,
		for theCol=1:AConfig.Montage.Across,
			%I don't draw the last image because it is used to indicate the positions				
			theYIndex = theYSeries((theRow-1)*AConfig.Montage.Across +theCol);
			theCoronalImg((theRow-1)*nDim3 +(1:nDim3), (theCol-1)*nDim1+(1:nDim1)) =GetGrayImage('Coronal', AConfig.Volume, theYIndex);
			%Write the Z Coordinates to the left-down corner
			%I have to move this code to the end of Setting Axis by using TEXT function
			
			%Save the Center image's Row and Col for CrossHair-line displaying
			if theYIndex==theCenterY,
				theCenterY_Row =theRow;
				theCenterY_Col =theCol;
			end
		end
	end			
	%Save View Series
	AConfig.ViewSeries = theYSeries;
	%Auto balance
	theCoronalImg =SaturateContrast(theCoronalImg, AConfig.Contrast.SatMin, AConfig.Contrast.SatMax);
	
	%Calculate the Result Image after Magnifying
	theMagnifyCoefficient =GetMagnifyCoefficient(AConfig);
	if license('test','image_toolbox')==1 && theMagnifyCoefficient~=1, 		
		theCoronalImg=imresize(theCoronalImg, theMagnifyCoefficient);
	end
	
	% Revise the Axes position to make it comfort to Magnify
	theFramePosParamSet =get(AConfig.hFrameSetPos, 'Position');
	theLeft 	=theFramePosParamSet(1) +theFramePosParamSet(3) +5;
	theBottom 	=10; %theFramePosParamSet(2);	
	thePosCoronal 	=[theLeft, theBottom, size(theCoronalImg,2), size(theCoronalImg,1)];
	
	%Map images to true color	
	theCoronalImg =repmat(theCoronalImg, [1 1 3]);
	
	%Add overlay
	if SeeOverlay(AConfig),
		theCoronalImg =AddOverlaySeries(AConfig, theCoronalImg);	
	end
	
	% Show Images
	%Transverse			
	set(AConfig.hAxesTransverse, 'Visible','off');
	set(AConfig.hImageTransverse,'Visible','off');
	set(AConfig.hXLineTransverse, 'Visible','off');
	set(AConfig.hYLineTransverse, 'Visible','off');
	%Sagittal
	set(AConfig.hAxesSagittal, 'Visible','off');
	set(AConfig.hImageSagittal,'Visible','off');
	set(AConfig.hXLineSagittal, 'Visible','off');
	set(AConfig.hYLineSagittal, 'Visible','off');
		
	%Transverse
	%theTransverseImg =repmat(theTransverseImg, [1, 1, 3])/AConfig.Contrast.GrayDepth; % For true color display
	set(AConfig.hImageCoronal, 'CData', (theCoronalImg), 'HitTest', 'off', 'Visible','on');
	%colormap(gray(AConfig.Contrast.GrayDepth));	
	set(AConfig.hAxesCoronal, 'Visible','on', ...
		'XLim', [1 size(theCoronalImg,2)], ...
		'YLim', [1 size(theCoronalImg,1)], ...
		'Position', thePosCoronal);	
	
	set(AConfig.hXLineCoronal, 'HitTest','off','Visible', IsCrosshairChecked(AConfig), ...		
		'XData', ([1 nDim1] +(theCenterY_Col-1)*nDim1 )* theMagnifyCoefficient, ...
		'YData', ([1 1]*AConfig.LastPosition(3) + (theCenterY_Row-1)*nDim3) *theMagnifyCoefficient);%Parallel to X-axis
	set(AConfig.hYLineCoronal, 'HitTest','off','Visible', IsCrosshairChecked(AConfig), ...		
		'XData', ([1 1]*AConfig.LastPosition(1)+(theCenterY_Col-1)*nDim1) * theMagnifyCoefficient , ...
		'YData', ([1 nDim3]+(theCenterY_Row-1)*nDim3)* theMagnifyCoefficient );%Parallel to Y-axis
		
	%Clear Text labels first
	ClearTextLabels(AConfig);	
	%Write text label to indicate the Z value
	if AConfig.Montage.WantLabel,
		for theRow=AConfig.Montage.Down:-1:1,
			for theCol=1:AConfig.Montage.Across,
				%I don't draw the last image because it is used to indicate the positions				
				theYIndex = theYSeries((theRow-1)*AConfig.Montage.Across +theCol);
				theYIndex = theYIndex -AConfig.Origin(2);
								
				%Transform to Physical distance 20071102
				theYIndex = AConfig.VoxelSize(2) *theYIndex;
										
				
				theY =theRow*nDim3* theMagnifyCoefficient;
				theX =(theCol-1)*nDim1* theMagnifyCoefficient;
				text( theX,theY,sprintf('%+gmm',theYIndex), 'Parent', AConfig.hAxesCoronal, 'Color', AConfig.Overlay.LabelColor, 'HitTest', 'off', 'VerticalAlignment', 'top', 'Units', 'pixels');			
			end
		end	
	end
	Result =AConfig;
	
function Result =GetGrayImage(AType, AVolume, APosition)
%Return raw image data at specific position in the Volume
	if nargin~=3, error('Result =GetGrayImage(AVolume, AType)'); end
	switch lower(AType)
	case 'sagittal',
		Result =squeeze(AVolume(APosition, :, :));
	case 'coronal',
		Result =squeeze(AVolume(:,APosition, :));
	case 'transverse',
		Result =squeeze(AVolume(:, :, APosition));
	otherwise
	end
	Result =Result';
	
function Result =ClickPositionCrossHair(AConfig)
	theFig 			=AConfig.hFig;
	hAxesSagittal 	=AConfig.hAxesSagittal;
	hAxesCoronal 	=AConfig.hAxesCoronal;
	hAxesTransverse =AConfig.hAxesTransverse;
	theAxes			=get(theFig, 'CurrentObject');
	%Check legal click point in the axes
	thePoint		=get(theAxes,'CurrentPoint');
	thePoint 		=thePoint(1, 1:2);
    theXLim =get(theAxes, 'XLim');
    theYLim =get(theAxes, 'YLim');	
	if thePoint(1)<theXLim(1) || thePoint(1)>theXLim(2) ...
	   || thePoint(2)<theYLim(1) || thePoint(2)>theYLim(2) ,
		Result =AConfig;
		return;
	end	
	
	thePosition		=AConfig.LastPosition; 
	theMagnifyCoefficient =GetMagnifyCoefficient(AConfig);	
	switch theAxes,
	case hAxesSagittal,
		thePosition(2) =round(thePoint(1));% x is Y
		thePosition(3) =round(thePoint(2));%y is Z		
		%Calculate the Result Position after Magnifying
		if license('test','image_toolbox')==1 && theMagnifyCoefficient~=1, 
			thePosition(2) =round(thePosition(2) / theMagnifyCoefficient);		
			thePosition(3) =round(thePosition(3) / theMagnifyCoefficient);		
		end
	case hAxesCoronal,
		thePosition(1) =round(thePoint(1));%x is X
		thePosition(3) =round(thePoint(2));%x is Z
		%Calculate the Result Position after Magnifying
		if license('test','image_toolbox')==1 && theMagnifyCoefficient~=1, 
			thePosition(1) =round(thePosition(1) / theMagnifyCoefficient);		
			thePosition(3) =round(thePosition(3) / theMagnifyCoefficient);		
		end
	case hAxesTransverse,
		thePosition(1) =round(thePoint(1));%x is  X
		thePosition(2) =round(thePoint(2));%y is Y
		%Calculate the Result Position after Magnifying
		if license('test','image_toolbox')==1 && theMagnifyCoefficient~=1, 
			thePosition(1) =round(thePosition(1) / theMagnifyCoefficient);		
			thePosition(2) =round(thePosition(2) / theMagnifyCoefficient);		
		end
	otherwise
		error(sprintf('Error call: It must be called by Axes''s ButtonDownFcn\nWhy did this occur?\nThere must be something wrong.\nrun "clear all" or re-start MATLAB to avoid this error.\n Dawnwei.song 20070526'));
	end
	
	% AConfig.LastPosition =thePosition;
	AConfig =UpdatePosition(AConfig, thePosition);
	%Display Images
	AConfig =SetImage(AConfig);
	
	Result =AConfig;
	
function Result =ClickPositionInSagittalMode(AConfig)
	theFig 			=AConfig.hFig;
	[nDim1 nDim2 nDim3] =size(AConfig.Volume);
	theAxes			=get(theFig, 'CurrentObject');
	%Check legal click point in the axes
	thePoint		=get(theAxes,'CurrentPoint');
	thePoint 		=round(thePoint(1, 1:2));
    theXLim =get(theAxes, 'XLim');
    theYLim =get(theAxes, 'YLim');	
	if thePoint(1)<theXLim(1) || thePoint(1)>theXLim(2) ...
	   || thePoint(2)<theYLim(1) || thePoint(2)>theYLim(2) ,
		Result =AConfig;
		return;
	end	
	
	theMagnifyCoefficient =GetMagnifyCoefficient(AConfig);
	thePosition		=AConfig.LastPosition; 
	thePosition(2)  =mod(thePoint(1), nDim2* theMagnifyCoefficient);% x is Y
	thePosition(3)  =mod(thePoint(2), nDim3* theMagnifyCoefficient);%y is Z		
		
	theSeries_RowId =ceil(thePoint(2)/ (theYLim(2)/AConfig.Montage.Down));
	theSeries_ColId =ceil(thePoint(1)/ (theXLim(2)/AConfig.Montage.Across));
	thePointId_inSeries =(theSeries_RowId -1)*AConfig.Montage.Across +theSeries_ColId;
	
	%Calculate the Result Position after Magnifying
	if license('test','image_toolbox')==1 && theMagnifyCoefficient~=1, 
		thePosition(2) =round(thePosition(2) / theMagnifyCoefficient);		
		thePosition(3) =round(thePosition(3) / theMagnifyCoefficient);		
		theXLim 	   =round(theXLim /theMagnifyCoefficient);
		theYLim 	   =round(theYLim /theMagnifyCoefficient);
	end		
	
	%Set the real position
	thePosition(1) = AConfig.ViewSeries(thePointId_inSeries);	
	% AConfig.LastPosition =thePosition;
	AConfig =UpdatePosition(AConfig, thePosition);
	
	%Display Images
	AConfig =SetImage(AConfig);	
	
	Result =AConfig;
	
function Result =ClickPositionInCoronalMode(AConfig)
	theFig 			=AConfig.hFig;
	[nDim1 nDim2 nDim3] =size(AConfig.Volume);
	theAxes			=get(theFig, 'CurrentObject');
	%Check legal click point in the axes
	thePoint		=get(theAxes,'CurrentPoint');
	thePoint 		=round(thePoint(1, 1:2));
    theXLim =get(theAxes, 'XLim');
    theYLim =get(theAxes, 'YLim');	
	if thePoint(1)<theXLim(1) || thePoint(1)>theXLim(2) ...
	   || thePoint(2)<theYLim(1) || thePoint(2)>theYLim(2) ,
		Result =AConfig;
		return;
	end	
	
	theMagnifyCoefficient =GetMagnifyCoefficient(AConfig);
	thePosition		=AConfig.LastPosition; 
	thePosition(1)  =mod(thePoint(1), nDim1* theMagnifyCoefficient);% x is Y
	thePosition(3)  =mod(thePoint(2), nDim3* theMagnifyCoefficient);%y is Z		
	
	
	theSeries_RowId =ceil(thePoint(2)/ (theYLim(2)/AConfig.Montage.Down));
	theSeries_ColId =ceil(thePoint(1)/ (theXLim(2)/AConfig.Montage.Across));
	thePointId_inSeries =(theSeries_RowId -1)*AConfig.Montage.Across +theSeries_ColId;
	
	%Calculate the Result Position after Magnifying
	if license('test','image_toolbox')==1 && theMagnifyCoefficient~=1, 
		thePosition(1) =round(thePosition(1) / theMagnifyCoefficient);		
		thePosition(3) =round(thePosition(3) / theMagnifyCoefficient);		
		theXLim 	   =round(theXLim /theMagnifyCoefficient);
		theYLim 	   =round(theYLim /theMagnifyCoefficient);
	end		
	
	%Set the real position
	thePosition(2) = AConfig.ViewSeries(thePointId_inSeries);	
	% AConfig.LastPosition =thePosition;
	AConfig =UpdatePosition(AConfig, thePosition);
	
	%Display Images
	AConfig =SetImage(AConfig);	
	
	Result =AConfig;	
	
function Result =ClickPositionInTransverseMode(AConfig)
	theFig 			=AConfig.hFig;
	[nDim1 nDim2 nDim3] =size(AConfig.Volume);
	theAxes			=get(theFig, 'CurrentObject');
	%Check legal click point in the axes
	thePoint		=get(theAxes,'CurrentPoint');
	thePoint 		=round(thePoint(1, 1:2));
    theXLim =get(theAxes, 'XLim');
    theYLim =get(theAxes, 'YLim');	
	if thePoint(1)<theXLim(1) || thePoint(1)>theXLim(2) ...
	   || thePoint(2)<theYLim(1) || thePoint(2)>theYLim(2) ,
		Result =AConfig;
		return;
	end	
	
	theMagnifyCoefficient =GetMagnifyCoefficient(AConfig);
	thePosition		=AConfig.LastPosition; 
	thePosition(1)  =mod(thePoint(1), nDim1* theMagnifyCoefficient);% x is Y
	thePosition(2)  =mod(thePoint(2), nDim2* theMagnifyCoefficient);%y is Z		
				
	theSeries_RowId =ceil(thePoint(2)/ (theYLim(2)/AConfig.Montage.Down));
	theSeries_ColId =ceil(thePoint(1)/ (theXLim(2)/AConfig.Montage.Across));
	thePointId_inSeries =(theSeries_RowId -1)*AConfig.Montage.Across +theSeries_ColId;
	
	%Calculate the Result Position after Magnifying
	if license('test','image_toolbox')==1 && theMagnifyCoefficient~=1, 
		thePosition(1) =round(thePosition(1) / theMagnifyCoefficient);		
		thePosition(2) =round(thePosition(2) / theMagnifyCoefficient);		
		theXLim 	   =round(theXLim /theMagnifyCoefficient);
		theYLim 	   =round(theYLim /theMagnifyCoefficient);
	end		
	
	%Set the real position
	thePosition(3) = AConfig.ViewSeries(thePointId_inSeries);	
	% AConfig.LastPosition =thePosition;
	AConfig =UpdatePosition(AConfig, thePosition);
	
	%Display Images
	AConfig =SetImage(AConfig);	
	
	Result =AConfig;

function Result =SetPositionCrossHair(AConfig)		
	% theCurrentControl =gco;
	% uicontrol(AConfig.hYoke);
	%I must change the current focus to force the callback of the edit to run at once to make sure 'get' can return current string/value instead of old value
	% when I use KeyPressFcn. And KeyPressFcn didn't exist for uicontrol before Matlab 7. In Matlab 6.5, there is only KeyPressFcn for figure;
	
	thePosition =AConfig.LastPosition;	
	theXLim =[1, size(AConfig.Volume, 1)];
	theYLim =[1, size(AConfig.Volume, 2)];
	theZLim =[1, size(AConfig.Volume, 3)];
	theX =str2num(get(AConfig.hEditPositionX, 'String'));
	theY =str2num(get(AConfig.hEditPositionY, 'String'));
	theZ =str2num(get(AConfig.hEditPositionZ, 'String'));
	
	%Revise Direction , dawnsong20071101
	theX = theX * (-1);
	
	
	theX =round(theX/AConfig.VoxelSize(1) +AConfig.Origin(1));
	theY =round(theY/AConfig.VoxelSize(2) +AConfig.Origin(2));
	theZ =round(theZ/AConfig.VoxelSize(3) +AConfig.Origin(3));
	
	
	
	% uicontrol(theCurrentControl);
	
	if ~isempty(theX) && theX>=theXLim(1) ...
		&& ~isempty(theY) && theY>=theYLim(1) ...
		&& ~isempty(theZ) && theZ>=theZLim(1) ...
		&& any(thePosition ~= [theX theY theZ]) ,
		
		if theX >theXLim(2), theX =theXLim(2); end
		if theY >theYLim(2), theY =theYLim(2); end
		if theZ >theZLim(2), theZ =theZLim(2); end
		
		thePosition =[theX theY theZ];		
		% AConfig.LastPosition =thePosition;
		AConfig =UpdatePosition(AConfig, thePosition);
	end		
	
	%Display Images
	AConfig =SetImage(AConfig);
	%Save LastPosition
	Result =AConfig;
	
function Result =SetDistanceFromOrigin(AConfig, ADistanceFromOrigin);
% Set current cross-hair position according to the Proportion Position among many size-not-equal brain images			
	thePosition = ADistanceFromOrigin ./ AConfig.VoxelSize + AConfig.Origin;
	thePosition =round(thePosition);
	if any(thePosition ~= AConfig.LastPosition) ...
		&& thePosition(1)>=1 && thePosition(1)<=size(AConfig.Volume,1) ...
		&& thePosition(2)>=1 && thePosition(2)<=size(AConfig.Volume,2) ...
		&&  thePosition(3)>=1 && thePosition(3)<=size(AConfig.Volume,3) , ...
		% AConfig.LastPosition =thePosition;
		AConfig =UpdatePosition(AConfig, thePosition);
	elseif any(thePosition ~= AConfig.LastPosition),
		for x=1:3,
			while thePosition(x)<1,
				thePosition(x) =thePosition(x) +size(AConfig.Volume,x);
			end
			while thePosition(x)>size(AConfig.Volume,x),
				thePosition(x) =thePosition(x) -size(AConfig.Volume,x);
			end
		end
	end
	
	%Display Images
	AConfig =SetImage(AConfig);	
	%Save LastPosition
	Result =AConfig;
	
function ShowPositionInEdit(AConfig)
	thePosition =AConfig.LastPosition;
	set(AConfig.hEditPositionX, 'String', num2str((thePosition(1)-AConfig.Origin(1))*AConfig.VoxelSize(1) *(-1) ));	%Make sure Left is Right like BA, and Left-image is + or Right-Brain is +
	set(AConfig.hEditPositionY, 'String', num2str((thePosition(2)-AConfig.Origin(2) )*AConfig.VoxelSize(2) ));	%Make sure Fore is +
	set(AConfig.hEditPositionZ, 'String', num2str((thePosition(3)-AConfig.Origin(3) )*AConfig.VoxelSize(3) ));	%Make sure Top is +
	
function SetMessage(AConfig)
	%Detect if I should hide the big information area
	theTitle ='Click to Toggle Hdr info';
	theOldMsg =get(AConfig.hMsgLabel, 'String');
	
	if SeeOverlay(AConfig),
		%Compute the cooresponding position according to physical distance(mm) from origin
		thePhysicalPos = (AConfig.LastPosition -AConfig.Origin) .* AConfig.VoxelSize;
		theOverlayPos  = thePhysicalPos ./ AConfig.Overlay.VoxelSize +AConfig.Overlay.Origin;
		theOverlayPos =round(theOverlayPos);
		if all(theOverlayPos<=size(AConfig.Overlay.Volume)) ...
			&& all(theOverlayPos >=[1 1 1]),
			%Legal
		else%Illegal data
			warning(sprintf('Illegal Overlay Position: (%s)\nI will revise the underlay''s position to its origin.', num2str(theOverlayPos)));
			%Revise the LastPosition on the underlay to the origin
			AConfig.LastPosition =AConfig.Origin;	%This line will not work because This fun didn't save the Global variable AConfig
			nic_rest_sliceviewer('SetPhysicalPosition', AConfig.hFig, [0 0 0]);
			nic_rest_sliceviewer('Repaint', AConfig.hFig);
			return;
		end
		
		theUnderlayIntensity =AConfig.Volume(AConfig.LastPosition(1),AConfig.LastPosition(2),AConfig.LastPosition(3));
		 
		theOverlayIntensity  =AConfig.Overlay.Volume(theOverlayPos(1),theOverlayPos(2),theOverlayPos(3));
		if  prod(size(AConfig.Overlay.InfoAal))==116 ...
			&& theOverlayIntensity>0,	%AAL template description
			theIntensity =sprintf('%s\n%g / %g', AConfig.Overlay.InfoAal{theOverlayIntensity},theUnderlayIntensity, theOverlayIntensity);
		else	%Default
			%Show the voxel's intensity for underlay and overlay
			theIntensity =sprintf('\n%g / %g', theUnderlayIntensity, theOverlayIntensity);
		end
		
		set(AConfig.hVoxelIntensity, 'String', theIntensity, 'TooltipString', ['Value: Underlay/Overlay = ', theIntensity]);
		
		theUnderlayInfo =sprintf('Dimension: %dx%dx%d\nVoxel(mm): %gx%gx%g\nOrigin(vxl): %d,%d,%d',size(AConfig.Volume,1), size(AConfig.Volume, 2), size(AConfig.Volume, 3), AConfig.VoxelSize(1), AConfig.VoxelSize(2),AConfig.VoxelSize(3), AConfig.Origin(1), AConfig.Origin(2), AConfig.Origin(3));
		theUnderlayInfo =sprintf('Underlay:\n%s\n\n', theUnderlayInfo);
		theOverlayInfo =sprintf('Dimension: %dx%dx%d\nVoxel(mm): %gx%gx%g\nOrigin(vxl): %d,%d,%d',size(AConfig.Overlay.Volume,1), size(AConfig.Overlay.Volume, 2), size(AConfig.Overlay.Volume, 3), AConfig.Overlay.VoxelSize(1), AConfig.Overlay.VoxelSize(2),AConfig.Overlay.VoxelSize(3), AConfig.Overlay.Origin(1), AConfig.Overlay.Origin(2), AConfig.Overlay.Origin(3));
		theOverlayInfo =sprintf('Overlay: (%s)\n%s', num2str((Pos_Underlay2Overlay(AConfig, AConfig.LastPosition) -AConfig.Overlay.Origin).*AConfig.Overlay.VoxelSize .* [-1, 1, 1]),theOverlayInfo);
		
		theInfo =[theUnderlayInfo theOverlayInfo];
		%set(AConfig.hMsgLabel, 'String', theInfo);
	else	%Don't see Overlay
		theIntensity =sprintf('\n%g',AConfig.Volume(AConfig.LastPosition(1),AConfig.LastPosition(2),AConfig.LastPosition(3)));
		set(AConfig.hVoxelIntensity, 'String', theIntensity, 'TooltipString', ['Value: Underlay ', theIntensity]);
		
		theInfo =sprintf('Dimension: %dx%dx%d\nVoxel(mm): %gx%gx%g\nOrigin(vxl): %d,%d,%d',size(AConfig.Volume,1), size(AConfig.Volume, 2), size(AConfig.Volume, 3), AConfig.VoxelSize(1), AConfig.VoxelSize(2),AConfig.VoxelSize(3), AConfig.Origin(1), AConfig.Origin(2), AConfig.Origin(3));
		%set(AConfig.hMsgLabel, 'String', theInfo);
	end	
	
	if ~isempty(AConfig.Message) && ~all(isspace(AConfig.Message)),
		theInfo =sprintf('%s\n\n%s', theInfo, AConfig.Message);
	end
	
	if strcmpi(theTitle, theOldMsg),
		%Hide the Information as the old
		%set(AConfig.hMsgLabel, 'String', theInfo);
		set(AConfig.hMsgLabel, 'TooltipString', theInfo);
	else	%Normally showing the Hdr info
		set(AConfig.hMsgLabel, 'String', theInfo,'TooltipString', '');
	end
		
	
	
	
	%Threshhold value display
	set(AConfig.hEdtThrdValue, 'String', num2str(AConfig.Overlay.ValueThrdAbsolute));
	
	return;
		
function ResizeFigure(AConfig)
	MarginX =10; MarginY =10;	
	[nDim1, nDim2, nDim3] =size(AConfig.Volume);
	
	if strcmpi(get(AConfig.hFrameSetPos, 'Visible'), 'on'),
		theFramePos =get(AConfig.hFrameSetPos, 'Position');	
	else
		theFramePos =[0 0 0 0];
	end
	theMagnifyCoefficient =GetMagnifyCoefficient(AConfig); % Considering Magnifying result
	nDim1 =nDim1 *theMagnifyCoefficient;
	nDim2 =nDim2 *theMagnifyCoefficient;
	nDim3 =nDim3 *theMagnifyCoefficient;
	if strcmpi(AConfig.ViewMode, 'Orthogonal'),
		FigWidth  =theFramePos(1) +theFramePos(3) +MarginX + nDim1 +2 +nDim2 + MarginX;
		FigHeight =10 + nDim2 +2 +nDim3 + MarginY;		
	elseif strcmpi(AConfig.ViewMode, 'Transverse'),
		FigWidth  =theFramePos(1) +theFramePos(3) +MarginX + nDim1 * AConfig.Montage.Across + MarginX;
		FigHeight =MarginY + nDim2 * AConfig.Montage.Down + MarginY;		
	elseif strcmpi(AConfig.ViewMode, 'Sagittal'),
		FigWidth  =theFramePos(1) +theFramePos(3) +MarginX + nDim2 * AConfig.Montage.Across + MarginX;
		FigHeight =MarginY + nDim3 * AConfig.Montage.Down + MarginY;		
	elseif strcmpi(AConfig.ViewMode, 'Coronal'),
		FigWidth  =theFramePos(1) +theFramePos(3) +MarginX + nDim1 * AConfig.Montage.Across + MarginX;
		FigHeight =MarginY + nDim3 * AConfig.Montage.Down + MarginY;		
	end
	%Resize figure's width according to colorbar's visiblity
	if SeeOverlay(AConfig),
		theColorBarPos=get(AConfig.hAxesColorbar, 'Position');
		FigWidth = FigWidth +MarginX +theColorBarPos(3) +1.5*MarginX +MarginX;
	end
	%FigHeight =theFramePos(2) + nDim2 +2 +nDim3 + MarginY;
		
	
	% Revise the Intensity position	
	% theMsgPos =get(AConfig.hVoxelIntensity, 'Position');
	% theMsgPos(1) =theFramePos(1) +theFramePos(3) +MarginX + nDim1 +5;
	% theMsgPos(2) =theFramePos(2);
	% theMsgPos(3) = FigWidth -theMsgPos(1) -MarginX;
	% set(AConfig.hVoxelIntensity, 'Position', theMsgPos); %Set first
	
	% theIntensity =get(AConfig.hVoxelIntensity, 'String');
	% [newMsg,newMsgPos]=textwrap(AConfig.hVoxelIntensity, {theIntensity});
	% set(AConfig.hVoxelIntensity, 'Position', newMsgPos);
	
	%Revise the Message's position
	if strcmpi(get(AConfig.hMsgLabel,'Visible'), 'on'),
		theMsgPos =get(AConfig.hMsgLabel, 'Position');
		theMsgPos(1) =theFramePos(1);
		theMsgPos(2) =theFramePos(2) +theFramePos(4) +MarginY;
		theMsgPos(3) =theFramePos(3);
		theMsgPos(4) =1;
		set(AConfig.hMsgLabel, 'Position', theMsgPos); %Set default position first
		
		theMsg =get(AConfig.hMsgLabel, 'String');
		[theMsg, theMsgPos] =textwrap(AConfig.hMsgLabel, cellstr(theMsg));
		set(AConfig.hMsgLabel, 'String', theMsg, 'Position', theMsgPos);
	end
	% Revise the Do Callback Button's position
	% if AConfig.hDoCallbackBtn>0
		% thePos =get(AConfig.hDoCallbackBtn, 'Position');
		% thePos(1) =theMsgPos(1);
		% thePos(2) =theMsgPos(2) +theMsgPos(4) +MarginY;
		% thePos(3) =theMsgPos(3);
		% thePos(4) =25;
		% set(AConfig.hDoCallbackBtn, 'Position', thePos);
	% end
	
	% Revise the figure's position according to the Brain Image's width and height	
	thePos 		=get(AConfig.hFig, 'Position');
	theScrPos	=get(0, 'ScreenSize');	
	% if AConfig.hDoCallbackBtn>0
		% theBtnPos =get(AConfig.hDoCallbackBtn, 'Position');
		% if FigHeight< (theBtnPos(2) +theBtnPos(4) +MarginY)
			% FigHeight =theBtnPos(2) +theBtnPos(4) +MarginY;
		% end
	% else end
	if strcmpi(get(AConfig.hMsgLabel,'Visible'), 'on'),
		theMsgPos =get(AConfig.hMsgLabel, 'Position');
		if FigHeight< (theMsgPos(2) +theMsgPos(4) +MarginY)
			FigHeight =theMsgPos(2) +theMsgPos(4) +MarginY;
		end
	end
	if (thePos(2) +FigHeight +60) > theScrPos(4)
		thePos(2) = theScrPos(4) -FigHeight -60;
	end
	if thePos(3) <FigWidth
		thePos(3) =FigWidth;
	elseif	thePos(3) >1.5*FigWidth
		thePos(3) =FigWidth;
	end
	thePos(4) =FigHeight;
	set(AConfig.hFig, 'Position', thePos);
	
	%Resize figure position according to the Message height
	if strcmpi(get(AConfig.hMsgLabel,'Visible'), 'on'),
		theMsgPos =get(AConfig.hMsgLabel, 'Position');
		if ( theMsgPos(2)+theMsgPos(4) )> thePos(4), 
			thePos(3) =FigWidth;
			thePos(4) =theMsgPos(2)+theMsgPos(4) +MarginY;
			set(AConfig.hFig, 'Position', thePos);
		end
	end	

function Result =GetMagnifyCoefficient(AConfig)	
	if license('test','image_toolbox')~=1 ,
		Result =1;
		return;
	end

	theStr =get(AConfig.hMagnify ,'String');
	theIdx =get(AConfig.hMagnify ,'Value');
	Result =1;
	switch upper(theStr{theIdx}),
	case 'X0.5',
		Result =0.5;
	case 'X1',
		Result =1;
	case 'X2',
		Result =2;
	case 'X3',
		Result =3;
	otherwise
		nic_rest_misc( 'ComplainWhyThisOccur');
	end

function Result =UpdateCallback(AConfig, ACallback, ACallbackCaption)
	Result =AConfig;
	Result.Callback =ACallback;
	% if ~isempty(ACallbackCaption) && ischar(ACallbackCaption)
		% theBtnCaption =ACallbackCaption;
	% else
		% theBtnCaption ='Do sth.';
	% end
	
	% if Result.hDoCallbackBtn>0
		% I have created the Button to respond to the click event
		% if ~isempty(ACallback) && ischar(ACallback) ,			
			% set(Result.hDoCallbackBtn, 'Callback', ACallback, 'String', theBtnCaption);
		% else
			% Remove the button because the Callback is illegal or empty
			% delete(Result.hDoCallbackBtn);
			% Result.hDoCallbackBtn =-1;
			% Result.Callback ='';
		% end
	% else
		% Create a Button responding the click event
		% if ~isempty(ACallback) && (ischar(ACallback) || isa(ACallback, 'function_handle')),
			% theCallback =sprintf('nic_rest_sliceviewer(''RunCallback'', ''%s'');',AConfig.Filename);
			% Result.hDoCallbackBtn =uicontrol(Result.hFig, 'Style','pushbutton',  ...
							  % 'Units','pixels','String', theBtnCaption, ...
							  % 'Callback', theCallback);							  
		% end
	% end	
	
function ClearTextLabels(AConfig)	
	%Clear Text labels first for multislice mode
	theLabels =findobj(AConfig.hAxesSagittal, 'Type', 'text');
	for theX=1:length(theLabels), delete(theLabels(theX)); end
	theLabels =findobj(AConfig.hAxesCoronal, 'Type', 'text');
	for theX=1:length(theLabels), delete(theLabels(theX)); end
	theLabels =findobj(AConfig.hAxesTransverse, 'Type', 'text');
	for theX=1:length(theLabels), delete(theLabels(theX)); end
	
function Result =AutoBalance(AConfig)
	Result =AConfig;
	%Save Maping Image parameters, Auto balance 20070911 revised, 20070914 revised for Statistical map which has negative values	
	%Revise first
	Result.Volume(isnan(Result.Volume)) =0;
	Result.Volume(isinf(Result.Volume)) =0;
	%Begin computation, the following two lines are time-consuming up to 4.6 seconds!!!
	%But after replacing AConfig with Result, then their speed rocketed to 0.2 seconds!!!
	%Attention!!! Dawnwei.Song, 20070914
	theMaxVal=max(Result.Volume(:));
	theMinVal=min(Result.Volume(:));
	if theMaxVal>theMinVal,
		nBins=255;
		%Special processing just for very common images! 20071212
		if (theMaxVal<257) && (theMinVal>=0) && (theMaxVal-theMinVal>100), %not statistic map
			theSum =histc(Result.Volume(:), 1:ceil(theMaxVal));		
		else
			theSum =histc(Result.Volume(:), theMinVal:(theMaxVal-theMinVal)/254:theMaxVal);		
		end
		theSum =cumsum(theSum);
		theCdf =theSum/theSum(end);
		if nic_rest_misc('GetMatlabVersion')>=7.3
			idxSatMin =find(theCdf>0.01, 1, 'first');
			idxSatMax =find(theCdf>=0.99, 1, 'first');			
		else
			idxSatMin =find(theCdf>0.01);
			idxSatMin =idxSatMin(1);
			idxSatMax =find(theCdf>=0.99);
			idxSatMax =idxSatMax(1);
		end	
		if idxSatMin==idxSatMax, idxSatMin =1; end	%20070919, For mask file's display
		theSatMin =(idxSatMin-1)/(nBins-1) *(theMaxVal-theMinVal) +theMinVal;
		theSatMax =(idxSatMax-1)/(nBins-1) *(theMaxVal-theMinVal) +theMinVal;	
	elseif theMaxVal==theMinVal,
		theSatMin =theMaxVal;
		theSatMax =theMaxVal;
	else
	end
	Result.Contrast.GrayDepth =255;
	Result.Contrast.SatMin =theSatMin;
	Result.Contrast.SatMax =theSatMax;
	%20070911, AutoBalance for contrast
	Result.Contrast.WindowWidth =theSatMax -theSatMin;
	Result.Contrast.WindowCenter=(theSatMax +theSatMin)/2;

	%For debug display
	% disp(Result.Contrast);
	
	
	
function Result =IsCrosshairChecked(AConfig)
	Result ='off';
	if get(AConfig.hCrosshair, 'Value'),
		Result ='on';
	end

function Transforming_MNI_Talairach(AConfig)
	isNeedUpdate =false;
	switch get(AConfig.hMniTal, 'Value'),
	case 1,	%'MNI/Talairach Coordinates'
		%Do nothing
	case 2, %'From Talairach to MNI'
		% AConfig.LastPosition 
		thePosition =round(rest_tal2mni(AConfig.LastPosition -AConfig.Origin) +AConfig.Origin);
		AConfig =UpdatePosition(AConfig, thePosition);
		isNeedUpdate =true;
	case 3, %'From MNI to Talairach'
		% AConfig.LastPosition 
		thePosition=round(rest_mni2tal(AConfig.LastPosition -AConfig.Origin) +AConfig.Origin);
		AConfig =UpdatePosition(AConfig, thePosition);
		isNeedUpdate =true;
	otherwise
	end
	% disp(AConfig.LastPosition);
	% return;
	
	if isNeedUpdate,
		ShowPositionInEdit(AConfig);
		SetMessage(AConfig);
		nic_rest_sliceviewer('SetPosition', AConfig.Filename);
	end
	%Reset position in Choice selection
	set(AConfig.hMniTal, 'Value', 1);
	

function Result =SaturateContrast(AImage, ASatMin, ASatMax)	
	Result =AImage;
	if ASatMin<ASatMax,
		Result(find(Result<ASatMin)) =ASatMin;
		Result(find(Result>ASatMax)) =ASatMax;
		Result =(Result -ASatMin)/(ASatMax - ASatMin);
	elseif ASatMin==ASatMax,
		Result(:) =0.01;
	else
		error('ASatMin>ASatMax ???');
	end
	
	%Map a indexed 2D image to a 2D * 3 image which is true color image and range is in [0 , 1]
	% Result =repmat(Result, [1 1 3]) /AGrayDepth;

function Result =InitUnderlay(AConfig)	
%Input: Need AConfig.Filename specified	
	try
		[theVolume,theVoxelSize, Header] =nic_rest_readfile(AConfig.Filename);  %%Yan 080610
        theOrigin=Header.Origin; %%Yan 080610
		AConfig =AddRecentUnderlay(AConfig, AConfig.Filename);		
        AConfig.Header=Header; %%Yan 080610
	catch
		if ~(exist(AConfig.Filename, 'file')==2) ...			
			&& ( ~all(isspace(AConfig.Filename)) && ~isempty(isspace(AConfig.Filename))),
			warning(sprintf('Please check whether Img/Hdr file "%s" exist!', AConfig.Filename));
			warndlg(sprintf('Please check whether Img/Hdr file "%s" exist!', AConfig.Filename));
		end
		theVolume =255*zeros(181,217,181);	%theVolume(:) =round([1:prod(size(theVolume))]/2^16);
		theVoxelSize =[1 1 1];
		theOrigin =[90 126 72];
	end
	[nDim1, nDim2, nDim3] =size(theVolume);
		
	% Displaying Orthogonal images 	
	theFramePos =get(AConfig.hFrameSetPos, 'Position');	
	MarginY =10; MarginX =10;
	OffsetX =theFramePos(1) +theFramePos(3) +MarginX;
	OffsetY =MarginY;	
	
	%Delete old handles if exists any
	if ishandle(AConfig.hAxesSagittal), delete(AConfig.hAxesSagittal); end
	if ishandle(AConfig.hAxesCoronal), delete(AConfig.hAxesCoronal); end
	if ishandle(AConfig.hAxesTransverse), delete(AConfig.hAxesTransverse); end	
	%Save Images' handles
	if ishandle(AConfig.hImageSagittal), delete(AConfig.hImageSagittal); end	
	if ishandle(AConfig.hImageCoronal), delete(AConfig.hImageCoronal); end	
	if ishandle(AConfig.hImageTransverse), delete(AConfig.hImageTransverse); end		
	%Save Lines' handles
	if ishandle(AConfig.hXLineSagittal), delete(AConfig.hXLineSagittal); end		%x
	if ishandle(AConfig.hYLineSagittal), delete(AConfig.hYLineSagittal); end		%y
	if ishandle(AConfig.hXLineCoronal), delete(AConfig.hXLineCoronal); end		%x
	if ishandle(AConfig.hYLineCoronal), delete(AConfig.hYLineCoronal); end		%y
	if ishandle(AConfig.hXLineTransverse), delete(AConfig.hXLineTransverse); end	%x	
	if ishandle(AConfig.hYLineTransverse), delete(AConfig.hYLineTransverse); end	%y	
	
	
	%Create Axes and lines and images
	theAxesButtonDownFcn =sprintf('nic_rest_sliceviewer(''ClickPosition'', %g);', AConfig.hFig);
	hAxesTransverse	=axes('Parent', AConfig.hFig, 'Box', 'on', ...
						  'Units', 'pixel', 'DrawMode','fast', ...
						  'Position', [OffsetX OffsetY nDim1 nDim2], ...
						  'YDir','normal', 'XTickLabel',[],'XTick',[], ...
						  'YTickLabel',[],'YTick',[], 'DataAspectRatio',[1 1 1],...
						  'ButtonDownFcn', theAxesButtonDownFcn);
	hImageTransverse =image('Tag','BrainImageTransverse', 'Parent', hAxesTransverse);
	set(hAxesTransverse,'YDir','normal','ButtonDownFcn', theAxesButtonDownFcn, 'XTickLabel',[],'XTick',[], ...
						  'YTickLabel',[],'YTick',[]);
	hXLineTransverse =line(0, 0, 'Parent', hAxesTransverse, 'Color', 'red');
	hYLineTransverse =line(0, 0, 'Parent', hAxesTransverse, 'Color', 'red');	
		
	hAxesCoronal 	=axes('Parent', AConfig.hFig, 'Box', 'on', ...
						  'Units', 'pixel', 'DrawMode','fast', ...
						  'Position', [OffsetX OffsetY+nDim2+2 nDim1 nDim3], ...
						  'YDir','normal', 'XTickLabel',[],'XTick',[], ...
						  'YTickLabel',[],'YTick',[], ...
						  'ButtonDownFcn', theAxesButtonDownFcn);
	hImageCoronal =image('Tag','BrainImageCoronal', 'Parent', hAxesCoronal);
	set(hAxesCoronal,'YDir','normal','ButtonDownFcn', theAxesButtonDownFcn, 'XTickLabel',[],'XTick',[], ...
						  'YTickLabel',[],'YTick',[]);
	hXLineCoronal =line(0, 0, 'Parent', hAxesCoronal, 'Color', 'red');
	hYLineCoronal =line(0, 0, 'Parent', hAxesCoronal, 'Color', 'red');
	
	hAxesSagittal 	=axes('Parent', AConfig.hFig, 'Box', 'on', ...
						  'Units', 'pixel', 'DrawMode','fast', ...
						  'Position', [OffsetX+nDim1+2 OffsetY+nDim2+2 nDim2 nDim3], ...
						  'YDir','normal', 'XTickLabel',[],'XTick',[], ...
						  'YTickLabel',[],'YTick',[], ...
						  'ButtonDownFcn', theAxesButtonDownFcn);
	hImageSagittal =image('Tag','BrainImageSagittal',  'Parent', hAxesSagittal);
	set(hAxesSagittal,'YDir','normal','ButtonDownFcn', theAxesButtonDownFcn, 'XTickLabel',[],'XTick',[], ...
						  'YTickLabel',[],'YTick',[]);
	hXLineSagittal =line(0, 0, 'Parent', hAxesSagittal, 'Color', 'red');
	hYLineSagittal =line(0, 0, 'Parent', hAxesSagittal, 'Color', 'red');		
	
	
	%Save Axes's handles
	AConfig.hAxesSagittal 	=hAxesSagittal;
	AConfig.hAxesCoronal 	=hAxesCoronal;
	AConfig.hAxesTransverse =hAxesTransverse;
	%Save Images' handles
	AConfig.hImageSagittal	 =hImageSagittal;
	AConfig.hImageCoronal 	 =hImageCoronal;
	AConfig.hImageTransverse =hImageTransverse;
	%Save Lines' handles
	AConfig.hXLineSagittal   =hXLineSagittal;		%x
	AConfig.hYLineSagittal   =hYLineSagittal;		%y
	AConfig.hXLineCoronal	 =hXLineCoronal;		%x
	AConfig.hYLineCoronal	 =hYLineCoronal;		%y
	AConfig.hXLineTransverse =hXLineTransverse;		%x
	AConfig.hYLineTransverse =hYLineTransverse;		%y
	
	AConfig.Volume =theVolume;	
	AConfig.VoxelSize =reshape(theVoxelSize, [1 3]);
	
	AConfig.Origin =reshape(theOrigin, [1 3]);
    AConfig.Header.Origin=AConfig.Origin;
	if any(AConfig.Origin==[0 0 0]),
		%Auto-Revise the Origin to the half of the size of the brain
		theMsg =sprintf('Illegal origin: (%s)\n\nI presume the origin is (%s)',num2str(AConfig.Origin), num2str(round(size(AConfig.Volume)/2)));
		warning(theMsg);
		warndlg(theMsg);
		AConfig.Origin =round(size(AConfig.Volume)/2);
	end	
	if norm(theOrigin)==0,
		AConfig.LastPosition =round([nDim1 nDim2 nDim3]/2);		%[x y z] the position in Volume corresponding to the cross-hair position 
	else
		if ~all(AConfig.LastPosition < size(theVolume)),	%If legal
			AConfig.LastPosition =reshape(AConfig.Origin, [1 3]);
		end		
	end
		
	%Auto balance
	AConfig=AutoBalance(AConfig);
	
	Result =AConfig;
	

	
function Result =SeeOverlay(AConfig)
	Result =get(AConfig.hSeeOverlay, 'Value');
	
function Result =GetOverlayImg(AType, AConfig, AUnderlayPosition)
%Return raw overlay image data by computing the real physical distance(mm) from the origin	 % AUnderlayPosition is a scalar, result is a slice according to AType and AUnderlayPosition	
	theVolume =AConfig.Overlay.VolumeThrd;
		
	switch lower(AType)
	case 'sagittal',
		thePhysicalPosition =(AUnderlayPosition -AConfig.Origin(1)) *AConfig.VoxelSize(1);
		thePhysicalPosition =thePhysicalPosition/AConfig.Overlay.VoxelSize(1) +AConfig.Overlay.Origin(1);
		if thePhysicalPosition>size(theVolume, 1),
			thePhysicalPosition =size(theVolume, 1);
		elseif thePhysicalPosition<1,
			thePhysicalPosition =1;
		end
		
		Result =squeeze(theVolume(round(thePhysicalPosition), :, :));
		
	case 'coronal',		
		thePhysicalPosition =(AUnderlayPosition -AConfig.Origin(2)) *AConfig.VoxelSize(2);
		thePhysicalPosition =thePhysicalPosition/AConfig.Overlay.VoxelSize(2) +AConfig.Overlay.Origin(2);
		if thePhysicalPosition>size(theVolume, 2),
			thePhysicalPosition =size(theVolume, 2);
		elseif thePhysicalPosition<1,
			thePhysicalPosition =1;
		end
		Result =squeeze(theVolume(:, round(thePhysicalPosition), :));
		
	case 'transverse',
		thePhysicalPosition =(AUnderlayPosition -AConfig.Origin(3)) *AConfig.VoxelSize(3);
		thePhysicalPosition =thePhysicalPosition/AConfig.Overlay.VoxelSize(3) +AConfig.Overlay.Origin(3);
		if thePhysicalPosition>size(theVolume, 3),
			thePhysicalPosition =size(theVolume, 3);
		elseif thePhysicalPosition<1,
			thePhysicalPosition =1;
		end
		Result =squeeze(theVolume(:, :, round(thePhysicalPosition)));
	otherwise
	end
	Result =Result';	
	
function Result =Pos_Underlay2Overlay(AConfig, AUnderlayPosition)
% AUnderlayPosition is a 1by3 vector, result is the same
	Result =(AUnderlayPosition -AConfig.Origin) .*AConfig.VoxelSize;
	Result =Result./AConfig.Overlay.VoxelSize +AConfig.Overlay.Origin;
	Result =round(Result);
	
function Result =SetThrdAbsValue(AConfig)	
%By default, I only set the Min absolute value to be the threshold, and renturn the Min, 20070918
	theObject =get(AConfig.hFig, 'CurrentObject');
	if strcmpi(get(theObject, 'Style'), 'edit'),
		Result =str2num(get(AConfig.hEdtThrdValue, 'String'));		
	elseif strcmpi(get(theObject, 'Style'), 'slider'),
		Result =get(AConfig.hSliderThrdValue, 'Value');
	else
		Result =-Inf;
		return;
	end	
	
	theMin =get(AConfig.hSliderThrdValue, 'Min');
	theMax =get(AConfig.hSliderThrdValue, 'Max');
	if Result<theMin,
		Result =theMin;
	elseif Result>theMax,
		Result =theMax;
	end
	set(AConfig.hSliderThrdValue, 'Value', Result);
	set(AConfig.hEdtThrdValue, 'String', num2str(Result));	
	
function Result =ThrdOverlayAbsoluteValueAbove(AOverlayImg, AAbsoluteValueMin)
%Threshold for Absolute value above the Min
	Result =AOverlayImg;	
	tmp = abs(AOverlayImg)>=abs(AAbsoluteValueMin);	
	Result(~tmp)=0;
	
function Result =ThrdOverlayAbsoluteValueBelow(AOverlayImg, AAbsoluteValueMax)
%Threshold for Absolute value above the Min
	Result =AOverlayImg;	
	tmp = abs(AOverlayImg)<=abs(AAbsoluteValueMax);	
	Result(~tmp)=0;
function Result =ThrdOverlayValueAbove(AOverlayImg, AValueMin)
%Threshold for Absolute value above the Min
	Result =AOverlayImg;	
	tmp = (AOverlayImg)>=(AValueMin);	
	Result(~tmp)=0;
	
function Result =ThrdOverlayValueBelow(AOverlayImg, AValueMax)
%Threshold for Absolute value above the Min
	Result =AOverlayImg;	
	tmp = (AOverlayImg)<=(AValueMax);	
	Result(~tmp)=0;	
	
function Result =ThrdOverlayValueIn(AOverlayImg, AValueSeries)
%Threshold for a seiry of values
	Result =AOverlayImg;
	tmp =false(size(AOverlayImg));
	for x=1:length(AValueSeries),
		tmp = tmp | ((AOverlayImg)==(AValueSeries(x)) );
	end	
	Result(~tmp)=0;	
	
	
	
	
function Result =ThrdOverlayCluster(AConfig, AVolume)	
%Threshold for Cluster Size or calculated cluster size from cluster-Raidus %This function must be called after thresholding the Value already!		
	%"AConfig.Overlay.VolumeThrd" must be thresholded before this function is called!
	Result =AVolume;
	%Raidus has Priority
	if AConfig.Overlay.ClusterRadiusThrd~=0, %Raidus(mm) 
		%Calcute the cluster size according to the Raidus(mm) 
		AConfig.Overlay.Header.Origin=AConfig.Overlay.Origin; %%Yan 080610
        maskROI =rest_SphereROI( 'BallDefinition2Mask' , sprintf('ROI Center=(0, 0, 0); Radius=%g mm.', AConfig.Overlay.ClusterRadiusThrd), size(AConfig.Overlay.Volume), AConfig.Overlay.VoxelSize, AConfig.Overlay.Header);  %%Yan 080610
		AConfig.Overlay.ClusterSizeThrd =length(find(maskROI));
		AConfig.Overlay.ClusterRadiusThrd =0;
	end
	if AConfig.Overlay.ClusterSizeThrd==0, return; end
	[theObjMask, theObjNum]=bwlabeln(Result);	
	for x=1:theObjNum,
		theCurrentCluster = theObjMask==x;
		if length(find(theCurrentCluster))<AConfig.Overlay.ClusterSizeThrd,
			Result(~logical(theCurrentCluster))=0;			
		end
	end	
	
	
function Result =ThresholdOverlayVolume(AConfig)
	AConfig.Overlay.VolumeThrd =AConfig.Overlay.Volume;
	%First, thresholding by a range set by Min,Max
	if ~isinf(AConfig.Overlay.ValueThrdMin),
		AConfig.Overlay.VolumeThrd =ThrdOverlayValueAbove(AConfig.Overlay.VolumeThrd, AConfig.Overlay.ValueThrdMin);		
	end
	if ~isinf(AConfig.Overlay.ValueThrdMax),
		AConfig.Overlay.VolumeThrd =ThrdOverlayValueBelow(AConfig.Overlay.VolumeThrd, AConfig.Overlay.ValueThrdMax);		
	end
	
	%Absolute value thresholding without priority!
	%Threshold the Overlay	by the Value or Range or Series
	if AConfig.Overlay.ValueThrdAbsolute>0,
		AConfig.Overlay.VolumeThrd =ThrdOverlayAbsoluteValueAbove(AConfig.Overlay.VolumeThrd, AConfig.Overlay.ValueThrdAbsolute);	
	end
		
	if ~isnan(AConfig.Overlay.ValueThrdSeries), 
		AConfig.Overlay.VolumeThrd =ThrdOverlayValueIn(AConfig.Overlay.VolumeThrd, AConfig.Overlay.ValueThrdSeries);
	end	
	AConfig.Overlay.VolumeThrd =ThrdOverlayCluster(AConfig, AConfig.Overlay.VolumeThrd);	
    Result =AConfig;
	
function Result =ScaleOverlay2TrueColor(AConfig, AOverlayImg, AColorMap)
	[pathstr, name, ext, versn] = fileparts(AConfig.Overlay.Filename);
	if strcmpi(name,'aal') ||  strcmpi(name,'brodmann'),
		Result =ScaleTemplate2TrueColor(AConfig, AOverlayImg);
	else
		Result =Overlay2TrueColor(AOverlayImg, AColorMap);
	end
	
function Result =Overlay2TrueColor(AOverlayImg, AColorMap)	
	Result =AOverlayImg;
	nColorLen =size(AColorMap, 1);
	%Attention:
	%Keep zero as zero always! 20070915
	
	%Mapping the Negative values	
	ResultNegative =Result;
	ResultNegative(Result>0) =0;
	
	theNonZeroPos =find(ResultNegative~=0);
	theMax =max(ResultNegative(theNonZeroPos));
	theMin =min(ResultNegative(theNonZeroPos));	
	if theMax>theMin,
		ResultNegative(theNonZeroPos) = (ResultNegative(theNonZeroPos)-theMin)/(theMax - theMin) *(nColorLen/2-1) +1;	%Add one to make sure theMin be mapped not zero(i.e. to 1) and could be mapped to the first element in colormap 
		ResultNegative =overlay_ind2rgb(floor(ResultNegative), AColorMap(1:nColorLen/2, :));
	else
		if theMax~=0,
			ResultNegative(theNonZeroPos) =1;
			ResultNegative =overlay_ind2rgb(floor(ResultNegative), AColorMap(1, :));
		else
			ResultNegative =zeros([size(Result), 3]);
		end
	end
	
	%Mapping the Positive values	
	ResultPositive =Result;
	ResultPositive(Result<0) =0;
	
	theNonZeroPos =find(ResultPositive~=0);
	theMax =max(ResultPositive(theNonZeroPos));
	theMin =min(ResultPositive(theNonZeroPos));	
	if theMax>theMin,		
		ResultPositive(theNonZeroPos) = (ResultPositive(theNonZeroPos)-theMin)/(theMax - theMin) *(nColorLen/2-1) +1;
		ResultPositive =overlay_ind2rgb(ceil(ResultPositive), AColorMap(nColorLen/2+1:end, :));
	else
		if theMax~=0,
			ResultPositive(theNonZeroPos) =1;
			ResultPositive =overlay_ind2rgb(floor(ResultPositive), AColorMap(end, :));
		else
			ResultPositive =zeros([size(Result), 3]);
		end		 
	end
	
	Result =ResultNegative +ResultPositive;
	
function Result =ScaleTemplate2TrueColor(AConfig, AOverlayImg)	
%Such as AAL, BRODMANN ...	
	Result =AOverlayImg;
	[pathstr, name, ext, versn] = fileparts(AConfig.Overlay.Filename);
	if strcmpi(name, 'aal'),		
		AColorMap =nic_rest_ReadLutColorScheme(fullfile(nic_rest_misc( 'WhereIsREST'),'Template', 'aal.lut'));		 
		theBlackPos=sum(AColorMap, 2)==0;
		AColorMap(theBlackPos, :) =1; %Black to White for I use black always as the background
		Result =overlay_ind2rgb(1+floor(Result), AColorMap);%Overpass the first color which may be backgound color
	elseif strcmpi(name, 'brodmann'),		
		AColorMap =nic_rest_ReadLutColorScheme(fullfile(nic_rest_misc( 'WhereIsREST'),'Template', 'brodmann.lut'));		 
		theBlackPos=sum(AColorMap, 2)==0;
		AColorMap(theBlackPos, :) =1; %Black to White for I use black always as the background
		Result =overlay_ind2rgb(1+floor(Result), AColorMap);%Overpass the first color which may be backgound color	
	end
	
	
function Result =AddOverlay(AType, AConfig, ATrueColorUnderlay)	
	switch lower(AType)
	case 'sagittal',
		AUnderlayPosition =AConfig.LastPosition(1);
	case 'coronal',		
		AUnderlayPosition =AConfig.LastPosition(2);
	case 'transverse',
		AUnderlayPosition =AConfig.LastPosition(3);
	otherwise
	end
	
	Result =ATrueColorUnderlay;
	if isempty(AConfig.Overlay.Filename),		
		return;
	else	%Add Overlay Image			
		theOverlay =GetOverlayImg(AType, AConfig, AUnderlayPosition);
		
		%Resize image to the same size with the Anatomical image
		if license('test','image_toolbox')==1,
			theOverlay =imresize(theOverlay, [size(ATrueColorUnderlay, 1), size(ATrueColorUnderlay, 2)]);
		else,
			error('You must install image_toolbox first!');
		end
		
		nonZeroPos = theOverlay~=0;
		theOverlay =ScaleOverlay2TrueColor(AConfig, theOverlay, AConfig.Overlay.Colormap);
		%Add r g b colors with mask
		Result =AddRGBInMask(theOverlay, ATrueColorUnderlay, nonZeroPos, AConfig.Overlay.Opacity);
		%Result =theOverlay *AConfig.Overlay.Opacity + ATrueColorUnderlay*(1-AConfig.Overlay.Opacity);
	end

function Result =AddOverlaySeries(AConfig, ATrueColorUnderlay)
	%Get the Magnified Brain Size
	%Make sure there will be no any fractional value   if GetMagnifyCoefficient(AConfig)<1
	theSize= floor(GetMagnifyCoefficient(AConfig) * size(AConfig.Volume));
	nDim1=theSize(1); nDim2=theSize(2); nDim3=theSize(3);
	
	Result =ATrueColorUnderlay;	
	if isempty(AConfig.Overlay.Filename),
		return;
	else	%Add Overlay Image
		for theRow=AConfig.Montage.Down:-1:1,
			for theCol=1:AConfig.Montage.Across,
				%Retrieve the underlay
				switch lower(AConfig.ViewMode)
				case 'sagittal',
					theUnderlay =Result((theRow-1)*nDim3 +(1:nDim3), (theCol-1)*nDim2+(1:nDim2), :);
				case 'coronal',		
					theUnderlay =Result((theRow-1)*nDim3 +(1:nDim3), (theCol-1)*nDim1+(1:nDim1), :);
				case 'transverse',
					theUnderlay =Result((theRow-1)*nDim2 +(1:nDim2), (theCol-1)*nDim1+(1:nDim1), :);
				otherwise
				end
				%Get the overlay
				theIndex = AConfig.ViewSeries((theRow-1)*AConfig.Montage.Across +theCol);
				theOverlay =GetOverlayImg(AConfig.ViewMode, AConfig, theIndex);
								
				if license('test','image_toolbox')==1,
					theOverlay =imresize(theOverlay, [size(theUnderlay, 1), size(theUnderlay, 2)]);
				else
					error('You must install image_toolbox first!');
				end
				
				nonZeroPos = theOverlay~=0;
				theOverlay =ScaleOverlay2TrueColor(AConfig, theOverlay, AConfig.Overlay.Colormap);
				%Add r g b colors with mask
				theUnderlay =AddRGBInMask(theOverlay, theUnderlay, nonZeroPos, AConfig.Overlay.Opacity);
				%theUnderlay(theIndex) =theOverlay(theIndex) *AConfig.Overlay.Opacity + theUnderlay(theIndex)*(1-AConfig.Overlay.Opacity);
				
				%Save underlay to big series' map
				switch lower(AConfig.ViewMode)
				case 'sagittal',
					Result((theRow-1)*nDim3 +(1:nDim3), (theCol-1)*nDim2+(1:nDim2), :) =theUnderlay;
				case 'coronal',		
					Result((theRow-1)*nDim3 +(1:nDim3), (theCol-1)*nDim1+(1:nDim1), :) =theUnderlay;
				case 'transverse',
					Result((theRow-1)*nDim2 +(1:nDim2), (theCol-1)*nDim1+(1:nDim1), :) =theUnderlay;
				otherwise
				end
			end %end for-loop theCol
		end	%end for-loop theRow	
	end	%end if
	
function Result =LoadOverlay(AConfig, AFilename)
	Result =AConfig;
	try
		[theVolume,theVoxelSize, Header] =nic_rest_readfile(AFilename); %%Yan 080610
        if(isfield(AConfig,'convertToZ') && AConfig.convertToZ)
            theVolume=myZscore(theVolume);
        end
        if(isfield(AConfig,'returnValue'))
            theVolume=ChangeValue(theVolume,AConfig.returnValue);
        end
        theOrigin=Header.Origin; %%Yan 080610
		Result =AddRecentOverlay(AConfig, AFilename);
	catch
		if ~(exist(AFilename, 'file')==2) ...			
			&& ( ~all(isspace(AFilename)) && ~isempty(isspace(AFilename))),
			warning(sprintf('Please check whether Img/Hdr file "%s" exist!', AConfig.Filename));
			warndlg(sprintf('Please check whether Img/Hdr file "%s" exist!', AConfig.Filename));
		end
		
		theVolume	 =zeros(61, 73, 61); theVolume(33,33,33)=0.1;
		theVoxelSize=[3 3 3];
		theOrigin	 =[31 43 25];
	end
	Result.Overlay.Filename =AFilename;
	Result.Overlay.Volume =theVolume;
	Result.Overlay.VolumeThrd =theVolume;%Volume Thresholded as cache
	Result.Overlay.VoxelSize =reshape(theVoxelSize, [1 3]);
	Result.Overlay.Origin =reshape(theOrigin, [1 3]);
    Result.Overlay.Header=Header; %%Yan 080610
	if any(Result.Overlay.Origin==[0 0 0]),
		%Auto-Revise the Origin to the half of the size of the brain
		theMsg =sprintf('Illegal origin: (%s)\n\nI presume the origin is (%s)',num2str(Result.Overlay.Origin), num2str(round(size(Result.Overlay.Volume)/2)));
		warning(theMsg);
		warndlg(theMsg);		
		Result.Overlay.Origin =round(size(Result.Overlay.Volume)/2);
	end
	
	%Calcute the min and max both in positive & negative field
	tmpVolume =theVolume(find(theVolume));
	theMinNegative = min(tmpVolume(tmpVolume<0));
	theMaxNegative = max(tmpVolume(tmpVolume<0));
	theMinPositive = min(tmpVolume(tmpVolume>0));
	theMaxPositive = max(tmpVolume(tmpVolume>0));
	clear tmpVolume;	
	if isempty(theMinNegative), theMinNegative =0; end	%Just For always zero map
	if isempty(theMaxNegative), theMaxNegative =0; end  %Just For always zero map
	if isempty(theMinPositive), theMinPositive =0; end	%Just For always zero map
	if isempty(theMaxPositive), theMaxPositive =0; end  %Just For always zero map
	
	theAbsMax =max(abs([theMinNegative, theMaxPositive]));
	theAbsMin =min(abs([theMaxNegative, theMinPositive]));
	% theAbsVolume =abs(theVolume);
	% theAbsMax =max(theAbsVolume(find(theAbsVolume)));
	% theAbsMin =min(theAbsVolume(find(theAbsVolume)));
	% clear theAbsVolume;
	if theAbsMax<=theAbsMin, theAbsMax =theAbsMin+1; end
	set(AConfig.hSliderThrdValue, 'Max',theAbsMax,'Min',theAbsMin, 'Value',theAbsMin, 'SliderStep',[0.01, 0.05]);
	
	
	Result.Overlay.MinNegative =theMinNegative;%-10
	Result.Overlay.MaxNegative =theMaxNegative;%-1
	Result.Overlay.MinPositive =theMinPositive;			%1
	Result.Overlay.MaxPositive =theMaxPositive;			%10
	Result.Overlay.AbsMin =theAbsMin;
	Result.Overlay.AbsMax =theAbsMax;
		
	Result.Overlay.ValueThrdAbsolute =theAbsMin; %Default, show all
	Result.Overlay.ValueThrdMin =theMinNegative; %Default, show all
	Result.Overlay.ValueThrdMax =theMaxPositive; %Default, show all
	Result.Overlay.ClusterThrd =0; %Default, don't confine cluster size
	Result.Overlay.ClusterRadius =0; %Default radius(mm) for Cluster size definition
	
	[pathstr, name, ext, versn] = fileparts(Result.Overlay.Filename);
	if strcmpi(name, 'aal'),		
		theInfoTxt =fullfile(nic_rest_misc( 'WhereIsREST'),'Template', 'aal.txt');
		[x,Result.Overlay.InfoAal,y] =textread(theInfoTxt,'%d %s %d');
	else
		Result.Overlay.InfoAal='None';
	end
	
	
function [rout,g,b] = overlay_ind2rgb(a,cm)
	theImage =a;
	% Make sure A is in the range from 0 to size(cm,1)
	theImage = max(0,min(theImage,size(cm,1)));
	%Exclude any zero values, following is the Revision 
	theColormap =[[-1 -1 -1]; cm];
	theImage =theImage+1;%Make any zero to one
	
	% Extract r,g,b components
	r = zeros(size(theImage)); r(:) = theColormap(theImage,1);
	g = zeros(size(theImage)); g(:) = theColormap(theImage,2);
	b = zeros(size(theImage)); b(:) = theColormap(theImage,3);

	if nargout==3,
	  rout = r;
	else
	  rout = zeros([size(r),3]);
	  rout(:,:,1) = r;
	  rout(:,:,2) = g;
	  rout(:,:,3) = b;
	end
	%Revision finally
	rout(rout==-1) =0;
	
function Result =GetDefaultColormap()
	theNegative =winter(128);
	thePositive =hot(128);
	thePositive =thePositive(128:-1:1, :);
	Result =[theNegative; thePositive];
	
function Result =AddRGBInMask(AMapO, AMapU, AMask, AOpacityX)
	if ~isequal(size(AMapO),size(AMapU)),	
		error('Non-same size are the two true-color maps');
	end	
	if AOpacityX<0 || AOpacityX>1,	
		error('Non legal AOpacity value');
	end	
	AMask = AMask~=0;
			
	rx =AMapO(:, :, 1);
	ry =AMapU(:, :, 1);
	r  =zeros(size(rx));
	r(AMask) =rx(AMask)*AOpacityX +ry(AMask)*(1-AOpacityX);
	r(~AMask)=ry(~AMask);
	
	gx =AMapO(:, :, 2);
	gy =AMapU(:, :, 2);
	g  =zeros(size(rx));
	g(AMask) =gx(AMask)*AOpacityX +gy(AMask)*(1-AOpacityX);
	g(~AMask)=gy(~AMask);
	
	bx =AMapO(:, :, 3);
	by =AMapU(:, :, 3);
	b  =zeros(size(rx));
	b(AMask) =bx(AMask)*AOpacityX +by(AMask)*(1-AOpacityX);
	b(~AMask)=by(~AMask);
	
	Result= zeros(size(AMapO));
	Result(:, :, 1)=r;
	Result(:, :, 2)=g;
	Result(:, :, 3)=b;
	
function Result =Overlay_Misc(AConfig)	
	isNeedUpdate =false;
	% if SeeOverlay(AConfig),
		switch get(AConfig.hOverlayMisc, 'Value'),
		case 1,	%Overlay Misc
			%Do nothing
		case 2, %'Set Overlay Opacity'	
			prompt ={'Overlay''s Opacity: (1=opaque, 0=transparent and restricted in [0, 1])'};
			def	={	num2str(AConfig.Overlay.Opacity) };
			answer =inputdlg(prompt, 'Overlay Opacity', 1, def);
			if numel(answer)==1,
				theVal =abs(str2num(answer{1}));
				if theVal>1, theVal=1; end
				AConfig.Overlay.Opacity = theVal;			
			end
		case 3, %Set Range of Threshold
			prompt ={'Threshold Value''s Range: Min, Max( Default=-Inf,Inf.)', sprintf('\nSet Threshold Value''s Series, such as 25,1,7,31 for only showing Brodmann''s area BA25, BA1, BA7, BA31 when overlay is BA template. This also works for AAL template. This supports MATLAB array defination syntax. NaN means not confined in any series.')};
			def	={sprintf('%d, %d',AConfig.Overlay.ValueThrdMin,AConfig.Overlay.ValueThrdMax) ,...
				  num2str(AConfig.Overlay.ValueThrdSeries)};
			answer =inputdlg(prompt, 'Set a range for thresholding', 2, def);
			if numel(answer)==2,
				theVal =(str2num(answer{1}));
				if length(theVal)==2, 
					if theVal(1)>theVal(2), theVal=theVal([2,1]); end
					
					if theVal(1)<AConfig.Overlay.MinNegative, 
						theVal(1) =AConfig.Overlay.MinNegative;
					end
					if theVal(2)>AConfig.Overlay.MaxPositive, 
						theVal(2) =AConfig.Overlay.MaxPositive;
					end
					
					AConfig.Overlay.ValueThrdMin =theVal(1);
					AConfig.Overlay.ValueThrdMax =theVal(2);
				end
				theVal =(str2num(answer{2}));
				if ~isempty(theVal), 
					AConfig.Overlay.ValueThrdSeries =theVal;
				else
					AConfig.Overlay.ValueThrdSeries =NaN;
				end
				AConfig =ThresholdOverlayVolume(AConfig);
			end
		case 4, %Set AConfig.Overlay.LabelColor
			theColor =uisetcolor;
			if numel(theColor)==1 && theColor==0,	
				%User canceled the color selection
			else
				AConfig.Overlay.LabelColor =theColor;
			end
		case 5, %Set Color map parameters			
			prompt ={sprintf('Overlay''s Color command: ( i.e. about how to generate the color map for overlay.)\n\n1. You can input 2 or 4 or 6...16 or 18 or 20... and so on. This way would generate a N-elements colorbar.\n2. "jet(64)" or other MATLAB command(such as "Winter(20)" and so on) would generate a smooth colorbar.\n3. ** means using default colormap that''s generated by command jet(64).)')};
			def	={	AConfig.Overlay.ColorbarCmd };
			answer =inputdlg(prompt, 'Set color bar definition', 1, def);
			if numel(answer)==1,				
				AConfig =DefineColorMap(AConfig, answer{1});				
			end
		case 99, %Save current map, 
			%Todo, 20070916
			[filename, pathname] = uiputfile('*.jpg','Save current view: ');
			if isequal(filename,0) | isequal(pathname,0)		   
			else
			   theFilename =fullfile(pathname,filename);
			   
			   
			   SaveCurrentView(AConfig, AFilename);
			end
		otherwise
		end
	% else
		% warndlg('Please Check on "SeeOverlay" before changing Overlay options!');
	% end%end if SeeOverlay(AConfig)
	%Reset position in Choice selection
	set(AConfig.hOverlayMisc, 'Value', 1);
	Result =AConfig;
    
function Result =Open_Template(AConfig)	
	isNeedUpdate =false;
	switch get(AConfig.hTemplate, 'Value'),
	case 1,	%Overlay Misc
		%Do nothing		
	case 2, %'Open Template AAL'
		nic_rest_misc( 'CheckTemplate');
		theNewOverlay =fullfile(nic_rest_misc( 'WhereIsREST'), 'Template', 'aal.img');
		set(AConfig.hOverlayFile, 'String', theNewOverlay);
		% nic_rest_sliceviewer('ChangeOverlay', AConfig.hFig);
		AConfig =LoadOverlay(AConfig, theNewOverlay);
		set(AConfig.hSeeOverlay, 'Value', 1);
	case 3, %'Open Template Brodmann'
		nic_rest_misc( 'CheckTemplate');
		theNewOverlay =fullfile(nic_rest_misc( 'WhereIsREST'), 'Template', 'brodmann.img');
		set(AConfig.hOverlayFile, 'String', theNewOverlay);
		% nic_rest_sliceviewer('ChangeOverlay', AConfig.hFig);			
		AConfig =LoadOverlay(AConfig, theNewOverlay);
		set(AConfig.hSeeOverlay, 'Value', 1);
	case 4, %'Open Template Ch2'
		nic_rest_misc( 'CheckTemplate');
		theNewUnderlay =fullfile(nic_rest_misc( 'WhereIsREST'), 'Template', 'ch2.img');
		set(AConfig.hUnderlayFile, 'String', theNewUnderlay);
		% nic_rest_sliceviewer('ChangeOverlay', AConfig.hFig);	
		AConfig.Filename =theNewUnderlay;
		AConfig =InitUnderlay(AConfig);			
	otherwise
	end
	set(AConfig.hTemplate, 'Value', 1);
	Result =AConfig;
	
function Result =CurrentCluster2Mask(AConfig)
%Retrieve the cluster containing current point!
	% Result =ThresholdOverlayVolume(AConfig); %ThrdOverlayValue(AConfig, AConfig.Overlay.Volume);
	Result =AConfig.Overlay.VolumeThrd;
	[theCluster, theCount] =bwlabeln(Result);
	%Get the current point's position
	thePosition =Pos_Underlay2Overlay(AConfig, AConfig.LastPosition);
	if Result(thePosition(1),thePosition(2),thePosition(3))~=0, %Current point is valid and must reside in some cluster
		[pathstr, name, ext, versn] = fileparts(AConfig.Overlay.Filename);
		if strcmpi(name, 'aal') || strcmpi(name, 'brodmann'),
			theCurrentCluster = Result==Result(thePosition(1),thePosition(2),thePosition(3));
			Result(~theCurrentCluster)=0;
			return;
		else %BwlabelN not work for AAL or Brodmann whose clusters are adjacent			
			%Get the current point's cluster's label and return the current cluster			
			theCurrentCluster = theCluster==theCluster(thePosition(1),thePosition(2),thePosition(3));
			theCluster(~theCurrentCluster)=0;
			%transform the Result to a binary mask				
			Result(~logical(theCluster))=0;
			Result =ceil(abs(Result));	%Revise for t-map just for not rounding to zero!
			return;
		end
	else
		Result =[];
	end	
	
%Todo, 20070919
function SaveCurrentView(AConfig, AFilename)
	%Hide most components and save the result 
	theObjects =allchild(AConfig.hFig);
	for x=1:length(AConfig.hFig),
		if strcmpi(get(theObjects,'Type'), 'axes'),
		end
	end
		   
	saveas(AConfig.hFig,theFilename);
	
function Result =InitRecent(AConfig)
	Result =AConfig;	 
	theRecentCfg =fullfile(nic_rest_misc( 'WhereIsREST'), 'RecentUnderlay.txt');
	if  exist(theRecentCfg, 'file')==2,
		[Result.Recent.Underlay] =textread(theRecentCfg,'%s', 'delimiter','\n');
	else
		Result.Recent.Underlay={};
	end
	theRecentCfg =fullfile(nic_rest_misc( 'WhereIsREST'), 'RecentOverlay.txt');
	if  exist(theRecentCfg, 'file')==2,
		[Result.Recent.Overlay] =textread(theRecentCfg,'%s', 'delimiter','\n');
	else
		Result.Recent.Overlay={};
	end	
	set(AConfig.hUnderlayRecent, 'String', [{'Underlay: '}; Result.Recent.Underlay], 'Value',1);
	set(AConfig.hOverlayRecent, 'String', [{'Overlay: '}; Result.Recent.Overlay], 'Value',1);
	
function Result =AddRecentUnderlay(AConfig, AFilename)
	Result =AConfig;
	
	%20071102
	%Check whether there is space in the AFilename to prevent from problem TextRead not-function when space contained !
	if any(isspace(AFilename)),	return;	end;
	
	%check whether the same menu item exist
	theIndex =strmatch(lower(AFilename), lower(Result.Recent.Underlay), 'exact');
	if ~isempty(theIndex),
		%Move the item to the first
		for x=theIndex-1:-1:1,
			Result.Recent.Underlay{x+1} =Result.Recent.Underlay{x};
		end
	else		
		%Add
		if length(Result.Recent.Underlay)<6,%few	
			Result.Recent.Underlay =[Result.Recent.Underlay; {''}];
		end
		for x=length(Result.Recent.Underlay):-1:2,
			Result.Recent.Underlay{x} =Result.Recent.Underlay{x-1};
		end
	end	
	Result.Recent.Underlay{1} =AFilename;		
	set(AConfig.hUnderlayRecent, 'String', [{'Underlay: '}; Result.Recent.Underlay], 'Value',1);	
	
function Result =AddRecentOverlay(AConfig, AFilename)
	Result =AConfig;
	%20071102
	%Check whether there is space in the AFilename to prevent from problem TextRead not-function when space contained !
	if any(isspace(AFilename)),	return;	end;
	
	
	%check whether the same menu item exist
	theIndex =strmatch(lower(AFilename), lower(Result.Recent.Overlay), 'exact' );
	if ~isempty(theIndex),
		%Move the item to the first
		for x=theIndex-1:-1:1,
			Result.Recent.Overlay{x+1} =Result.Recent.Overlay{x};
		end
	else		
		%Add
		if length(Result.Recent.Overlay)<6,%few	
			Result.Recent.Overlay =[Result.Recent.Overlay; {''}];
		end
		for x=length(Result.Recent.Overlay):-1:2,
			Result.Recent.Overlay{x} =Result.Recent.Overlay{x-1};
		end
	end		
	Result.Recent.Overlay{1} =AFilename;
	set(AConfig.hOverlayRecent, 'String', [{'Overlay: '}; Result.Recent.Overlay], 'Value',1);	
	
function SaveRecent(AConfig, AType)
%AType = RecentUnderlay.txt or RecentOverlay.txt
	theRecentCfg =fullfile(nic_rest_misc( 'WhereIsREST'), [AType, '.txt']);
	if strcmpi(AType, 'RecentUnderlay'),
		theList =AConfig.Recent.Underlay;
	elseif strcmpi(AType, 'RecentOverlay'),
		theList =AConfig.Recent.Overlay;
	end
	hFile =fopen(theRecentCfg, 'w');
	if hFile>0,					
		for x=1:length(theList),
			fprintf(hFile, '%s\r\n', theList{x});
		end		
		fclose(hFile);
	else 
		error(sprintf('Can''t write config file: %s', theRecentCfg));
	end		
	
%20070921, Colorbar definition/regeneratioin	
function Result =DefineColorMap(AConfig, AColorDefCmd)	
	Result =AConfig;
	try
		theNumberCmd =str2double(AColorDefCmd);
		if ~isnan(theNumberCmd), %2,4,6...20 and is even!
			if mod(theNumberCmd,2)==1 || theNumberCmd>20,
				errordlg(sprintf('The number must be even because there must be even numbers of colors in the colormap.\n\n And the Number must be less than 20. \n\nIllegal for your input: %d.', theNumberCmd), nic_rest_misc( 'GetRestVersion'));				
				return;
			else
				if theNumberCmd<2, theNumberCmd =2; AColorDefCmd='2'; end %for not zero encountered!
				theColormap =jet(theNumberCmd);
			end			
		else	%It is an USER DEFINED MATLAB command to generate the color map
			if strcmpi(AColorDefCmd, '**'), %Use default color map
				theColormap =jet(64);
			else	%Evaluate the user's command in MATLAB
				theColormap=eval(AColorDefCmd);
			end
		end
		%Save the color-bar's definition
		AConfig.Overlay.ColorbarCmd =AColorDefCmd;
		AConfig.Overlay.Colormap 	=theColormap;
		Result =DrawColorbar(AConfig);
	catch		
		nic_rest_misc( 'DisplayLastException');
		errordlg('Error occured! Input may be illegal!');
	end	
	
function Result =DrawColorbar(AConfig)
	Result =AConfig;
	%Set whether to show the color bar	
	[pathstr, name, ext, versn] = fileparts(AConfig.Overlay.Filename);
	if SeeOverlay(AConfig) && ~strcmpi(name,'aal') && ~strcmpi(name,'brodmann'),
		set(AConfig.hAxesColorbar, 'Visible', 'on');
		set(AConfig.hImageColorbar,'Visible', 'on');
	else
		set(AConfig.hAxesColorbar, 'Visible', 'off');
		set(AConfig.hImageColorbar,'Visible', 'off');
		%Clear old labels
		theLabels =findobj(AConfig.hAxesColorbar, 'Type', 'text');
		for theX=1:length(theLabels), delete(theLabels(theX)); end
		return;
	end
	
	
	theColorbarWidth =20;
	%Set the colorbar's position according to the figure's height
	MarginX =10; MarginY =10;
	thePos =get(AConfig.hFig, 'Position');
	if strcmpi(AConfig.ViewMode, 'Orthogonal'),
		theAxesPosTop  =get(AConfig.hAxesSagittal, 'Position');
		theAxesPosDown =get(AConfig.hAxesTransverse, 'Position');
		theLeft 	=theAxesPosTop(1) +theAxesPosTop(3) +MarginX;
		theHeight	=theAxesPosTop(4) +theAxesPosDown(4);
		theColorBarPos =[theLeft, MarginY, theColorbarWidth, theHeight];
	elseif strcmpi(AConfig.ViewMode, 'Sagittal'),
		theAxesPos  =get(AConfig.hAxesSagittal, 'Position');		
		theLeft 	=theAxesPos(1) +theAxesPos(3) +MarginX;
		theHeight	=theAxesPos(4);
		theColorBarPos =[theLeft, MarginY, theColorbarWidth, theHeight];
	elseif strcmpi(AConfig.ViewMode, 'Transverse'),
		theAxesPos  =get(AConfig.hAxesTransverse, 'Position');		
		theLeft 	=theAxesPos(1) +theAxesPos(3) +MarginX;
		theHeight	=theAxesPos(4);
		theColorBarPos =[theLeft, MarginY, theColorbarWidth, theHeight];
	elseif strcmpi(AConfig.ViewMode, 'Coronal'),
		theAxesPos  =get(AConfig.hAxesCoronal, 'Position');		
		theLeft 	=theAxesPos(1) +theAxesPos(3) +MarginX;
		theHeight	=theAxesPos(4);
		theColorBarPos =[theLeft, MarginY, theColorbarWidth, theHeight];
	end
	set(AConfig.hAxesColorbar, 'Position', theColorBarPos);
		
	
	theNumberCmd =str2double(AConfig.Overlay.ColorbarCmd);
	if ~isnan(theNumberCmd), %2,4,6...20 and is even!		
		%Draw a element-divided colorbar, each element-color is defined by the coordesponding color in jet(theNumberColorElements)
		theColormap =reshape(AConfig.Overlay.Colormap, [size(AConfig.Overlay.Colormap,1), 1, size(AConfig.Overlay.Colormap,2)]);
		theColormap =repmat(theColormap, [1 theColorbarWidth 1]);
		theColormap =imresize(theColormap, [theColorBarPos(4), theColorbarWidth]);
		theDivideLine =reshape(get(AConfig.hFig, 'Color'), [1 1 3]);
		theDivideLine =repmat(theDivideLine, [3, theColorbarWidth, 1]);
		for x=1:theNumberCmd-1,
			theGrayLinePos = floor(x*(theColorBarPos(4)/theNumberCmd) +[-1 0 1]);
			theColormap(theGrayLinePos, :, :) = theDivideLine;			
		end
	else	%Evaluate the user's command in MATLAB  and %Draw a smooth colorbar
		%Build the image to show
		theColormap =reshape(AConfig.Overlay.Colormap, [size(AConfig.Overlay.Colormap,1), 1, size(AConfig.Overlay.Colormap,2)]);
		theColormap =repmat(theColormap, [1 theColorbarWidth 1]);
	end
	
	set(AConfig.hImageColorbar, 'CData', (theColormap), 'HitTest', 'off','Visible', 'on');
	set(AConfig.hAxesColorbar,'Visible', 'on', 'XLim', [1 size(theColormap,2)], ...
		'YLim', [1 size(theColormap,1)]);
	
	
	%Clear old labels
	theLabels =findobj(AConfig.hAxesColorbar, 'Type', 'text');
	for theX=1:length(theLabels), delete(theLabels(theX)); end
	%Add new labels
	if ~isnan(theNumberCmd), %2,4,6...20 and is even!
		%Draw a element-divided colorbar, each element-color is defined by the coordesponding color in jet(theNumberColorElements)		
		%		for x=1:(theNumberCmd+1),
		%Draw negative lables
		for x=1:theNumberCmd/2,
			theGrayLinePos  = floor((x-1)*(theColorBarPos(4)/theNumberCmd));
			
			if theNumberCmd/2 >1,
				thePercentValue = AConfig.Overlay.MinNegative +(AConfig.Overlay.MaxNegative -AConfig.Overlay.MinNegative) /(theNumberCmd/2 -1)  * (x-1);
			elseif theNumberCmd/2 ==1,
				thePercentValue = AConfig.Overlay.MinNegative;
			end
			
			text( 1.5* theColorbarWidth, theGrayLinePos, sprintf('%+g',thePercentValue), 'Parent', AConfig.hAxesColorbar, 'Color', 'black', 'HitTest', 'off', 'Units', 'pixels', 'VerticalAlignment', 'bottom', 'FontName','FixedWidth', 'FontSize', 10);
		end
		%Draw positive lables
		for x=(theNumberCmd/2+1):theNumberCmd,
			theGrayLinePos  = floor((x-1+1)*(theColorBarPos(4)/theNumberCmd)) -12;
			
			if theNumberCmd/2 >1,
				thePercentValue = AConfig.Overlay.MinPositive +(AConfig.Overlay.MaxPositive -AConfig.Overlay.MinPositive) /(theNumberCmd -1 -theNumberCmd/2)  * (x-1 -theNumberCmd/2);
			elseif theNumberCmd/2 ==1,
				thePercentValue = AConfig.Overlay.MaxPositive;
			end
			
			text( 1.5* theColorbarWidth, theGrayLinePos, sprintf('%+g',thePercentValue), 'Parent', AConfig.hAxesColorbar, 'Color', 'black', 'HitTest', 'off', 'Units', 'pixels', 'VerticalAlignment', 'bottom', 'FontName','FixedWidth', 'FontSize', 10);
		end
	else		%Draw labels for smooth display
		%Draw negative lables
		text( 1.5* theColorbarWidth, 0, sprintf('%g',AConfig.Overlay.MinNegative), 'Parent', AConfig.hAxesColorbar, 'Color', 'black', 'HitTest', 'off', 'Units', 'pixels', 'VerticalAlignment', 'bottom');
		text( 1.5* theColorbarWidth, floor(theColorBarPos(4)/2)-10, sprintf('%g',AConfig.Overlay.MaxNegative), 'Parent', AConfig.hAxesColorbar, 'Color', 'black', 'HitTest', 'off', 'Units', 'pixels', 'VerticalAlignment', 'bottom');
		%Draw positive lables
		text( 1.5* theColorbarWidth, ceil(theColorBarPos(4)/2)+10, sprintf('%g',AConfig.Overlay.MinPositive), 'Parent', AConfig.hAxesColorbar, 'Color', 'black', 'HitTest', 'off', 'Units', 'pixels', 'VerticalAlignment', 'bottom');
		text( 1.5* theColorbarWidth, theColorBarPos(4), sprintf('%g',AConfig.Overlay.MaxPositive), 'Parent', AConfig.hAxesColorbar, 'Color', 'black', 'HitTest', 'off', 'Units', 'pixels', 'VerticalAlignment', 'bottom');
	end	
	
	ResizeFigure(AConfig);
	
function Result =SetColorElements(AConfig)	
%Callback by clicking the color element on the color bar
	%1. Detect which element was clicked
	%2. Change the color and save
	
	theAxes			=get(AConfig.hFig, 'CurrentObject');
	%Check legal click point in the axes
	thePoint		=get(theAxes,'CurrentPoint');
	thePoint 		=round(thePoint(1, 1:2));
    theXLim =get(theAxes, 'XLim');
    theYLim =get(theAxes, 'YLim');	
	if thePoint(1)<theXLim(1) || thePoint(1)>theXLim(2) ...
	   || thePoint(2)<theYLim(1) || thePoint(2)>theYLim(2) ,
		Result =AConfig;
		return;
	end
	
	theColorBarPos =get(AConfig.hAxesColorbar, 'Position');
	theNumberCmd =str2double(AConfig.Overlay.ColorbarCmd);
	if ~isnan(theNumberCmd), %2,4,6...20 and is even!
		% theColorbar =get(AConfig.hImageColorbar, 'CData');		
		% uisetcolor(theColorbar(thePoint(2), 1, :));
		theColorIndex =1+ floor(thePoint(2)/(theColorBarPos(4)/theNumberCmd));
		theColor =uisetcolor(AConfig.Overlay.Colormap(theColorIndex, :));
		if numel(theColor==3),%User defined a color, didn't clicked Cancel btn
			AConfig.Overlay.Colormap(theColorIndex, :) =theColor;
		end
	end
	Result =AConfig;
	return;
	
	

function ToggleInfoDisplay(AConfig);
	theTitle ='Click to Toggle Hdr info';
	theOldMsg =get(AConfig.hMsgLabel, 'String');
	if strcmpi(theTitle, theOldMsg),
		set(AConfig.hMsgLabel, 'String', 'Anything not same with theTitle');
	else
		set(AConfig.hMsgLabel, 'String', theTitle);
	end
	SetMessage(AConfig);
	ResizeFigure(AConfig);
	


		

	
function Result =OnKeyPress(AConfig)
%Processing up/down left/right J/K F1/F2... to responding previous slice or next slice
	%left=0x1C, right=0x1D, up=0x1E, down=0x1F
	%j =0x6A, k=0x6B; 
	%J=0x4A, K=0x4B
	%F1, F2 not known! MATLAB not responding!
	%disp(sprintf('%x',(get(AConfig.hFig, 'CurrentCharacter'))));
	Result =AConfig;
	theKey =get(AConfig.hFig, 'CurrentCharacter');
	if isempty(theKey), return; end
	if any(theKey==hex2dec(['1c';'1f';'6a';'4a';])),
		Result =Slice2Previous(AConfig);
	elseif any(theKey==hex2dec(['1d';'1e';'6b';'4b';])),
		Result =Slice2Next(AConfig);
	end
	
function Result =Slice2Previous(AConfig)
	Result =AConfig;
	switch lower(AConfig.LastAxes),
	case 'transverse',
		AConfig.LastPosition(1) =AConfig.LastPosition(1)-1;
		while AConfig.LastPosition(1) <1,
			AConfig.LastPosition(1) = AConfig.LastPosition(1) +size(AConfig.Volume, 1);
		end
	case 'coronal',
		AConfig.LastPosition(2) =AConfig.LastPosition(2)-1;
		while AConfig.LastPosition(2) <1,
			AConfig.LastPosition(2) = AConfig.LastPosition(2) +size(AConfig.Volume, 2);
		end
	case 'sagittal',
		AConfig.LastPosition(3) =AConfig.LastPosition(3)-1;
		while AConfig.LastPosition(3) <1,
			AConfig.LastPosition(3) = AConfig.LastPosition(3) +size(AConfig.Volume, 3);
		end
	end
	Result =AConfig;
	
function Result =Slice2Next(AConfig)
	Result =AConfig;
	switch lower(AConfig.LastAxes),
	case 'transverse',
		AConfig.LastPosition(1) =AConfig.LastPosition(1)+1;
		while AConfig.LastPosition(1) >size(AConfig.Volume, 1),
			AConfig.LastPosition(1) = AConfig.LastPosition(1) -size(AConfig.Volume, 1);
		end
	case 'coronal',
		AConfig.LastPosition(2) =AConfig.LastPosition(2)+1;
		while AConfig.LastPosition(2) >size(AConfig.Volume, 2),
			AConfig.LastPosition(2) = AConfig.LastPosition(2) -size(AConfig.Volume, 2);
		end
	case 'sagittal',
		AConfig.LastPosition(3) =AConfig.LastPosition(3)+1;
		while AConfig.LastPosition(3) >size(AConfig.Volume, 3),
			AConfig.LastPosition(3) = AConfig.LastPosition(3) -size(AConfig.Volume, 3);
		end
	end
	Result =AConfig;
	
function Result =UpdatePosition(AConfig, ACurrentPosition)
	%Set the last axes by comparing the last position's value change
	theV =sum(AConfig.LastPosition==ACurrentPosition);
	if theV==1,		
		%Clicking one image/axes
		switch find(AConfig.LastPosition==ACurrentPosition),
		case 1,
			AConfig.LastAxes ='Transverse';
		case 2,
			AConfig.LastAxes ='Coronal';
		case 3,
			AConfig.LastAxes ='Sagittal';
		end
	elseif theV==2,
		%Directly Setting the value in the edit control
		switch find(AConfig.LastPosition~=ACurrentPosition),
		case 1,
			AConfig.LastAxes ='Transverse';
		case 2,
			AConfig.LastAxes ='Coronal';
		case 3,
			AConfig.LastAxes ='Sagittal';
		end
	end
	AConfig.LastPosition =ACurrentPosition;
	Result =AConfig;
	
function ToDo	



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Add by Gwen ,20090920
% Z-score and change value of components
function data=myZscore(data)

mask_ind = (data ~= 0);
data(mask_ind) = detrend(data(mask_ind), 0);
v2 = data(mask_ind);
    
vstd = std(v2);
if vstd ~= 0
        data=data./(eps + vstd);
else
        disp('-- Not converting to z-scores as division by zero warning may occur.');
end

function theVolume=ChangeValue(theVolume,returnValue)
switch(returnValue)
    case 2,theVolume(find(theVolume<0))=0;%positive
    case 3,theVolume=abs(theVolume);%absolute
    case 4,theVolume(find(theVolume>0))=0;%negative
end

return;

%ToDo, 20070921
%1. Show/Hide information
%2. Set Min or Max for thresholding and this should has priority
%Done 20070922

