function ReturnValue=DragVect(fn,arg)

%    DragVect: Eigenvalue/EigenVector Exploration Program
%    Copyright (C) 1996  Brad North

%    This program is free software; you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation; either version 2 of the License, or
%    (at your option) any later version.

%    This program is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.

%    You should have received a copy of the GNU General Public License
%    along with this program; if not, write to the Free Software
%    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

%    Problems, Comments, and Suggestions can be sent to 
%            northbh@nextwork.rose-hulman.edu

if nargin == 0
	fn = 'init';
end;

Figure_Name='Eigenvalues and Eigenvectors';

%Activates the Matrix Rotations figure and makes sure it has
%been properly initialized

if ~strcmp(fn,'init')
	h_MainFig = gcf;

%If the current figure is not named Figure_Name then find 
%the figure that is and put its handle in h_MainFig. This will 
%be found by checking the children of root.

	if ~strcmp(get(h_MainFig,'name'),Figure_Name)
		h_figs=get(0,'children');
		h_MainFig = findobj(h_figs,'flat',...
				    'name',Figure_Name);

	%If the figure does not exist, initialize it and then
	%run the function that was originally intended

		if length(h_MainFig)==0
			DragVect('init');
			DragVect(fn);
			return;
		end;
	end;
end;
%____________________________________________________________________________

%GetPoint	Gets the pointer location from the current figure and relates it
%		to the tick marks on the axis.
%
%USEAGE		[x,y]=GetPoint(h_axis);
%		x and y are the coordinates of the pointer expressed in terms of the
%		axis corresponding to the handle h_axis.  The figure handle is extracted
%		directly from the object properties of the axis.
%
if strcmp(fn,'GetPoint');

h_data=get(h_MainFig,'user');
h_axis=h_data(1);
h_fig=get(h_axis,'Parent');
temp=get(0,'PointerLocation');
x=temp(1); y=temp(2);
temp=get(h_fig,'Position');
i=temp(1); j=temp(2);
l=temp(3); h=temp(4);
temp=get(h_axis,'Position');
a=temp(1); b=temp(2);
ln=temp(3); hn=temp(4);
vxmin=a*l+i;
vymin=b*h+j;
vxmax=l*(a+ln)+i;
vymax=h*(b+hn)+j;
xn=(x-vxmin)/(vxmax-vxmin);
yn=(y-vymin)/(vymax-vymin);
temp=get(h_axis,'XLim');
xcoord=xn*(temp(2)-temp(1))+temp(1);

if xcoord > temp(2)
	xcoord=temp(2);
end;

if xcoord < temp(1)
	xcoord=temp(1);
end

temp=get(h_axis,'Ylim');
ycoord=yn*(temp(2)-temp(1))+temp(1);

if ycoord > temp(2)
	ycoord=temp(2);
end;

if ycoord < temp(1)
	ycoord=temp(1);
end

ReturnValue=[xcoord;ycoord];
end;
%____________________________________________________________________________
%Function: BeginDrag

if strcmp(fn,'BeginDrag')

	set(h_MainFig,'WindowButtonMotionFcn','DragVect(''Drag'');',...
		      'WindowButtonUpFcn','DragVect(''EndDrag'');');

	return;
end;
%____________________________________________________________________________
%Function: Drag

if strcmp(fn,'Drag')


%Get Handles

	h_data=get(h_MainFig,'user');

	h_plot=h_data(2);
	h_plot2=h_data(3);

	a(1,1:2)=h_data([4 6]);
	a(2,1:2)=h_data([5 7]);
	
%Figure out where the mouse is

	Coord=DragVect('GetPoint');
	aCoord=a*Coord;

%Calculate arrow tips

	sine=sin(9*pi/8);
	cosine=cos(9*pi/8);

	Vect1=([cosine (-sine) Coord(1);sine cosine Coord(2);0 0 1]*[.1*Coord(1);.1*Coord(2);1]);
	Vect2=([cosine sine Coord(1);-sine cosine Coord(2);0 0 1]*[.1*Coord(1);.1*Coord(2);1]);

	AVect1=([cosine (-sine) aCoord(1);sine cosine aCoord(2);0 0 1]*[.1*aCoord(1);.1*aCoord(2);1]);
	AVect2=([cosine sine aCoord(1);-sine cosine aCoord(2);0 0 1]*[.1*aCoord(1);.1*aCoord(2);1]);

%Set Data
	set(h_plot,'xdata',[0 Coord(1) NaN Vect1(1) Coord(1) Vect2(1) ],...
		   'ydata',[0 Coord(2) NaN Vect1(2) Coord(2) Vect2(2)]);

	set(h_plot2,'xdata',[0 aCoord(1) NaN AVect1(1) aCoord(1) AVect2(1)],...
		    'ydata',[0 aCoord(2) NaN AVect1(2) aCoord(2) AVect2(2)]);

	return;
end;

%____________________________________________________________________________

%Function: EndDrag

if strcmp(fn,'EndDrag')

	set(h_MainFig,'WindowButtonMotionFcn','',...
		      'WindowButtonUpFcn','');

	return;

end;
%____________________________________________________________________________

%Function: ApplyMatrix

if strcmp(fn,'ApplyMatrix')

	h_data=get(h_MainFig,'User');
	h_matrix(1:4)=h_data(8:11);
	h_EigPlot=h_data(12);

	set(h_EigPlot,'xdata',0,...
		      'ydata',0);

	a=[eval(get(h_matrix(1),'string')) eval(get(h_matrix(3),'string'));...
	   eval(get(h_matrix(2),'string')) eval(get(h_matrix(4),'string'))];

	
	
	h_data([4 6])=a(1,1:2);
	h_data([5 7])=a(2,1:2);

	h_plot=h_data(2);

	xdata1=get(h_plot,'xdata');
	ydata1=get(h_plot,'ydata');
	
	h_plot2=h_data(3);
	
	Coord=a*[xdata1(2);ydata1(2)];
	
	
	
	sine=sin(9*pi/8);
	cosine=cos(9*pi/8);


	Vect1=([cosine (-sine);sine cosine]*[Coord(1);Coord(2)]).*.1+[Coord(1);Coord(2)];
	Vect2=([cosine sine;-sine cosine]*[Coord(1);Coord(2)]).*.1+[Coord(1);Coord(2)];

%Set Data
	set(h_plot2,'xdata',[0 Coord(1) NaN Vect1(1) Coord(1) Vect2(1) ],...
		   'ydata',[0 Coord(2) NaN Vect1(2) Coord(2) Vect2(2)]);

	drawnow;	

	set(h_MainFig,'user',h_data);
end;

%____________________________________________________________________________

%Function: GenMatrix

if strcmp(fn,'GenMatrix')

	h_data=get(h_MainFig,'UserData');

%	h_data(8)	=	h_11data;
%	h_data(9)	=	h_21data;
%	h_data(10)	=	h_12data;
%	h_data(11)	=	h_22data;

	GMatrx22(arg,h_data([8:11]));
	return;

end;
%____________________________________________________________________________

%Function: Eig

if strcmp(fn,'Eig')
	
	h_data=get(h_MainFig,'User');
	h_axis=h_data(1);
	h_EigPlot=h_data(12);
	h_Matrix=[h_data([8 10]);h_data([9 11])];
	h_EigenVals=h_data(13:14);
	h_EigenVects=h_data(15:18);

	for col=1:2
		for row=1:2
			Matrix(row,col)=str2num(get(h_Matrix(row,col),'string'));
		end;
	end;

	[EigenVects,EigenVals]=eig(Matrix);
	
	set(h_EigenVals(1),'string',num2str(EigenVals(1,1)));
	set(h_EigenVals(2),'string',num2str(EigenVals(2,2)));

	set(h_EigenVects(1),'string',num2str(EigenVects(1,1)));
	set(h_EigenVects(2),'string',num2str(EigenVects(2,1)));
	set(h_EigenVects(4),'string',num2str(EigenVects(1,2)));
	set(h_EigenVects(3),'string',num2str(EigenVects(2,2)));

	if ~max(max(imag(EigenVects)~=0)) & (EigenVects(1,1:2)~=0)
		xlim=get(h_axis,'xlim');
		y1=EigenVects(2,1)/EigenVects(1,1)*xlim;
		y2=EigenVects(2,2)/EigenVects(1,2)*xlim;
		set(h_EigPlot,'xdata',[xlim NaN xlim],...
			      'ydata',[y1 NaN y2]);

	elseif EigenVects(1,1) == 0

		xlim=get(h_axis,'xlim');
		ylim=get(h_axis,'ylim');
		y2=EigenVects(2,2)/EigenVects(1,2)*xlim;
		set(h_EigPlot,'xdata',[0 0 NaN xlim],...
			      'ydata',[ylim NaN y2]);
	
	elseif EigenVects(1,2) == 0

		xlim=get(h_axis,'xlim');
		ylim=get(h_axis,'ylim');
		y2=EigenVects(2,1)/EigenVects(1,1)*xlim;
		set(h_EigPlot,'xdata',[0 0 NaN xlim],...
			      'ydata',[ylim NaN y2]);
			
		
		
	end;

	return;

end;

%____________________________________________________________________________

if strcmp(fn,'init')

	delete(findobj('Name',Figure_Name));

	h_MainFig=figure('NumberTitle','off',...
			 'Name',Figure_Name,...
			 'MenuBar','none',...
			 'BackingStore','off');

	h_axis=axes('pos',[.1 .1 .63 .85]);

	sine=sin(9*pi/8);
	cosine=cos(9*pi/8);

	Vect1=([cosine (-sine);sine cosine]*[1;1]).*.1+[1;1];
	Vect2=([cosine sine;-sine cosine]*[1;1]).*.1+[1;1];

%Set up menus

	h_RootMatrix=uimenu(h_MainFig,...
			'label','&Matrices');

	uimenu(h_RootMatrix,...
		'label','&Rotation Matrix',...
		'CallBack','DragVect(''GenMatrix'',''Rotation'');');

	uimenu(h_RootMatrix,...
		'label','&Projection Matrix',...
		'CallBack','DragVect(''GenMatrix'',''Projection'');');


	uimenu(h_RootMatrix,...
		'label','Re&flection Matrix',...
		'CallBack','DragVect(''GenMatrix'',''Reflection'');');

	uimenu(h_RootMatrix,...
		'label','&Scalar Matrix',...
		'CallBack','DragVect(''GenMatrix'',''Scalar'');');

%Set Data

	h_plot=plot([0,1],[0,1],'linewidth',1,...
		    'Button','DragVect(''BeginDrag'');',...
		    'EraseMode','xor');

	set(h_plot,'xdata',[0 1 NaN Vect1(1) 1 Vect2(1)],...
		   'ydata',[0 1 NaN Vect1(2) 1 Vect2(2)]);

	hold on;

	h_plot2=plot([0 0],[0 0],'r','linewidth',1,...
			'EraseMode','xor');

	h_EigPlot=plot(0,0,'w:');

	set(h_axis,'xlim',[-2 2],...
		   'ylim',[-2 2]);


	uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.75 0 .249 1],...
	'back',[1 1 1],...
	'style','frame');

	uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.76 .6 .1 .07],...
	'back',[1 1 1],...
	'style','frame');

	h_11data=uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.77 .61 .08 .05],...
	'back',[1 1 1],...
	'style','edit',...
	'string','0');

	uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.76 .52 .1 .07],...
	'back',[1 1 1],...
	'style','frame');

	h_21data=uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.77 .53 .08 .05],...
	'back',[1 1 1],...
	'style','edit',...
	'string','0');

	uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.88 .6 .1 .07],...
	'back',[1 1 1],...
	'style','frame');

	h_12data=uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.89 .61 .08 .05],...
	'back',[1 1 1],...
	'style','edit',...
	'string','0');

	uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.88 .52 .1 .07],...
	'back',[1 1 1],...
	'style','frame');

	h_22data=uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.89 .53 .08 .05],...
	'back',[1 1 1],...
	'style','edit',...
	'string','0');

	uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.76 .7 .23 .05],...
	'back',[1 1 1],...
	'style','text',...
	'string','Enter Matrix A');

	uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.765 .425 .22 .07],...
	'string','Apply Matrix',...
	'CallBack','DragVect(''ApplyMatrix'')');
	
	uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.765 .35 .22 .07],...
	'string','Show Eigenvectors',...
	'CallBack','DragVect(''Eig'');');

	h_EigenVal1=uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.8 .2 .07 .07],...
	'back',[1 1 1],...
	'style','text');

	h_EigenVal2=uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.8 .07 .07 .07],...
	'back',[1 1 1],...
	'style','text');

	h_EigenVec11=uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.9 .25 .07 .07],...
	'back',[1 1 1],...
	'style','text');

	h_EigenVec12=uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.9 .18 .07 .07],...
	'back',[1 1 1],...
	'style','text');

	h_EigenVec21=uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.9 .025 .07 .07],...
	'back',[1 1 1],...
	'style','text');

	h_EigenVec22=uicontrol(h_MainFig,...
	'units','normal',...
	'pos',[.9 .1 .07 .07],...
	'back',[1 1 1],...
	'style','text');

	h_data(1)	=	h_axis;
	h_data(2)	=	h_plot;
	h_data(3)	=	h_plot2;
	h_data(4:7)	=	zeros(1,4);
	h_data(8)	=	h_11data;
	h_data(9)	=	h_21data;
	h_data(10)	=	h_12data;
	h_data(11)	=	h_22data;
	h_data(12)	=	h_EigPlot;
	h_data(13)	=	h_EigenVal1;
	h_data(14)	=	h_EigenVal2;
	h_data(15)	=	h_EigenVec11;
	h_data(16)	=	h_EigenVec12;
	h_data(17)	=	h_EigenVec21;
	h_data(18)	=	h_EigenVec22;
	set(h_MainFig,'User',h_data,...
		'tag','vla');


end;
