function err = readsb(sbfile,slfile,topblk)
%READSB translates ASCII SystemBuild files into SIMULINK.
%
%       READSB('SBFILE') translates the SystemBuild file SBFILE into 
%	SIMULINK and opens it in a SIMULINK window.  If there are more
%	than one superblocks in the file, you will be prompted to select
%	one or more superblocks to be translated. All of the
%	superblocks selected will be translated.
%
%       READSB('SBFILE','SLFILE') translates the SystemBuild file SBFILE
%       into a SIMULINK M-file SLFILE.M.
%
%       READSB('SBFILE','SLFILE','SUPERBLOCK') translates the
%       the SystemBuild subsystem SUPERBLOCK contained in SBFILE into
%	SIMULINK.  Subsystems contained in SUPERBLOCK are also translated.
%       The subsystem is saved in the file SLFILE.M.
%
%       ERR = READSB('SBFILE',...) returns a 1 if the translation
%       produces an error. A zero is returned if the translation is
%       successful.
%
%	Run LOAD SLFILE to load data if there is any data saved in the 
%	SystemBuild file and/or in the conversion.

%	Wes Wang 8/26/92 - 1/17/93
%	Copyright (c) 1990-94 by The MathWorks, Inc.
%	$Revision: 1.45 $  $Date: 1994/09/16 01:09:29 $

% This function is really lengthy; however, the data flow and functionality
% in each section are clear. The reason for not dividing this function
% into smaller functions is to avoid passing too many variables
% between functions and to avoid leaving a file open between functions.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Routine check up and make up for input variables                           %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Check if at least one parameter exists. If not, give error message.
err = 0;

sim_ver = 0;
if exist('bdclose')
    sim_ver = 1.3;
end;

% if there is no parameter input, error
if nargin <1,
  error('Usage: READSB SystemBuildFile');
end;

% if file to be saved is not specified
save_flag = 1;
if nargin <2 
  slfile = sbfile;
  save_flag = 0;
end;

% Check if slfile is empty. If it is empty, convert it from sbfile
if isempty(slfile)
  slfile = sbfile;
  save_flag = 0;
end;

% when top block is not specified
if nargin < 3
   topblk = [];
end

% make sure slfile is a row vector
[i,j]=size(slfile);
if i>j, 
  slfile = slfile'; 
end;

% take out the path indicated by '/' from SIMULINK file
ind = find(slfile == '/');
if ~isempty(ind)
  slfile = slfile(ind(length(ind))+1:length(slfile));
end;

% if it is a VMS computer, remove the header in a different way.

if findstr(lower(computer),'vms')
  ind = find(slfile == ']');
  if ~isempty(ind)
    slfile = slfile(ind(length(ind))+1:length(slfile));
  end;
end;

% add extension for slfile as *.m
ind = find(slfile == '.');

if isempty(ind)
 slstring = slfile;
 slfile = [slfile '.m'];
else
 slstring = slfile(1:min(ind)-1);
 slfile = [slstring,'.m'];
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Read SystemBuild file                                                      %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% open SB file; and search for the necessary information.
f_sb = fopen(sbfile,'r');
if f_sb < 0
  error(['Cannot Open File ''' sbfile '''. Please Check Your Filename.'])
  return;
end;
x = fread(f_sb, 20, 'char');
tmp = find(x == 77);
if isempty(tmp)
  fclose(f_sb)
  error('Your file is not a SystemBuild File')
  return;
end;
flag_bi = 0;
if tmp(1) > 1
  x = fread(f_sb, tmp(1)-1, 'char');
  flag_bi = 1;
end;

%number of variables to be read in
numz = fscanf(f_sb,'%d',1);
xn  = 0;

x = fread(f_sb, 21, 'char');

fprintf('Your SystemBuild file was saved on')
fprintf(setstr(x(4:21)'));
fprintf('\n')

if flag_bi == 1
  fclose(f_sb)
  fprintf('We are sorry for cannot transfer your binary file yet.\n');
  return;
  numz = 0;
end;

% prepare files to be saved
save sb2sltmp slstring numz xn

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Read and Save Data Variables						%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if numz > 0
  fprintf('Reading and Saving variables.')
  x = fread(f_sb, numz*20+ceil(numz/4), 'char');
  ind = find(x == 10);
  for i = length(ind):-1:1
    x(ind(i)) = [];
  end;
  for i=1:numz
    var_n = [var_n; setstr(x((i-1)*20+1:(i-1)*20+11)')];
    var_r = [var_r; str2num(setstr(x((i-1)*20+12:(i-1)*20+15))')];
    var_c = [var_c; str2num(setstr(x((i-1)*20+16:(i-1)*20+20))')];
  end;
  zzz = 'sb2sltmp';
  for i=1:numz
    fprintf('.');
    x = fread(f_sb, 40, 'char');
    x = fscanf(f_sb, '%e', var_r(i)*var_c(i));
    y = [];
    for j=1:var_c(i)
      tmp = (j-1)*var_r(i)+1:j*var_r(i);
      if length(x) >= max(tmp)
        y=[y,x(tmp)];
      end;
    end;
    x = deblank(var_n(i,:));
    appsave(zzz, x, y);
  end;
  disp([ num2str(numz) ' variables saved in the file.'])
end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%find the location of the SystemBuild mark				%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fprintf('Reading and sorting SystemBuild block data')
x = fseek(f_sb, 0, -1);
x = fread(f_sb, inf, 'char');

%bug fix. if both 10 and 13 exist, take off both.
adj_length = 0;
ind = find(x==10);
if ~isempty(ind)
    adj_length = adj_length + 1;
end;
ind = find(x==13);
if ~isempty(ind)
    adj_length = adj_length + 1;
end;
%find where the System Build begins. It always begin with "System Build 2XX"
pos = findstr(x','SYSTEM BUILD ');
if isempty(pos)
  fclose(f_sb);
  error([sbfile ' is not a SystemBuild ASCII file.']);
else
  i = fseek(f_sb, pos(1)-1, 'bof');
  ver_num = fread(f_sb, 26, 'char');
  disp(' ');
  disp(['Your file was saved under ', setstr(ver_num')]);
  pos = pos(1) + 46;
end;

%find where the position for reading
i = fseek(f_sb, pos, 'bof');

% error information if anything goes wrong
if pos == 0 | i == -1,
  fclose(f_sb);
  error([sbfile ' is not a SystemBuild ASCII file.']);
end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                      Read and Assign Variables						%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
gen_block = fscanf(f_sb,'%d',4);

if gen_block(1) <= 0 
  disp('there is no block to be converted')
else
 %read the description for every block characters + four integers
 % (+ two real if the first integer is not zero)
 for i = 1:gen_block(1),
  tmp = fread(f_sb, 38, 'char');
  ind = find(tmp == 10);
  if ~isempty(ind)
     for i_tmp=length(ind):-1:1
        tmp(ind(i_tmp)) = [];
        tmp = [tmp; 32];
     end;
  end;
  ind = find(tmp == 13);
  if ~isempty(ind)
     for i_tmp=length(ind):-1:1
        tmp(ind(i_tmp)) = [];
        tmp = [tmp; 32];
     end;
  end;
  name_st = [name_st; tmp'];
  name_in = [name_in; fscanf(f_sb,'%d',4)'];
  if name_in(i,1) ~= 0
    name_fl = [name_fl; fscanf(f_sb, '%e', 2)'];
  else
    name_fl = [name_fl; [0 0]];
  end;
 end;
 %remove the extra length
 name_st=name_st(:,1:37);

 %read the content of each block.
 for i = 1:gen_block(1),
  % read the first line block information and four integer
  blk_wt = fread(f_sb,37+adj_length,'char')';
  ind = find(blk_wt == 10);
  if ~isempty(ind)
     for i_tmp=length(ind):-1:1
        blk_wt(ind(i_tmp)) = [];
        blk_wt = [blk_wt 32];
     end;
  end;
  ind = find(blk_wt == 13);
  if ~isempty(ind)
     for i_tmp=length(ind):-1:1
        blk_wt(ind(i_tmp)) = [];
        blk_wt = [blk_wt 32];
     end;
  end;
  if max(blk_wt(1:37) ~= name_st(i,:))
    error('Something goes wrong in the file. Abort Convertion');
  end;
  tmp = fscanf(f_sb,'%d',4);
  blk_dm = [blk_dm; tmp'];
  % read string with length blk_dm(i,1)
  fseek(f_sb,1,0);
  adj = adj_length*(floor(blk_dm(i,1)/72) + 1) - 1; %includes number for carriage return
  if isempty(adj)
    adj = 0;
  end;
  if findstr(lower(computer),'vms')
    tmp = fread(f_sb, 1, 'char');
  end;
  tmp = fread(f_sb, blk_dm(i, 1)+adj, 'char');
  ind = find(tmp == 10);
  if ~isempty(ind)
     for i_tmp=length(ind):-1:1
        tmp(ind(i_tmp)) = [];
     end;
  end;
  ind = find(tmp == 13);
  if ~isempty(ind)
     for i_tmp=length(ind):-1:1
        tmp(ind(i_tmp)) = [];
     end;
  end;
  blk_dm(i,1) = length(tmp);
  blk_st = [blk_st; tmp];
  % read integer with length blk_dm(i,2)
  blk_in = [blk_in; fscanf(f_sb, '%d', blk_dm(i,2))];
  % read real with length blk_dm(i,3)
  blk_fl = [blk_fl; fscanf(f_sb, '%e', blk_dm(i,3))];
 end;
end;
fclose(f_sb);
%xn=0;
%xs='save sb2sltmp xn xs';
%eval(xs);

fprintf('.');
if gen_block(1) > 0 
 %Remove all returns in the string
 ind = find(blk_st == 10);
 for i = length(ind):-1:1
   blk_st(ind(i)) = [];
 end;
 clear x i j ind

 % in the case of the top block is not a superblock in the file
 test=1;
 for i=1:gen_block(1)
     k=strcmp(topblk,deblank(setstr(name_st(i,:))));
     if k 
       test = 0;
     end;
 end;

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %Find the structure of the superblock tree 						%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 if test
   if gen_block(1) > 10
     disp(['The sorting is slow for your system with ' num2str(gen_block(1)) ' superblocks.'])
     disp('To speed up, input top superblock name next time.')
     disp('Type Ctrl-C to abort. Please wait.');
   end;
   top_blk = zeros(gen_block(1),1);
   %top_blk(i) == 0 if block_i is an independent superblock 
   %           == 1 if block_i is a subsuperblock
   sub_blk = zeros(gen_block(1),gen_block(1));
   %top_blk(i,:) lists all blocks depending on block_i
   ini_st = 1;
   %searching for the structure
   for i=1:gen_block(1)
     fprintf('.');
     if i ~= 1
       ini_st = sum(blk_dm(1:i-1,1))+1;
     end;
     st = setstr(blk_st(ini_st:ini_st+blk_dm(i,1)-1)');
     for j = 1:gen_block(1)
       if i ~= j
         ind = [];
         ind = findstr(st, ['|' deblank(setstr(name_st(j,:))) '||']);
         if ~isempty(ind)
           top_blk(j) = 1;
           if isempty(find(sub_blk(i,:)==j))
             k = find(sub_blk(i,:) == 0);
             sub_blk(i,k(1)) = j;
           end; % if isempty
         end; % if ~isempty
       end; %if i~=j
     end; %for j = 1:gen
   end; %for i=1:gen
   fprintf('.\n');
   %list all of sub-superblocks
   ind=find(top_blk == 0);
   if isempty(top_blk)
     disp('The superblocks have called recursively, the list of all superblock follows')
     for i=1:gen_block(1)
       disp(setstr(name_st(i,:)))
     end
   else
     temp = length(ind);
       space='                                                                      ';
     if temp == 1
       disp(['There is one independant superblock tree, which is']);
     else
       disp(['There are ' num2str(temp) ' independant superblock trees, which are:']);
     end;
     for i=1:temp
       if (ind(i) < 10) & (gen_block(1) >= 10) 
         tmp = ['( ' num2str(ind(i)) ') '];
       else
         tmp = ['(' num2str(ind(i)) ') '];
       end;
       tmp = [tmp setstr(name_st(ind(i),:))];
       disp(tmp);
       if gen_block(1) <= 1
	  stack = [];
       else
          stack = [ind(i),1];
       end;
       while ~isempty(stack)
         k = length(stack);
         j = sub_blk(stack(k-1),stack(k));
         if j == 0
           if k <=2
             stack = [];
           else
             stack = stack(1:k-2);
           end;
         else
           if (j < 10) & (gen_block(1) >= 10) 
             tmp = ['( ' num2str(j) ') '];
           else
	     tmp = ['(' num2str(j) ') '];
           end;
           tmp = [tmp space(1:k) setstr(name_st(j,:))];
           disp(tmp);
           stack(k) = stack(k) + 1;
           if stack(k) > gen_block(1)
             error('readsb error, report to the mathworks.')
           end; 
           stack=[stack j 1];
         end;
       end;
     end;
   end;
   if gen_block(1) > 1
     test = 1;
   else
     test = 0;
   end;
   while test
     for i=1:gen_block(1)
       k=strcmp(topblk,deblank(setstr(name_st(i,:))));
       if k 
         test = 0;
       end;
     end;
     if test == 1
       topblk = ...
	input('Input the number or the string of your top superblock ==> ');
       if ~isstr(topblk)
         if topblk <= gen_block(1)
           topblk = deblank(setstr(name_st(topblk,:)));
         end; %if topblk
       end; %if ~isstr
     end; %if test
   end; %while
   clear ind i j k  test stack top_blk sub_blk
 end; %if test
 %end the finding structure procedure 1/8/93

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % Variable Layout                                                            %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % We have the variables:
 % gen_block :(1) number of super blks, number of row of
 %	          name_st, name_in, and name_fl
 %	      (2) number of characters, dimension of blk_st
 %	      (3) number of integers, dimension of blk_in
 %	      (4) number of real number, dimension of blk_fl
 % name_st :  gen_block(1) X 31 matrix, name(i,:) is the name
 %                of ith super block.
 % name_in :  (1) feature of super block. =0 continuous;
 %                =1 discrete; =33 state order =73 fuzzy
 %            (2) number of blocks in this superblock
 %            (3) number of inputs in this super block
 %            (4) number of outputs in this super block
 % name_fl :  real numbers of the super block. 
 %                it is zero when name_in(1)=0.
 % blk_dm :   (i,1) number of characters in this superblock
 %            (i,2) number of integer in this superblock
 %            (i,3) number of real number in this superblock
 %            (i,4) FORTRAN format of this superblock's integers
 % blk_st :   string. ith block string start from
 %               sum_{k=1}^{i-1}(blk_dm(k,1))+1
 %                   ==> sum_{k=1}^{i}(blk_dm(k,1))
 % blk_in :   integer. ith block integer start from
 %               sum_{k=1}^{i-1}(blk_dm(k,2))+1
 %                   ==> sum_{k=1}^{i}(blk_dm(k,2))
 % blk_fl :   real. ith block real start from
 %               sum_{k=1}^{i-1}(blk_dm(k,3))+1
 %                   ==> sum_{k=1}^{i}(blk_dm(k,3))
 %
 % End of reading variables from SystemBuild file

 %load data from sb2sldat
 sb2sldat
 clear face

 % Analyze the data series from the beginning of the file

 % setup flags to indicate blocks has been converted or not.
 % flag(i) == 1, ith block has not been processed yet.
 % flag(i) == 0, ith block has been done.
 flag = ones(gen_block(1),1);

 % set up flag to indicate tree structure
 % son(i) == 0, root block
 % son(i) == j, ith block is son of jth block
 % done(i) which one to be done.
 %
 son = zeros(gen_block(1),1);
 done = -ones(gen_block(1),1);

 % if topblk == [], find the order number of the root block
 % In the process, if there is more than one block sharing 
 % the same name, use the first encounted.
 % 'now' is the number of current processing block
 if ~isempty(topblk)
   now = 0; i = 1;
   xx=deblank(topblk);
   indxX = find(xx >=97 & xx <=122);
   xx(indxX) = xx(indxX) - 32;           
   while now ==0;
      tmp = deblank(setstr(name_st(i,:)));
      indxX = find((tmp >=97) & (tmp <=122));
      tmp(indxX) = tmp(indxX) - 32;
      if strcmp(xx,tmp)
	 now = i;
      else     
         i = i+1;
         if i > gen_block(1) % cannot find, then error.
            fprintf('block '); fprintf(topblk); 
	    fprintf(' is not a super block in the file\n');
            break;
         end; %if i>
      end;  %if same
   end; % while
 else %if isempty
   now = 1;
 end; %if ~isempty
 root = now;
 topblk = slstring;

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % open a new system window							%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 new_system(slstring);
 simver(1.3);
 sys = slstring;
 set_param(sys,'Location',[14,98,100,100])
 open_system(sys)
 fprintf('\nTranslating '); fprintf(sys); fprintf('\n');

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % Block Setup, Main Procedure                                                %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %beginning of one-by-one block process the conversion
 while ~isempty(topblk) %now ~= 0

  % make chain loaded with all tree pathes for all the group definition
%  chain = [];
%  i = now;
%  while i~=0 & i~= root
%    %add tree structure chain
%    chain=[deblank(setstr(name_st(i,:))) '/' chain];
%    i = son(i);
%  end; %while
  chain = deblank(topblk(1,:));
  chain = deblank(chain);
  topblk(1,:) = [];
  now = root(1);
  root(1) = [];

  %add top to the chain
%  chain = [sys '/' chain];
%  %takeout the last '/'
%  if ~isempty(chain), 
%     while (chain(length(chain)) == '/') 
%	chain=chain(1:length(chain)-1); 
%     end;
%  end;

  % the initial starting point of string, integer and real number.
  if now ==1;
     ini_st = 1; ini_in = 1; ini_fl = 1;
  else
     ini_st = sum(blk_dm(1:now-1,1)) + 1;
     ini_in = sum(blk_dm(1:now-1,2)) + 1;
     ini_fl = sum(blk_dm(1:now-1,3)) + 1;
  end;

  % pull out the sting, integer and real number to a separated vector.
  st = blk_st(ini_st:ini_st+blk_dm(now,1)-1); %string
  in = blk_in(ini_in:ini_in+blk_dm(now,2)-1); %integer
  fl = blk_fl(ini_fl:ini_fl+blk_dm(now,3)-1); %real

  relocat = fl(1:4);
  zoomx = 1200/(relocat(3)-relocat(1));
  if zoomx <.4, zoomx = .4; end;
  zoomy = 760/(relocat(4)-relocat(2));
  if zoomy <.4, zoomy = .4; end;
  if son(now) ~= 0 %if it is not the super block, open system
     set_param(chain,'Location',[14,98,100,100])
     if save_flag == 0
       open_system(chain) %for final version, this line can be deleted
     end;
     fprintf('Translating '); fprintf(chain); fprintf('\n');
  else             % I/O port have not added yet for the top block
    if in(5) > 0
      for i=1:in(5)
        add_block('built-in/Inport',[chain '/input' num2str(i)]);
        set_param([chain '/input' num2str(i)],'position',...
		[1230,1010,1250,1033],...
		'Port',num2str(i));
      end;
    end %if
    if in(6) > 0
      for i=1:in(6)
       add_block('built-in/Outport',[chain '/output' num2str(i)]);
       set_param([chain '/output' num2str(i)],'position',...
		[0,0,20,20],...
		'Port',num2str(i));
      end;
    end %if
  end;

  % analyze integer
  ind = in(18);
  
  % record of in_b
  rec_in = [];

  % find the maximum and minimum axis
  axiz = [1000 , 1000 , 0 , 0]; % the number for set I/O port location
  %locate every block's information and define blocks
  if name_in(now,2) >= 0
    count_in=0; count_ot=0;
    for i = 1:name_in(now,2)     %number of blocks
      %The location of each block
      in_b = ind+in(ind+3*i-2)+2;
      in_e = ind+in(ind+3*i+1); 
      fl_b = in(19) + in(ind+3*i-1)+1;
      fl_e = in(19) + in(ind+3*i+2);
      st_b = in(20) + in(ind+3*i)+1;
      st_e = in(20) + in(ind+3*i+3);
      if i == name_in(now,2), 
        in_e = blk_dm(now,2); 
        fl_e = blk_dm(now,3);
        st_e = blk_dm(now,1);
      end;

      %double check to see if everything is okay.
      while in(in_b) ~= 8 | ~(in(in_b+7) == 20 |in(in_b+7) ==23)
         in_b = in_b+1;
         if in_b+7 > blk_dm(now,2)
            disp('Convert goes wrong; Please check your file.');
	    disp('If this message shows again, send your file to Mathworks');
            break;
         end;
      end; %while
      rec_in = [rec_in in_b];

      %The block type is in  in_b+1 and in_b+2;
      %The I/O number is in  in_b+3 and in_b+4;
      %State number   is in  in_b+5;
      %block id number is in in_b+6
      %block input con is in in_b+18+input_number            (blk#)
      %                  and in_b+18+in(in_b+3)+input_number (out#)
      %block ori struc is in in_b+19+in(in_b+3)*2 
      %block location x_axis in_b+20+in(in_b+3)*2
      %block location y_axis abs(in(in_b+21+in(in_b+3)*2))
      %block size x_axis     in_b+22+in(in_b+3)*2
      %block size y_axis     in_b+23+in(in_b+3)*2
      
      %blocks name
      blkname = setstr(st(st_b:st_e))';
      pt = min(find(blkname == '|'));
      blkname = blkname(1:pt-1);
      % bug fix for '/' in the sequence
      pt = find(blkname == '/');
      if ~isempty(pt)
        for i = length(pt) : -1 : 1
            blkname = [blkname(1:pt(i)), '/', blkname(pt(i)+1:length(blkname))];
        end;
      end;
      % end bug fix for '.' in the sequence
      orblkname = blkname;
      hiden = 0;

      %find the numbers for function coding, position and size
      if in(in_b+1) <= 0 | in(in_b+1) > 16
        disp('Illegal Block, send your file and description of this block to MathWorks and ask for solution.');
        in(in_b+1) = 16;
        pt1 = 1;
      end;
      if in(in_b+1) ~= 6 & in(in_b+1) ~= 16
        pt1 = pointer(in(in_b+1),in(in_b+2));           %code number
      else
	pt1 = 40;
      end;

      % block name
      if isempty(blkname) 
         blkname = [deblank(block(pt1,:)) num2str(in(in_b+6))];
         hiden = 1;
         orblkname = blkname;
      end;

      %avoid repeating name
      if i>1
         for j=1:(i-1)
            if strcmp(blkname,deblank(sto_nm(j,:)))
               blkname = [blkname num2str(in(in_b+6))];
            end; %if
         end; %for
       end; %if

      % size and location
      pt2 = in_b + in(in_b+7) + in(in_b + 3) * 2;     %location and size
      posit = in(pt2:pt2+3)';
      %%  relocation points  %%
      posit(1) = ceil((posit(1) - floor(relocat(1)))*zoomx);
      posit(2) = ceil((relocat(4) - posit(2))*zoomy);
      posit(3) = ceil(posit(3)*zoomx);
      posit(4) = ceil(posit(4)*zoomy);
      if posit(3) >= 200
         posit(3) = posit(3)/2;
      end;
      if posit(4) >= 200
        posit(4) = max(posit(4)/2,min(posit(4),max(in(in_b+3),in(in_b+4))*15));
        posit(4) = max(posit(4), max(in(in_b+3),in(in_b+4))*5+10);
      end;
      %      posit(3:4) = 0.8*posit(3:4);
      %      posit = 0.75*posit;
      %      posit(2) = 200-posit(2)-posit(4);       %position for SL
      %      posit(1) = posit(1)+20;
      posit = abs(posit);
      if in(in_b+1) == 2 & (in(in_b+2) == 2 | in(in_b+2) == 5)
         posit(3) = ceil(posit(3)/3);
         hiden = 1;
         posit(1) = posit(1) + posit(3);
      end;
      posit = posit - rem(posit,5);
      for kk=1:4
        if posit(kk) < 10
           posit(kk) = 10; 
        end;
      end;
      rotat = rem(floor(in(pt2-1)/2),2); %check the second last bit of the numb
      % > str_ori(in(in_b+1),in(in_b+2));

      %decide whether a super block for mux is necessary.
      %logic for adding input/output
      lgc_in = (in(in_b+3)>1) & (pt1~=2);	%logic for input needs mux
      lgc_in = lgc_in & (pt1 ~= 6) & (pt1 ~= 8) & (pt1 ~= 10) & (pt1 ~=9);
				%product and sum do not need a mux
      %lgc_in = lgc_in & (pt1 ~= 65) ;
      %the following always need a mux.
      lgc_in = lgc_in | (pt1==33) | (pt1==34) | (pt1==35) | (pt1==28) | (pt1==29) | (pt1==62);
      lgc_ot = (in(in_b+4) > 1) & (pt1~=2);   %logic for output needs Demux
      lgc_ot = lgc_ot | (pt1>=54 & pt1<=57);
      %resize block size

      mask = 0;
      if lgc_in & lgc_ot
            mask = 1;
      elseif lgc_in
	    mask = 2;
      elseif lgc_ot
            mask = 3;
      end;

      % add block
      fprintf('.')
      [temp, note_name] = sb2slmng(pt1,[chain '/' deblank(blkname)],posit,in(in_b:in_e),...
    	fl(fl_b:fl_e),[name_in(now,1),mask, rotat],...
    	name_fl(now,:),st(st_b:st_e));
%      drawnow;
      err = err + temp;
      posit(4) = max(posit(4), 5*max(in(in_b+3),in(in_b+4)));
      posit(3:4)=posit(1:2)+posit(3:4);

      if isempty(note_name)
          set_param([chain '/' deblank(blkname)], 'position', posit);

          if hiden
             set_param([chain '/' deblank(blkname)], 'hide name',0);
          else
             set_param([chain '/' deblank(blkname)], 'move name',0);
          end
      else
          set_param(note_name, 'position', floor([(posit(1)+posit(3))/2, (posit(2)+posit(4))/2, (posit(1)+posit(3))/2, (posit(2)+posit(4))/2]));
      end;

      %save positions for line layout
      blklocs(i,1:2) = posit(1:2); 
      blklocs(i,3:4) = posit(3:4);
      orienta(i) = rotat*2;

      % relocate all input blocks
      dsl = in(in_b+7) - 2;
      if in(in_b+3) > 0
        for ji = 1:in(in_b+3)
          innumb = in(in_b + dsl + ji + in(in_b+3));
          if in(in_b + dsl + ji) == 0 & innumb > 0
            xx = get_param([chain '/input' num2str(innumb)], 'position');
            yy = get_param([chain '/' deblank(blkname)], 'inport');
            yy = yy(ji,:);
            yy(1) = max(0, yy(1)+(30+rem(ji,5)*25)*(2*rotat-1));
            yy(2) = max(0,yy(2) - 10);
            if ~isempty(xx)  & ~isempty(yy)
             if xx(1) > yy(1)
              set_param([chain '/input' num2str(innumb)], 'position',[yy yy+20],...
		'hide name',0);
              in_ori(innumb) = 0;
              if rotat
                set_param([chain '/input' num2str(innumb)],'orientation',2);
                in_ori(innumb) = 2;
              end;
             end;
            end;
          end;
        end;
      end;
      %save the name for link usage
      sto_nm(i,:)=[blkname blankt(length(blkname)+1:40)];

      % find the minimum and maximum axis for the blocks
      axiz(1) = min(axiz(1),posit(1));
      axiz(2) = min(axiz(2),posit(2));
      axiz(3) = max(axiz(3),posit(1)+posit(3));
      axiz(4) = max(axiz(4),posit(2)+posit(4));

      % for a super block, mark the location of the block
      if pt1 == 2, 
         test = 0; 
         ij = 1;
         while ~test & (ij <= gen_block(1))
           tmp = deblank(setstr(name_st(ij,:)));
	   % case insensitive setup
           indxX = find(tmp >=97 & tmp <= 122);
           tmp(indxX) = tmp(indxX) - 32;
           tmp2 = deblank(orblkname);
           indxX = find(tmp2 >=97 & tmp2 <=122);
           tmp2(indxX) = tmp2(indxX) - 32;           
	   % end of case insensitive setup
	   if strcmp(tmp2,tmp)
              test = 1;
              son(ij) = now;
              done(ij) = now;
	      name_st(ij,1:length(orblkname)) = abs(orblkname);
              root = [root; ij];
              [tmp, tmp2] = size(topblk);
              tmp3 = [ chain '/' deblank(blkname) ];
              if tmp > 0
                 if length(tmp3) > tmp2
                    topblk(1,length(tmp3)) = ' ';   
                 elseif length(tmp3) < tmp2
                    tmp3(tmp2) = ' ';
                 end;
              end;
              topblk = [topblk; tmp3];
           else %if
             ij = ij+1;
             if ij > gen_block(1)
               fprintf('A nonexistent block ''')
               fprintf('Superblock '); fprintf([chain '/' blkname]);
	       fprintf(''' has been used.\n');
             end;
           end; %if
         end; %while
      end; %if pt1
    end; %for i = 1:name_in(now,2)

    % input/output blocks
    fprintf('.')
    axiz(1) = max(axiz(1)-60,5);
    axiz(2) = max(axiz(2),5);
    axiz(3) = axiz(3)+40;
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Relocate output blocks                    %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    in_b = 3;
    dsl = in(9) - in_b;
    innumb = in(in_b + 3);
    if innumb > 0
      for j = 1:innumb
        blkname_in = ['output' num2str(j) '/1'];
        if in(in_b + dsl + j) >0
           ij = in(in_b + dsl + j);
           ijk = in(in_b+dsl+j+innumb);
           blkname_ot = [deblank(sto_nm(ij,:)) '/' num2str(ijk)];
           z = get_param([chain '/' deblank(sto_nm(ij,:))],'outport');
           blank_num = 1;
           while (isempty(z) & (blank_num < 20))
               z = get_param([chain,'/',deblank(sto_nm(ij,:)),setstr(ones(1,blank_num)*32)],'outport')
               blank_num = blank_num + 1;
           end;
           z = z(ijk,:);
           orien(1) = orienta(ij);
           if orien(1) == 0
              z(1) = z(1) + (30 + rem(ijk,5)*25);
           else
              z(1) = max(0,z(1) - (30 + rem(ijk,5)*25));
           end;
           z(2) = z(2) - 10;
           set_param([chain '/output' num2str(j)],'position',[z z+20],...
  		  'hide name',0,...
		  'Port',num2str(j));
           orien(2) = 0;
           if orien(1) ~= 0
              set_param([chain '/output' num2str(j)],'orientation',2);
              orien(2) = 2;
           end;
         end;
      end;
    end;
    drawnow
    bloc = get_param(chain,'blocks');
    [n_bl,m_bl]=size(bloc);
    clear bllc new_bllc
    for i = 1:n_bl
       bllc(i,:) = get_param([chain '/' deblank(bloc(i,:))],'position');
    end;
    shif_x = 20 - min(bllc(:,1));
    shif_y = 20 - min(bllc(:,2));
    new_bllc(:,1) = bllc(:,1) + shif_x;
    new_bllc(:,3) = bllc(:,3) + shif_x;
    new_bllc(:,2) = bllc(:,2) + shif_y;
    new_bllc(:,4) = bllc(:,4) + shif_y;
    blklocs(:,[1,3]) = blklocs(:,[1,3]) + shif_x;
    blklocs(:,[2,4]) = blklocs(:,[2,4]) + shif_y;

    for i=1:n_bl
      set_param([chain '/' deblank(bloc(i,:))],'position',new_bllc(i,:));
    end;
    x_ma = max(new_bllc(:,3));
    y_ma = max(new_bllc(:,4));
    loca(1) = 14;
    loca(2) = 98;
    loca(3) = loca(1) + x_ma + 20;
    loca(4) = loca(2) + y_ma + 20;
    set_param(chain,'Location',loca);
    drawnow;

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Link all of the blocks                                                     %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % connect all lines
    for i = 0:name_in(now,2)     %number of blocks
%      in_b = ind+in(ind+3*i-2)+2; dsl = 18;
      if i == 0 %starting from superblock
         in_b = 3;
%         dsl = 20;
         dsl = in(9) - in_b;
%         if blk_dm(now,4) >4 & in(11) > 13
%           dsl = 11 + in(11);
%         end;
         orien = [0 0];
      else
         in_b = rec_in(i);
         dsl = in(in_b+7)-2;      %it was assigned to be dsl=18;
         orien = [0 orienta(i)];
      end;
      innumb = in(in_b+3);
      if innumb >0  %when the input number greater than 0 make connection
         for j = 1:innumb
          if i>0 
             blkname_in = [deblank(sto_nm(i,:)) '/' num2str(j)];
           else
             blkname_in = ['output' num2str(j) '/1'];
           end;
           if in(in_b + dsl + j) >0
             ij = in(in_b + dsl + j);
             ijk = in(in_b+dsl+j+innumb);
             blkname_ot = [deblank(sto_nm(ij,:)) '/' num2str(ijk)];
             orien(1) = orienta(ij);
             if i <= 0
               z = get_param([chain '/' deblank(sto_nm(ij,:))],'outport');
               blank_num = 1;
               while (isempty(z) & (blank_num < 20))
                   z = get_param([chain,'/',deblank(sto_nm(ij,:)),setstr(ones(1,blank_num)*32)],'outport')
                   blank_num = blank_num + 1;
               end;
               z = z(ijk,:);
               if orien(1) == 0
                 z(1) = z(1) + (30 + rem(ijk,5)*25);
               else
                 z(1) = max(0,z(1) - (30 + rem(ijk,5)*25));
               end;
               z(2) = z(2) - 10;
%               set_param([chain '/output' num2str(j)],'position',[z z+20],...
%  		  'hide name',0,...
%		  'Port',num2str(j));
               orien(2) = 0;
               if orien(1) ~= 0
%                 set_param([chain '/output' num2str(j)],'orientation',2);
                 orien(2) = 2;
               end;
             end;
           else
             blkname_ot = ['input' num2str(in(in_b + dsl + j + innumb)) '/1'];
             if (length(in_ori) >=in(in_b+dsl+j+innumb)) &...
		 (in(in_b+dsl+j+innumb) >0)
               orien(1) = in_ori(in(in_b+dsl+j+innumb));
             end;
             orien(1) = orien(2);
           end;
           if in(in_b + dsl + j + innumb)
            if sim_ver <= 1.2
             xx=autoline(chain, blkname_ot, blkname_in, blklocs, orien);
            else
             add_line(chain, blkname_ot, blkname_in);
            end;
           end;
         end; % for j=
      	end; % if innumb
      if save_flag == 0
         drawnow
      end;
    end;  % for i = 1:name_in(now,2)     %number of blocks
  end %if name_in(i,2) =>0
  tmp=max(blklocs);
  if length(tmp) < 4
    tmp = blklocs;
  end;
%  bdresize(1,chain);
%  set_param(chain,'Location',[20,20,tmp(3)+110,tmp(4)+50]);
  %close_system(chain);
  blklocs = [];
    fprintf('.\n')
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % make marks and choose the next block                                       %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  if (son(now) ~= 0) & (save_flag == 0)
       close_system(chain); 
  end;
  done(now) = 0;
  % end of 'now'th process, find out if there is any block to be done.
  % if it is, process the son process
  ind = find(done >0);
  if isempty(ind)
     now = 0;
  else
     now = ind(1);
  end;
 end;
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % Save the generated file                                                    %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 load sb2sltmp
%remove the following line for 3.5 runable
% if xn > 0 | numz > 0
%   set_param(sys,'Start callback',['load ' slstring]);
%   set_param(sys,'Load callback',['load ' slstring]);
% end;
 if save_flag
   close_system(sys,1);
 end

 %warning, the following super block has not been used in the conversion.
 ind = find( done < 0 );
 if ~isempty(ind)
   disp('Warning: the following blocks are in the file but never used');
   for i = 1: length(ind)
      disp(setstr(name_st(ind(i),:)));
   end;
 end;

 %give out the final instruction for executable file
 if err > 0
   fprintf('\nConversion finished, ')
   fprintf(num2str(err))
   fprintf(' blocks have left unconverted.\n')
 else
   fprintf('\nConversion has been succesful.\n')
 end;
 if nargin > 1
   fprintf('\nYour SIMULINK file is in '); fprintf(slfile);
   fprintf('.\nRun '''); fprintf(slstring); 
   fprintf(''' to open '''); fprintf(slstring); 
   fprintf(''' SIMULINK window.\n');
 end;
end;

%clean house
if xn>0 | numz>0
  appsave('sb2sltmp','err',err);
  clear
  load sb2sltmp
  %clear the space
%  xs = [xs(1:5) slstring xs(14:length(xs)) zzz(13:length(zzz))];
%  eval(xs);
  fprintf('\nData file ''')
  fprintf(slstring);
  fprintf('.mat'' has been created.\n')
  fprintf('''load ')
  fprintf(slstring);
  fprintf(''' before simulation\n')
  eval(['save ' slstring])
end;

clear
if findstr(lower(computer),'vms')
  eval('!del sb2sltmp.mat;*');
  if exist('apptmp.mat')
    eval('!del apptmp.mat;*');
  end;
elseif findstr(lower(computer),'pc')
  eval('!del sb2sltmp.mat');
  if exist('apptmp.mat')
    eval('!del apptmp.mat');
  end;
else
  eval('!rm sb2sltmp.mat');
end;
