### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###
##                    308-522 -- Modelling and Simulation
##                                  Fall 2002
##                             --- ASSIGNMENT 1 ---
##
## EXPORT_Mfile.py
##
## last modified: 09/27/02
### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###

import Traversal  # Traversal of the model
import tkFileDialog  # For brwoser dialog

def exportMfile(parentApp, model):

  # List of all integrator blocks:
  intBlocks = filter( lambda x : x.block_type.getValue()[1] == 6,             \
        model.listNodes["Block"] )

  # Build "lookUp" dictionnary:
  Traversal.lookUp = {}
  c = 1
  for b in intBlocks:
    name = b.block_name.getValue()
    if name == "":
      raise SyntaxError, "missing integrator name"
    Traversal.lookUp[ name ] = c
    c += 1

  if c == 1:
    raise NotImplementedError, "model is not an ODE"

  # "outStr" is used to store the representation of the ordinary differential
  # equations themselves. "tmpStr" is used to store the algebraic equations.
  outStr = ""
  tmpStr = "x0 = ["

  # Loop over all Integrator blocks:
  for iBlock in intBlocks:
    icPort = iBlock.block_IC_port[0]
    inPort = filter( lambda x : x != icPort, iBlock.in_connections_)[0]
    var = iBlock.block_name.getValue()  # integrator's name
    index = Traversal.lookUp[var]

    # LEFT-HAND SIDE OF THE ODE:
    outStr += "xdot(" + str(index) + ") = "
    # RIGHT-HAND SIDE OF THE ODE
    outStr += Traversal.traverse(inPort, 1) + ";\n"

    # INITIAL CONDITION
    tmpStr += Traversal.traverse(icPort, 1) + "; "


  # Get a filename:
  filename = tkFileDialog.asksaveasfilename()
  if not filename:
    return

  # Make sure the name is valid:
  assert (filename[-2:] == ".m"), "invalid name"

  # Build function name (must be the same as the file name):
  fncname = filename[:-2]
  i = len(fncname) - 1
  while 1:
    if fncname[i] == "/":
      break
    else:
      i -= 1
  fncname = fncname[i+1:]

  # Build whole string:
  # NOTE that the name of the function must be that of the file
  outStr = "function xdot = " + fncname + "(t, x)\n" +                        \
           "xdot = zeros(" + str( len( Traversal.lookUp ) ) +                 \
           ", 1);\n" + outStr
  outStr += "\n" + tmpStr[:-2] +  "];\n"

  #  Print "outStr" in file:
  fd = open(filename, 'w')
  fd.write(outStr)
  fd.close()





