#This perl script will read a matlab script file and generate a header file.

use Cwd;
$dir = getcwd;

$object = $ARGV[0];

if ($object =~ m"\.m") {
    $object =~ s"\.m"";
}

$mfile = $object.".m";
$hfile = "Mli".ucfirst($object)."Mfile.h"; 
$mlhfile = "ml".ucfirst($object).".h";
$mlcfile = "ml".ucfirst($object).".cpp";
$tsdfile = "Mli".ucfirst($object)."Mfile.tsd";
$htmfile = "Mli".ucfirst($object)."Mfile.html";

$dir = $dir."/".$mfile;

$flag = 0;
$dtype = 0;
$usg = "";
$count = 0;
@include = ();
if (open(MFH,$mfile)) {
    @mat = <MFH>;
    for ($i=0; $i<@mat; $i++) {
	if (($flag == 0) && ($mat[$i] =~ m"function")) {
            $func = $mat[$i];
            $usg = $mat[$i];
            if ($usg =~ m"\;") {
                $usg =~ s"\;""g;
            }
            $flag = 1;
	}
	if (($mat[$i] =~ m"%") && (lc($mat[$i]) =~ m"tempus:") && ($mat[$i] !~ m"\#")) {
	    $dtype = $mat[$i];
            $datatype = $dtype;
	}
        if (($mat[$i] =~ m"%") && (lc($mat[$i]) =~ m"tempus:") && ($mat[$i] =~ m"\#")) {
	    $include[$count] = $mat[$i];
            $count = $count+1;
	}
    }
    close(MFH);
}

# here usg is the function definition
if ($usg eq "") { 
  print "Mlimtoh Error: missing function line in .m file\n";
  die;
}

#parsing variable names
$usg =~ s"function""g;
$usg =~ s/\s+//g;

# get the list of outputs
if (($usg =~ m"\[") && ($usg =~ m"\]")) {
    @tmp = split(m"=",$usg);
    $/ = "\]";
    chomp($tmp[0]);
    $/ = "\[";
    $tmp1 = reverse($tmp[0]);
    chomp($tmp1);
    $tmp[0] = reverse($tmp1);
    @oname = split(m",",$tmp[0]);
    $onamelen = @oname;
}
else {
    @oname = "";
    $onamelen = 0;
    $tmp[0] = "";
    $tmp[1] = $usg;
}

# get the list of inputs
$/ = ")";
chomp($tmp[1]);
$len1 = length($object)+1;
$len2 = length($tmp[1])-len1;
$tmp[1] = substr($tmp[1],$len1,$len2);

if ($tmp[1] eq "") {
    @iname = "";
    $inamelen = 0;
}
else {
    @iname = split(m",",$tmp[1]);
    $inamelen = @iname;
}

#parsing data types
$timestep = -1;
#check if the timestep is defined
if ($dtype =~ m"@") {
   @tmp = split(m"@",$dtype);
   $dtype = $tmp[0];
   $timestep = $tmp[1];
   $timestep =~ s/\s+//g;
   if ($timestep eq "") {
      $timestep = -1;
   }
}

@tmp = split(m":",$dtype);
$dtype = $tmp[1];
if ($dtype eq "") {
#    $dtype =~ s/\s+//g;
#If there is no data type information found, use flaot as the default type.
    print "MLIMTOH Warning: a comment providing tempus-to-matlab type translation was \n";
    print "not found in the input m-file. Type \"float\" will be used for all inputs and \n";
    print "outputs.\n";
    $dtype = "\[";
    for ($i=0; $i<$onamelen-1; $i++) {
	$dtype = $dtype."float,";
    }
    if ($onamelen >= 1) {
	$dtype = $dtype."float\]=".$object."(";
    }
    else {
	$dtype = $dtype."\]=".$object."(";
    }
    for ($i=0; $i<$inamelen-1; $i++) {
	$dtype = $dtype."float,";
    }
    if ($inamelen >= 1) {
	$dtype = $dtype."float)";
    }
    else {
        $dtype = $dtype.")";
    }
}

# output types
@tmp = split(m"=",$dtype);
$tmp[0] =~ s/\s+//g;
$/ = "\[";
$tmp1 = reverse($tmp[0]);
chomp($tmp1);
$tmp[0] = reverse($tmp1);
$/ = "\]";
chomp($tmp[0]);
if ($tmp[0] eq "") {
    @otype = "";
}    
else {
    @otype = split(m",",$tmp[0]);
}

# input types
$tmp[1] =~ s/^\s+//;  
$tmp[1] =~ s/\s+$//;  
$/ = ")";
chomp($tmp[1]);
$len1 = length($object)+1;
$len2 = length($tmp[1])-len1;
$tmp[1] = substr($tmp[1],$len1,$len2);

if ($tmp[1] eq "") {
    @itype = "";
}
else {
    @itype = split(m",",$tmp[1]);
}

#checking the number of state variables
$istate = 0;
for ($i=0; $i<@itype; $i++) {
    $itype[$i] =~ s/^\s+//;
    @tmp1 = split(m" ",$itype[$i]);
    if (lc($tmp1[0]) =~ m"state") {
        $istatvar[$istate] = $iname[$i];
        $istate++;
    }
}
$ostate = 0;
for ($i=0; $i<@otype; $i++) {
    $otype[$i] =~ s/^\s+//;
    @tmp1 = split(m" ",$otype[$i]);
    if (lc($tmp1[0]) =~ m"state") {
        $ostatvar[$ostate] = $oname[$i];
        $ostate++;
    }
}
if ($ostate != $istate) {
    print "Check the number of state variables on both sides\n";
    die;
}
for ($i=0; $i<@ostatvar; $i++) {
    $compflag = 0;
    for ($j=0; $j<@istatvar; $j++) {
        if ($ostatvar[$i] eq $istatvar[$j]) {
            $compflag = 1;
        }
    }
    if ($compflag != 1) {
        print "The names of statevariable are not agree\n";
        die;
    }
}

#starting generate code
#Mli(object)Mfile.h
open(HFH, ">$hfile");

print HFH "//\n";
print HFH "// ".$hfile." Generated on ".localtime()."\n"; 
print HFH "// (c) Copyright 2000, MZA Associates Corporation\n";
print HFH "//\n\n";

print HFH "#ifndef "."MLI".uc($object)."MFILE_CLASS_H\n";
print HFH "#define "."MLI".uc($object)."MFILE_CLASS_H\n\n";

print HFH "#define "."MLI".uc($object)."MFIL"."INPUTS ".$inamelen."\n";
print HFH "#define "."MLI".uc($object)."MFIL"."OUTPUTS ".$onamelen."\n\n";

print HFH "#ifdef TEMPUS_IN_MEX\n";
print HFH "   #define "."MLI".uc($object)."MFILE"."MEX\n";
print HFH "#else\n";
print HFH "   //#define "."MLI".uc($object)."MFILE"."COMPILED\n";
print HFH "   #define "."MLI".uc($object)."MFILE"."ENGINE\n";
print HFH "#endif\n\n";

print HFH "#define "."MLI".uc($object)."MFILE"."OUTPUTDRIVEN\n";
print HFH "//#define "."MLI".uc($object)."MFILE"."INPUTDRIVEN\n\n";

if ($timestep < 0) {
    print HFH "//#define "."MLI".uc($object)."MFILE"."TIMESTEP "."timestep\n\n";
}
else {
    print HFH "#define "."MLI".uc($object)."MFILE"."TIMESTEP "."$timestep\n\n";
}

print HFH "#ifdef "."MLI".uc($object)."MFILE"."COMPILED"."\n";
print HFH "#include "."\"".$mlhfile."\"\n";
print HFH "#endif\n\n";

print HFH "#include "."\"tempus.h\"\n";
print HFH "#ifndef "."MLI".uc($object)."MFILE"."MEX\n";
print HFH "#include "."\"mli.h\"\n";
print HFH "#else\n";
print HFH "#include \"mlimex.h\"\n";
print HFH "#endif\n\n";

for ($i=0; $i<@include; $i++) {
    $tmp = $include[$i];
    $tmp =~ s"Tempus""g;
    $tmp =~ s"tempus""g;
    $tmp =~ s":""g;
    $tmp =~ s"%""g;
    $tmp =~ s/\s+//g;
    $tmp =~ s"include"include "g;
    print HFH "$tmp\n";
}
print HFH "\n";

print HFH "//This header file is generated based on the following information\n";
print HFH "//$func";
print HFH "//$datatype";
for ($i=0; $i<@include; $i++) {
   print HFH "//$include[$i]";
}
print HFH "// $dir \n\n";
 
print HFH "class "."Mli".ucfirst($object)."Mfile : public System {\n\n";
		       
print HFH "private:\n";
    print HFH "    double __Mli_lastTime\;\n";
for ($i=0; $i<$inamelen; $i++) { 
    $tmp = $itype[$i];
    if (lc($tmp) =~ m"parameter") {
       $tmp =~ s"parameter""g;
       $tmp =~ s/\s+//g;
       print HFH "    $tmp ".$iname[$i]."\;\n";
    }
}
for ($i = 0; $i < @istatvar; $i++) {
    print HFH "    mxArray* ".$istatvar[$i]."\;\n";
}

		       
print HFH "\n";
print HFH "public:\n";
for ($i=0; $i<$inamelen; $i++) { 
    $tmp = $itype[$i];
    $tmp =~ s/^\s+//;
    @tmp1 = split(m" ",$tmp);
    if (@tmp1 > 1) {
        if (lc($tmp1[0]) =~ m"input") {
            print HFH "    Input< ".$tmp1[1]." > ".$iname[$i]."\;\n";
        }
    }
    else {
        if ($tmp1[0] ne "state") {
            print HFH "    Input< ".$tmp1[0]." > ".$iname[$i]."\;\n";
        }
    }
}

print HFH "\n";
for ($i=0; $i<$onamelen; $i++) { 
    $tmp = $otype[$i];
    $tmp =~ s/^\s+//;
    @tmp1 = split(m" ",$tmp);
    if (@tmp1 > 1) {
        if (lc($tmp1[0]) =~ m"output") {
            print HFH "    Output< ".$tmp1[1]." > ".$oname[$i]."\;\n";
        }
    }
    else {
        if (lc($tmp1[0]) eq "state" || lc($tmp1[0]) eq "null") {}
        else {
            print HFH "    Output< ".$tmp1[0]." > ".$oname[$i]."\;\n";
        }
    }
}
print HFH "\n";

print HFH "    Mli".ucfirst($object)."Mfile(SystemNode *parent, const char *name";
for ($i=0; $i<$inamelen; $i++) { 
    $tmp = $itype[$i];
    if (lc($tmp) =~ m"parameter") {
       $tmp =~ s"parameter""g;
       $tmp =~ s/\s+//g;
       print HFH ",\n";
       print HFH "        ".$tmp." _".$iname[$i];
    }
}
print HFH "):\n";
 
print HFH "        System(parent, name),\n";
print HFH "        __Mli_lastTime(now()-1.0)";

for ($i=0; $i<$inamelen; $i++) { 
    $tmp = $itype[$i];
    if (lc($tmp) =~ m"input") {
       print HFH ",\n";
       print HFH "        $iname[$i]"."(this, "."\"".$iname[$i]."\")";
    }
    else {
       if ($tmp =~ m"parameter" ) {
           $tmp =~ s"parameter""g;
           $tmp =~ s/\s+//g;
           print HFH ",\n";
           print HFH "        $iname[$i](_".$iname[$i].")";
       }
       elsif ($tmp =~ m"expression") {      
       }
       elsif ($tmp =~ "state") {
           print HFH ",\n";
           print HFH "        $iname[$i]"."(NULL)";   
       }
       else {
           print HFH ",\n";
           print HFH "        $iname[$i]"."(this, "."\"".$iname[$i]."\")";        
       }
    }   
}
for ($i=0; $i<$onamelen; $i++) { 
    $tmp = $otype[$i];
    if (lc($tmp) =~ m"output") {
       print HFH ",\n";
       print HFH "        $oname[$i]"."(this, "."\"".$oname[$i]."\")";
    }
    else {
       if (lc($tmp) eq "state" || lc($tmp) eq "null") { 
       }
       else {
           print HFH ",\n";
           print HFH "        $oname[$i]"."(this, "."\"".$oname[$i]."\")";        
       }
    }   
}

print HFH "\n";
print HFH "    {\n";
print HFH "#ifdef "."MLI".uc($object)."MFILE"."TIMESTEP\n";
print HFH "        scheduleEvent(0.0, \"timestep\")\;\n";
print HFH "#endif\n";
print HFH "    }\n\n";
		       
print HFH "    void respondToChangedInputs()\n";
print HFH "    {\n";
print HFH "#ifdef "."MLI".uc($object)."MFILE"."INPUTDRIVEN\n";
print HFH "        if(now() != __Mli_lastTime) {\n";
for ($i=0; $i<$onamelen; $i++) { 
    $tmp = $otype[$i];
    if (lc($tmp) =~ m"output") {
       print HFH "            $oname[$i]".".warnReferencors()\;\n";
    }
    else {
       if (lc($tmp) eq "state" || lc($tmp) eq "null") { 
       }
       else {
           print HFH "            $oname[$i]".".warnReferencors()\;\n";       
       }
    }   
}
print HFH "            computeOutputs()\;\n";
print HFH "        }\n";
print HFH "#else\n";
for ($i=0; $i<$onamelen; $i++) { 
    $tmp = $otype[$i];
    if (lc($tmp) =~ m"output") {
       print HFH "        $oname[$i]".".warnReferencors()\;\n";
    }
    else {
       if (lc($tmp) eq "state" || lc($tmp) eq "null") { 
       }
       else {
           print HFH "        $oname[$i]".".warnReferencors()\;\n";       
       }
    }   
}
print HFH "#endif\n";
print HFH "    }\n\n";

print HFH "    void respondToOutputRequest(OutputBase* /* output */) {\n";
print HFH "        if (now() != __Mli_lastTime) {\n";
print HFH "            computeOutputs()\;\n";
print HFH "        }\n"; 
print HFH "    }\n\n";

print HFH "    void computeOutputs()\n";
print HFH "    {\n";
print HFH "#ifdef "."MLI".uc($object)."MFILE"."ENGINE\n"; 
print HFH "        Engine *ep = mliEngine()\;\n";
print HFH "        mxArray *mxtmp = NULL\;\n\n";

for ($i=0; $i<$inamelen; $i++) {
    $tmp = $itype[$i];
    if (lc($tmp) =~ m"expression") {
       $tmp =~ s"expression""g;
       $tmp =~ s/\s+//g;
       print HFH "        mxtmp = toMxArray(".$tmp.")\;\n";
       print HFH "        mxSetName(mxtmp,\"".$iname[$i]."\")\;\n";
       print HFH "        engPutArray(ep,mxtmp)\;\n";
       print HFH "        mxDestroyArray(mxtmp)\;\n\n";
    }
    elsif ($tmp =~ m"state") {
       print HFH "        if (".$iname[$i]." == NULL) ".$iname[$i]." = mxCreateDoubleMatrix(0, 1, mxREAL)\;\n";
       print HFH "        mxSetName(".$iname[$i].",\"".$iname[$i]."\")\;\n";
       print HFH "        engPutArray(ep,".$iname[$i].")\;\n";
       print HFH "        mxDestroyArray(".$iname[$i].")\;\n\n";
    } 
    else {
       print HFH "        mxtmp = toMxArray(".$iname[$i].")\;\n";
       print HFH "        mxSetName(mxtmp,\"".$iname[$i]."\")\;\n";
       print HFH "        engPutArray(ep,mxtmp)\;\n";
       print HFH "        mxDestroyArray(mxtmp)\;\n\n";
    }
}
print HFH "\n";

print HFH "        engEvalString(ep,\"".$usg."\;\")\;\n\n";

for ($i=0; $i<$onamelen; $i++) {
    $tmp = $otype[$i];
    if (lc($tmp) =~ m"state") {
        print HFH "        ".$oname[$i]." = engGetArray(ep, \"".$oname[$i]."\")\;\n";
    }
    else {
        if (lc($tmp) =~ m"null") {}
        else {
            print HFH "        fromMxArray(mxtmp = engGetArray(ep, \"".$oname[$i]."\"),".$oname[$i].")\;\n";
            print HFH "        mxDestroyArray(mxtmp)\;\n";
        }
    }
}
print HFH "#endif\n\n";

print HFH "#ifdef "."MLI".uc($object)."MFILE"."MEX"." | MLI".uc($object)."MFILE"."COMPILED\n";
if ($onamelen != 0 ) {
    print HFH "        mxArray *__Mli_lhs\["."MLI".uc($object)."MFIL"."OUTPUTS"."\]\;\n\n";
}
else {
    print HFH "        mxArray *__Mli_lhs\;\n\n";
}
for ($i=0; $i<$onamelen; $i++) {
    print HFH "        __Mli_lhs\[".$i."\] = NULL\;\n";
}
print HFH "\n";

if ($inamelen != 0 ) {
    print HFH "        mxArray *__Mli_rhs\["."MLI".uc($object)."MFIL"."INPUTS"."\]\;\n";
}
else {
    print HFH "        mxArray *__Mli_rhs\;\n\n";
}
for ($i=0; $i<$inamelen; $i++) {
    $tmp = $itype[$i];
    if (lc($tmp) =~ m"expression") {
       $tmp =~ s"expression""g;
       $tmp =~ s/\s+//g;
       print HFH "        __Mli_rhs\[".$i."\] = NULL\;\n";
       print HFH "        __Mli_rhs\[".$i."\] = toMxArray(".$tmp.")\;\n";
       print HFH "        mxSetName(__Mli_rhs\[".$i."\],\"".$iname[$i]."\")\;\n\n";
    }
    elsif ($tmp =~ m"state") {
       print HFH "        if (".$iname[$i]." == NULL) ".$iname[$i]." = mxCreateDoubleMatrix(0, 1, mxREAL)\;\n";
       print HFH "        __Mli_rhs\[".$i."\] = ".$iname[$i]."\;\n";
       print HFH "        mxSetName(__Mli_rhs\[".$i."\],\"".$iname[$i]."\")\;\n\n";
    }
    else {
       print HFH "        __Mli_rhs\[".$i."\] = NULL\;\n";
       print HFH "        __Mli_rhs\[".$i."\] = toMxArray(".$iname[$i].")\;\n";
       print HFH "        mxSetName(__Mli_rhs\[".$i."\],\"".$iname[$i]."\")\;\n\n";
    }
}
print HFH "#endif\n\n";

print HFH "#ifdef "."MLI".uc($object)."MFILE"."MEX"."\n";
print HFH "        mexCallMATLAB"."("."MLI".uc($object)."MFIL"."OUTPUTS".",__Mli_lhs,"."MLI".uc($object)."MFIL"."INPUTS".",__Mli_rhs,".
"\"$object\"".")\;\n";
print HFH "#endif\n\n";

print HFH "#ifdef "."MLI".uc($object)."MFILE"."COMPILED"."\n";
print HFH "        ml".ucfirst($object)."("."MLI".uc($object)."MFIL"."OUTPUTS".",__Mli_lhs,"."MLI".uc($object)."MFIL"."INPUTS".",__Mli_rhs)\;\n";
print HFH "#endif\n\n";

print HFH "#ifdef "."MLI".uc($object)."MFILE"."MEX"." | MLI".uc($object)."MFILE"."COMPILED\n";

print HFH "        int i\;\n";
print HFH "        for(i=0\; i<"."MLI".uc($object)."MFIL"."INPUTS"."\; i++) mxDestroyArray(__Mli_rhs\[i\])\;\n\n";

for ($i=0; $i<$onamelen; $i++) { 
    $tmp = $otype[$i];
    if (lc($tmp) =~ m"state") {
	    print HFH "        ".$oname[$i]." = __Mli_lhs\[$i\]\;\n";
	}
    else {
        if (lc($tmp) =~ m"null") {}
        else {
	    print HFH "        fromMxArray(__Mli_lhs\[".$i."\],".$oname[$i].")\;\n";
            print HFH "        mxDestroyArray(__Mli_lhs\[$i\])\;\n";
        }
    }   
}
print HFH "\n";
print HFH "#endif\n\n";

print HFH "        __Mli_lastTime = now()\;\n\n";

print HFH "    }\n\n";

print HFH "#ifdef "."MLI".uc($object)."MFILE"."TIMESTEP"."\n";
print HFH "    void respondToScheduledEvent(const Event& event)\n";
print HFH "    {\n";
print HFH "       if (strcmp(event.descriptor, \"timestep\") == 0)\n";
print HFH "       {\n";
print HFH "          respondToChangedInputs()\;\n";
print HFH "          scheduleEvent("."MLI".uc($object)."MFILE"."TIMESTEP,"." \"timestep\")\;\n";
print HFH "       }\n";
print HFH "    }\n";
print HFH "#endif\n";

print HFH "}\;\n\n";
print HFH "#endif //"."MLI".uc($object)."MFILE_CLASS_H\n";
close(HFH);

#ml(object).h
open(HFH, ">$mlhfile");

print HFH "//\n";
print HFH "// ".$mlhfile." Generated on ".localtime()."\n"; 
print HFH "// (c) Copyright 2000, MZA Associates Corporation\n";
print HFH "//\n\n";

print HFH "#ifndef "."ML".uc($object)."_H\n";
print HFH "#define "."ML".uc($object)."_H\n\n";
print HFH "#include \"mat.h\"\n\n";

print HFH "void ml".ucfirst($object)."(int nlhs, mxArray * plhs\[\], int nrhs, mxArray * prhs\[\])\;\n\n";

print HFH "#endif\n"; 

close(HFH);

#ml(object).cpp
open(CFH, ">$mlcfile");

print CFH "//\n";
print CFH "// ".$mlcfile." Generated on ".localtime()."\n"; 
print CFH "// (c) Copyright 2000, MZA Associates Corporation\n";
print CFH "//\n\n";

print CFH "#include \"ml".ucfirst($object).".h\"\n";
print CFH "#include \"".$object.".hpp\"\n\n";

print CFH "void ml".ucfirst($object)."(int nlhs, mxArray * plhs\[\], int nrhs, mxArray * prhs\[\]){\n";
print CFH "    mlx".ucfirst($object)."(nlhs, plhs, nrhs, prhs)\;\n";
print CFH "}\n";

close(CFH);

#(object).tsd file
open(TSD, ">$tsdfile");

print TSD "tempus 2000.01\n";
print TSD "//\n";
print TSD "// (c) Copyright 2000, MZA Associates Corporation\n";
print TSD "//\n\n";

print TSD "NAME = "."Mli".ucfirst($object)."Mfile  "."\[Interface: ".localtime()." GMT\]"."   \[Implementation: ".localtime()." GMT\]   (*) //\n\n";

print TSD "C++ CODE\n\n";

format TSD = 
   @<<<<<<<<<<<<<<<<<<<<<<<   @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<        @<    @<<
   $type                      $name                                         $eq   $bs
.
$eq = '=';
$bs = '//';

print TSD "PARAMETERS\n";
for($i=0; $i<$inamelen; $i++) {
    $tmp = $itype[$i];
    if ($tmp =~ m"parameter") {
       $tmp =~ s"parameter""g;
       $tmp =~ s/\s+//g;
       $type = $tmp;
       $name = $iname[$i];
       #write TSD;
       print TSD "   $type"."   $name"." $eq"."  $bs\n";
    }
}

print TSD "\n";
print TSD "INPUTS\n";
for($i=0; $i<$inamelen; $i++) {
    $tmp = $itype[$i];
    if ($tmp =~ m"input") {
       $tmp =~ s"input""g;
       $tmp =~ s/\s+//g;
       $type = $tmp;
       $name = $iname[$i];
       #write TSD;
       print TSD "   $type"."   $name"." $eq"."  $bs\n";
    }
    else {
#       if ($tmp =~ m"parameter" || $tmp =~ m"expression") {}
       if ($tmp =~ m"parameter" || $tmp =~ m"expression" || $tmp =~ m"state") {}
       else {
          $tmp =~ s/\s+//g;
          $type = $tmp;
          $name = $iname[$i];
          #write TSD;
          print TSD "   $type"."   $name"." $eq"."  $bs\n";
       }
    }
}

print TSD "\n";
print TSD "OUTPUTS\n";
for($i=0; $i<$onamelen; $i++) {
if ($otype[$i] =~ m"state") {}
else {
   $type = $otype[$i];
   $name = $oname[$i];
   #write TSD;
   print TSD "   $type"."   $name"." $eq"."  $bs\n";
}
}

print TSD "\n";
print TSD "SUBSYSTEMS\n\n";

print TSD "CONNECTIONS\n\n";
close(TSD);

#(object).html file
open(HTM, ">$htmfile");

print HTM "<html>\n";
print HTM "<head>\n";
print HTM "<title>"."Mli".ucfirst($object)."Mfile"."</title>\n";
print HTM "</head>\n";
print HTM "<body>\n";
print HTM "<h1>"."Mli".ucfirst($object)."Mfile"."</h1>\n";

print HTM "<h2>Description</h2>\n";
print HTM "<p>\n";
print HTM "\n";
print HTM "</p>\n";

print HTM "<h2>Subsystems</h2>\n";
print HTM "<p>\n";
print HTM "None\n";
print HTM "</p>\n";

print HTM "<hr>\n";
print HTM "<h2>Parameters</h2>\n";
print HTM "<table border>\n";
print HTM "<tr>\n";
print HTM "<th>Name</th>\n";
print HTM "<th>Type</th>\n";
print HTM "<th>Description</th>\n";
print HTM "</tr>\n";
for ($i=0; $i<$inamelen; $i++) {
    $tmp = $itype[$i];
    if ($tmp =~ m"parameter") {
       $tmp =~ s"parameter""g;
       $tmp =~ s/\s+//g;
       $type = $tmp;
       $type =~ s">"&gt"g;
       $type =~ s"<"&lt"g;
       print HTM "<tr>\n";
       print HTM "<td>".$iname[$i]."</td>\n";
       print HTM "<td>".$type."</td>\n";
       print HTM "<td></td>\n";
       print HTM "</tr>\n";       
    }
}
print HTM "</table>\n";
print HTM "<hr>\n";

print HTM "<h2>Inputs</h2>\n";
print HTM "<table border>\n";
print HTM "<tr>\n";
print HTM "<th>Name</th>\n";
print HTM "<th>Type</th>\n";
print HTM "<th>Description</th>\n";
print HTM "</tr>\n";

for ($i=0; $i<$inamelen; $i++) {
    $tmp = $itype[$i];
    if ($tmp =~ m"input") {
       $tmp =~ s"input""g;
       $tmp =~ s/\s+//g;
       $type = $tmp;
       $type =~ s">"&gt"g;
       $type =~ s"<"&lt"g;
       print HTM "<tr>\n";
       print HTM "<td>".$iname[$i]."</td>\n";
       print HTM "<td>".$type."</td>\n";
       print HTM "<td></td>\n";
       print HTM "</tr>\n";       
    }
    else {
#       if ($tmp =~ m"parameter" || $tmp =~ m"expression") {}
       if ($tmp =~ m"parameter" || $tmp =~ m"expression" || $tmp =~ m"state") {}
       else {
          $tmp =~ s/\s+//g;
          $type = $tmp;
          $type =~ s">"&gt"g;
          $type =~ s"<"&lt"g;
          print HTM "<tr>\n";
          print HTM "<td>".$iname[$i]."</td>\n";
          print HTM "<td>".$type."</td>\n";
          print HTM "<td></td>\n";
          print HTM "</tr>\n";
       }
    }   
}

print HTM "</table>\n";
print HTM "<hr>\n";

print HTM "<h2>Outputs</h2>\n";
print HTM "<table border>\n";
print HTM "<tr>\n";
print HTM "<th>Name</th>\n";
print HTM "<th>Type</th>\n";
print HTM "<th>Description</th>\n";
print HTM "</tr>\n";

for ($i=0; $i<$onamelen; $i++) {
if ($otype[$i] =~ m"state") {}
else {
    $type = $otype[$i];
    $type =~ s">"&gt"g;
    $type =~ s"<"&lt"g;
    print HTM "<tr>\n";
    print HTM "<td>".$oname[$i]."</td>\n";
    print HTM "<td>".$type."</td>\n";
    print HTM "<td></td>\n";
    print HTM "</tr>\n";   
}
}

print HTM "</table>\n";
print HTM "</body>\n";
print HTM "</html>\n";

close(HTM);
