#! /bin/sh

     ###################################### 
     ##### Model Transformation Tools #####
     ######################################

# Bourne shell script: rbg2abg_m
#
###############################################################
## Version control history
###############################################################
## $Id$
## $Log$
## Revision 1.20  2004/02/19 12:05:49  gawthrop
## Fix prob. when no bonds
##
## Revision 1.19  2002/04/28 18:55:03  geraint
## Fixed [ 549658 ] awk should be gawk.
## Replaced calls to awk with call to gawk.
##
## Revision 1.18  2001/03/30 15:13:58  gawthrop
## Rationalised simulation modes to each return mtt_data
##
## Revision 1.17  2000/12/05 12:04:03  peterg
## Changed function name to name()
##
## Revision 1.16  2000/12/05 09:04:08  peterg
## Fixed function () compatibility problem.
##
## Revision 1.15  2000/11/03 14:53:33  peterg
## Copy NOTPAR as well
##
## Revision 1.14  2000/09/14 08:41:35  peterg
## Strip off the additional direction info from rbonds
##
## Revision 1.13  2000/03/16 12:53:26  peterg
## Added copy of the %VAR declarations
## Put in the endfunction statement
##
## Revision 1.12  1998/07/28 19:07:48  peterg
## Writes out N_ports as well as n_ports
##
## Revision 1.11  1998/07/25 16:14:44  peterg
## *** empty log message ***
##
## Revision 1.10  1998/07/08 15:34:56  peterg
## Sorted out error exit status
##
## Revision 1.9  1998/07/08 08:24:26  peterg
## Added -I option -- if set prints out the indormation messages
##
## Revision 1.8  1998/02/19 08:57:02  peterg
## Fixed mtt-info bug -- confused filename with number
##
## Revision 1.7  1997/08/05 08:38:23  peterg
## Added n-ports to the argument list in the comment.
##
## Revision 1.6  1996/12/04 21:52:01  peterg
## Uses filenum and fopen instead of filename.
##
## Revision 1.5  1996/08/25 09:20:32  peter
## General error handling.
##
## Revision 1.4  1996/08/24 17:57:41  peter
## Removed `touch mtt_info.txt'
##
## Revision 1.3  1996/08/24 14:58:56  peter
## Fixed missprint - mtt_err --> mtt_error
##
## Revision 1.2  1996/08/24 14:33:07  peter
## Error handling included.
##
## Revision 1.1  1996/08/05 12:22:16  peter
## Initial revision
##
###############################################################

# Raw bond graph to structured acausal bond graph: mfile format
# The structured BG is described by four matrices:
#   junctions: describes the junctions -
#     Column 1   Index of component (see components)
#     Column 2.. Indices of bonds on junction (see jbonds)
#                  rows may be padded with zeros
#
#   jbonds:    describes the true bonds -
#     Column 1     Index of component (see components)
#     Column 2     Direction
#                    1 away from junction
#                   -1 towards junction
#     Column 3     Causality 
#                     1 stroke at arrow end
#                    -1 stroke at other end
#                     0 no stroke (ie acausal)
#     Columns 4:5  x,y coordinates of non-arrow end (in Fig)
#     Columns 6:7  x,y coordinates of arrow end (in Fig)
#
#   mbonds:    describes the modulation bonds -
#     Column 1     Index of component at non-arrow end
#     Column 2     Index of component at arrow end
#     Columns 4:5  x,y coordinates of non-arrow end (in Fig)
#     Columns 6:7  x,y coordinates of arrow end (in Fig)
#
#   components: describes the comonents -
#     Column 1     Type of component
#                    0  0-junction
#                    1  1-junction
#                    2  R component
#                    3  C component
#                    4  I component
#                    11 TF component
#                    12 GY component
#                    13 A  component
#     Column 2     Flag for explicit junction
#                    4  Explicit component (4 means text type)
#                    0  Implicit component
#     Column 3-14    fig file information (see fig documentation)
#
# P.J.Gawthrop May 1996
# Copyright (c) P.J.Gawthrop, 1996.

while [ -n "`echo $1 | grep '^-'`" ]; do
  case $1 in
	-I )
                info=info;;
	-nounits )
                units=no;;
	*)
		echo "$1 is an invalid argument - ignoring" ;;
  esac
  shift
done

## Set up some vars
sys=$1
lbl_file=${sys}_lbl.txt
abg_file=${sys}_abg.m

# Remove the old log file
rm -f rbg2abg_m.log
rm -f ${abg_file}

#Inform user
echo Creating ${abg_file}

# Use matrix manipulation to accomplish the transformation
$MATRIX > rbg2abg_m.log  2>mtt_error.txt << EOF
  name = '$1'
  infofile = fopen('mtt_info.txt', 'wt');
  errorfile = fopen('mtt_error.txt', 'wt');

  %Convert from the fig version of the bonds to a structured version
  [rbonds,rstrokes,rcomponents,port_coord,port_name,port_list] = $1_rbg
  [n_ports, junk] = size(port_list)
 
  N_ports = 0;
  for i=1:n_ports		# Count the true number of ports.
    [subport,n_sub] = split_port(port_list(i,:), ',');
    N_ports = N_ports+n_sub;
  end;
 
  [n_bonds,m_bonds] = size(rbonds);
  if n_bonds>0
    rbonds = rbonds(:,1:6);  # Strip  the directional information
  endif

  [bonds,components,n_vector_bonds] = rbg2abg(name,rbonds,rstrokes,rcomponents,port_coord,port_name,\
                               infofile,errorfile);

  %Write the function m-file for the causal bond graph
  write_abg(name,bonds,components,n_vector_bonds);    
EOF

## Sets the units for the abg file
test_units()
{ 
  grep '^[\s]*[#|%]UNITS' < ${lbl_file} >/dev/null
  if [ $? = "0" ]; then 
    grep '^[\s]*[#|%]UNITS' < ${lbl_file} |\
    gawk '{
      printf("mtt_units.sh %s %s %s %s %s\n", sys, $2, $3, $4, $5)
    }' sys=${sys}  | sh | grep ERROR
    if [ $? = "0" ]; then
      echo "    " *MTT_ERRROR: domains and units are not OK - exiting
      exit 1  
    else
      echo "    " domains and units are OK 
    fi
  else
    echo "  no domains or units declared"
  fi
} 

check_ports_exist()
{
 declared_ports=`grep '^[\s]*[#|%]UNITS' < ${lbl_file} | gawk '{print $2}'`
  for declared_port in $declared_ports; do
    grep "${sys}\.ports\.${declared_port}\.type" ${abg_file} >/dev/null
    if [ $? = "1" ]; then
      echo "*MTT_ERRROR: Units declared for non-existent port ${declared_port}"
      exit 1
    fi
  done
}

set_units()
{ 
  grep '^[\s]*[#|%]UNITS' < ${lbl_file} |\
  gawk '{
    printf("  %s.ports.%s.domain = \"%s\";\n", sys, $2, $3);
    printf("  %s.ports.%s.units.effort = \"%s\";\n", sys, $2, $4);
    printf("  %s.ports.%s.units.flow = \"%s\";\n", sys, $2, $5);
  }' sys=${sys}
} 

if [ -z "$units" ]; then
  echo Checking port domains and units
  check_ports_exist;
  test_units;
  echo "## Port domain and units" >> ${abg_file}
  set_units >> ${abg_file}
fi

# Append any VAR declarations
if [ -f "$1_lbl.txt" ]; then
  echo "## Explicit variable declarations" >> ${abg_file}
  grep '^[\s]*[%|#][V|P]AR' $1_lbl.txt | tr '%' '#' >> ${abg_file}    
  grep '^[\s]*[%|#]NOT[V|P]AR' $1_lbl.txt | tr '%' '#' >> ${abg_file}    
fi

## Close off the function
echo "endfunction" >> ${abg_file}

## Errors and info
if [ "$info" = "info" ]; then
  cat mtt_info.txt    
fi

if mtt_error mtt_error.txt
then
    exit 0
else
    exit 1
fi
