(*
  File: Statespace.sml

  Structure for the state and transition monitoring operations.
*)

structure Statespace =
(* structure Statespace :> Statespace = *)
struct

  (* Transitions counter *)
  val transitions = ref 0;

  (* Transition file *)
  val transStream = ref TextIO.stdOut

  (* gcla - remove later *)
  val pwbsolveStream = ref TextIO.stdOut

  (* Initialization routine *)
  fun initialize () = 
     (transitions := 0;
      case (!Options.solver) of
	 Options.BCG =>
	    pwbsolveStream := TextIO.openOut (Files.jobName() ^ Options.ext())
       | _ =>
	    transStream := TextIO.openOut (Files.jobName() ^ Options.ext())
	    )

  (* Finalization routine *)

  fun finalize () =
     case (!Options.solver) of
	Options.BCG => (TextIO.closeOut (!pwbsolveStream))
      | _ => TextIO.closeOut (!transStream)
	   
     
  fun formatTransition (n, (alpha,rate), m) =
    let
      val ns = Int.toString n 
      val ms = Int.toString m

      val (LPAR, RPAR, EQ, SEMI, COMBEGIN, COMEND) =
	  case !Options.solver of
	      Options.Matlab => ("(", ")", "=", ";", " % ", "\n")
	    | Options.Maple  => ("[", "]", ":=", ":", " # ", "\n")
	    | Options.BCG  => ("[", "]", ":=", ":", " # ", "\n")
	    | Options.Mathematica  => ("[[", "]]", "=", "", " (* ", " *)\n")
		  
      val Qentry   = "Q"^LPAR^ns^","^ms^RPAR
      val Qassign  = Qentry ^ EQ ^ Qentry^"+"^rate^SEMI^"\n"
      val Qtarget  = "Q"^LPAR^ns^","^ns^RPAR
      val Qcorrect = Qtarget ^ EQ ^ Qtarget^"-"^rate^SEMI
      val Comment  = COMBEGIN^ns^"--"^ alpha ^","^rate^"->"^ms^COMEND
    in
       (Qassign ^ Qcorrect ^ Comment,
	(* gcla - remove later *)
	"\t"^ns^"\t"^ms^"\t"^rate^"\n")
    end

  fun addTransition (P, NONE, Q) = 
      Error.warning ("phantom component " ^ Prettyprinter.print
		     Prettyprinter.uncompressed P)
    | addTransition (P, SOME ((alpha, rate), n), Q) = 
      (transitions := !transitions + 1;
       let val f = formatTransition
	  (Table.getCode P, 
	   (HashTable.unhash alpha,
	    (Expressions.toString (Expressions.eval rate))),
	   Table.getCode Q)
       in
	  case (!Options.solver) of
	     Options.BCG =>
		TextIO.output (!pwbsolveStream, (#2 f))
	   | _ =>
		TextIO.output (!transStream, (#1 f))
       end)


end;
