function  [sys, x0, str, ts]  = sfuny(t,x,u,flag,ax,color, dt)
%SFUNY S-function scope using graph window.
%
%	This M-file is designed to be used in a SIMULINK S-function block.
%	It stores the last input point using discrete states
%	and then plots this against time.
%
%	S-function Syntax (see SFUNC):
%	      [SYS, X0]  = SFUNY(T,X,U,FLAG,LTYPE)
%	where:
%	      AX - graph axis
%             LTYPE - line type (e.g. 'r','r-.','x') (See PLOT)
%
%	Set this M-file up in an S-function block.
%	Set the function parameter up as a four element vector
%	which defines the axis of the graph. The line type must be in
%	quotes.
%
%	See also PLOT, SFUNYST, SFUNXY, LORENZ2.

%	Copyright (c) 1990-94 by The MathWorks, Inc.
%	Andrew Grace 1-27-92.
%	Revised Wes Wang 4-28-93, 8-17-93, 12-15-93

if (flag == 2) | (flag == 9)
	% initialize the figure
	if x(3) <= 0
		h_fig = x(3);
		% Initialize graph
		[sl_name,block] = get_param;
		[n_b, m_b]= size(block);
		if n_b < 1
			error('Cannot delete block while simulating')
		elseif n_b > 1
			error('Something wrong in get_param, You don''t have the current SIMULINK')
		end;

		% findout if the graphics window exist
		ind = find(sl_name == setstr(10));
		dash = '_';
		sl_name(ind)=dash(ones(size(ind)));

		% in the case of the figure exists
		Figures = get(0,'Chil');
		new_figure = 1;
		i = 1;
		while ((new_figure) & (i <= length(Figures)))
		  if strcmp(get(Figures(i), 'Type'), 'figure')
		    if strcmp(get(Figures(i), 'Name'), sl_name)
		      h_fig = Figures(i);
		      handles = get(h_fig,'UserData');
		      new_figure = 0;
		      h_axis = handles(1);
		      set(0,'CurrentF',h_fig);
		      set(h_axis,'Xlim', ax(1:2), 'Ylim', ax(3:4)); %,'XTickLabels',[],'YTickLabels',[]);
		      set(h_axis,'UserData',[]);
		      test = (length(u) == length(get(h_axis,'Child')));
		      h_plot = handles(2:length(u)+1);
		      if test
			test = min(sort(h_plot') == sort(get(h_axis,'Child')));
		      end;
		      if test
			coll = color;
			for k=1:length(u);
			  [col, coll]=strtok(coll,'/');
			  if length(col) <= 1
			    col = 'w-';
			  end;
			  set(h_plot(k),'XData',0,'YData',0,'Erasemode','none','Color',col(1),'LineStyle',col(2:length(col)));
			end;
		      else
			% input number has been changed
			delete(get(h_axis,'Child'));
			h_plot = [];
			set(h_axis,'NextPlot','add','UserData',[]);
			set(h_fig,'NextPlot','add');
			coll = color;
			for k=1:length(u);
			  [col, coll]=strtok(coll,'/');
			  if length(col) <= 1
			    col = 'w-';
			  end;
			  h_plot(k) =  plot(0,0,col,'Erasemode','none','Color',col(1),'LineStyle',col(2:length(col)));
			end;
			set(h_fig, 'UserData',[h_axis, h_plot, ax(2:4), abs(color)]);
			set(h_axis,'NextPlot','new');
			set(h_fig,'NextPlot','new');
		      end;
		    end;
		  end;
		  i = i + 1;
		end;

		% the figure does not exist, and this is an end of simulation (flag 9) call
		% exit early
		if new_figure & (flag == 9)
		  sys = [];
		  return;
		end;

		% the figure does not exist, create a new figure
		if new_figure
			h_fig = figure('Unit','pixel','Pos',[100 100 400 300], ...
				'Name',sl_name,'Number','off');
			set(0, 'CurrentF', h_fig);
			h_axis = axes('Xlim', ax(1:2), 'Ylim', ax(3:4),'Box','on');
			set(h_axis,'NextPlot','add');
			coll = color;
			for i=1:length(u)
				[col, coll] = strtok(coll, '/');
				if isempty(col)
					col = 'w-';
				end;
				h_plot(i) =  plot(0,0,col,'Erasemode','none');
			end;
			set(h_axis,'NextPlot','new');
			xl = get(h_axis,'XLabel');
			set(xl,'String','Time (second)');
		end;
		set(h_axis,'XGrid','on','YGrid','on');
		set(h_fig,'Color',get(h_fig,'Color'));
		set(h_fig,'NextPlot','new');
		x = [Inf; -Inf; h_fig]; 	% Infinity flags to indicate first point
		set(h_fig, 'UserData',[h_axis, h_plot, ax(2:4), abs(color)]);
	end;

	handles = get(x(3),'UserData');
	len_u = length(u);
	len_c = length(color);
	len_h = length(handles);
	axis_color_reset = 0;

	if (t > x(2)) | ((len_u + len_c) ~= (len_h - 4))
		axis_color_reset = 1;
	elseif max([ax(2:4) abs(color)] ~= handles(len_u+2:len_h))
		axis_color_reset = 1;
	end;

	if axis_color_reset
		if (t > x(2)) | max((ax(2:4) ~= handles(len_u+2:len_u+4)))
			if flag == 9
				sys = [];
				return
			end

			% Keep track of X-axis limit in third discrete state
			if max((ax(2:4) ~= handles(len_u+2:len_u+4))) | (x(1) == inf)
				x(2) = t;
			end;

			sample_time = get_param(gcb, 'sample time');

			sys = [0; x(2)+ax(2); x(3); any(sample_time)];

			% New axis is the original plus all the elapsed time:
			newax = [ax(1)+x(2),ax(2)+x(2),ax(3),ax(4)];
			if newax(4) <= newax(3)
				newax(4) = newax(3) + eps;
			end;
			if newax(2) <= newax(1)
				newax(2) = newax(1) + eps;
			end;
			set(handles(1), 'Xlim', newax(1:2), 'Ylim', newax(3:4));
			set(x(3),'Color',get(x(3),'Color'));

			handles(len_u+2:len_u+4) = ax(2:4);
		end;

		test = 0;
		if (len_c ~= (len_h - len_u - 4))
			test = 1;
		elseif (1-min(abs(color) == handles(len_u+5:len_h)))
			test = 1;
		end;

		if test
			coll = color;
			for i=1:length(u)
				[col, coll] = strtok(coll, '/');

				if isempty(col)
					col = 'w-';
				elseif length(col) <2
					col(2) = '-';
				end;
				set(handles(i+1), 'Color',col(1),'LineStyle',col(2:length(col)));
			end;
			sys = x;
		end;
		set(x(3),'UserData',[handles(1:length(u)+4), abs(color)]);
	else
		sys = x;
	end
	time_t = get(handles(1),'UserData');

	if (isempty(time_t))
		storage = u;
		past_t = t;
		time_t = t;
		y = ones(1,len_u);
		y(:) = u;
		x(1) = 1;
		sys(1) = 1;
		sys(4) = any(get_param(gcb, 'sample time'));
		discrete = sys(4);	
	else
		discrete = sys(4);	
		reset = 0;

		past_t = time_t(x(1));
		y = [];
		for i=1:len_u
			y = [y, get(handles(i+1),'UserData')];
		end;
		len_t = length(time_t);

		if len_t == x(1)
			if ((t-min(time_t)) <= (ax(2)-ax(1))) & (len_t < 1024)
				% grow buffers
				if (discrete)
					time_t = [time_t; t; t];
					y = [y; y(x(1),:); u'];
					sys(1) = x(1) + 2;
				else
					time_t = [time_t; t];
					y = [y; u'];
					sys(1) = x(1) + 1;
				end
			else
				% restart at beginning of buffer
				sys(1) = 1;
				reset = 1;

				time_t(1) = time_t(x(1));
				y(1, :) = y(x(1), :);

				% write over existing buffer entries
				sys(1) = sys(1) + 1;
				if (discrete)
					time_t(sys(1):sys(1)+1) = [t; t];
					y(sys(1):sys(1)+1, :) = [y(x(1),:); u'];
					sys(1) = sys(1) + 1;
				else
					time_t(sys(1)) = t;
					y(sys(1), :) = u';
				end;

			end;
		else
			% write over existing buffer entries
			sys(1) = x(1) + 1;
			if (discrete)
				time_t(sys(1):sys(1)+1) = [t; t];
				y(sys(1):sys(1)+1, :) = [y(x(1),:); u'];
				sys(1) = sys(1) + 1;
			else
				time_t(sys(1)) = t;
				y(sys(1), :) = u';
			end;
		end;
	end;
	for i=1:len_u
		if (discrete)
			set(handles(i+1),'XData',[time_t(x(1)), t,         t     ], ...
					 'YData',[y(x(1),i),    y(x(1),i), u(i)]);
		else
			set(handles(i+1),'XData',[time_t(x(1)), t     ], ...
					 'YData',[y(x(1),i),    u(i)]);
		end
		set(handles(i+1), 'UserData', y(:,i));
	end;

	drawnow

	set(handles(1), 'UserData', time_t);
	if flag == 9
		%draw the plot;
%		set(handles(1),'Xlim',[min(time_t), max(time_t)]);
		len_t = length(time_t);
		if (sys(1) < len_t)
			time_t = [time_t(sys(1)+1:len_t);time_t(1:x(1))];
			y      = [y(sys(1)+1:len_t,:); y(1:x(1),:)];
		end;
		for i=1:len_u
			set(handles(i+1),'XData',time_t, 'YData',y(:,i));
		end;
        tmp_x = get(handles(1),'Xlim');
        tmp_y = get(handles(1),'Ylim');
        set(handles(1),'Xlim',tmp_x/2);
        set(handles(1),'Xlim',tmp_x,'Ylim',tmp_y);
		sys=[];
	end;

elseif flag  == 0, 	% Initialization

	% Return system sizes

	sys(1) = 0;		% 0 continuous states
	sys(2) = 4;		% 4 discrete states
	sys(3) = 0;		% 0 outputs
	sys(4) = -1;		% autowidth number of inputs
	sys(5) = 0;		% 0 roots
	sys(6) = 0;		% no direct feedthrough
	sys(7) = 1;		% 1 sample time

	x0 = [0; -Inf; 0; 0]; 	% Infinity flags to indicate first point

	if (nargin > 6)
		ts = [dt, 0];
	else
		ts = [-1, 0];
	end

elseif (flag == 4) & (nargin > 6)
	if (dt > 0)
		sys = t + dt;
	else
		sys = [];
	end;
else
	% Other flag options not defined.
	sys = [];
end
