#
# Library functions for the ic_xml library
#
# File: ic_xml/lib/mesh_report.tcl
#
# $Revision$ on $Date$
# 
# Copyright (c) 1993-2004 ICEM CFD Engineering
#
# Author: Jason Aftosmis (jason@icemcfd.com)
#
# TODO:
#   o
#
#---------------------------------------------------------------------
#
#      <mesh_quality subset="All">
#           <metric name="Quality">
#                <histogram name="Quality" min="0" max="1" nintervals="10">
#                     <interval min="0" max="0.1">21</interval>
#                     <interval min="0.1" max="0.2">3</interval>
#                     <interval min="0.2" max="0.3">5</interval>
#                     <interval min="0.3" max="0.4">8</interval>
#                     <interval min="0.4" max="0.5">11</interval>
#                     <interval min="0.5" max="0.6">19</interval>
#                     <interval min="0.6" max="0.7">63</interval>
#                     <interval min="0.7" max="0.8">41</interval>
#                     <interval min="0.8" max="0.9">36</interval>
#                     <interval min="0.9" max="1.0">510</interval>
#                </histogram>
#           </metric>
#           <custom_metric name="Custom quality">
#                <criteria>
#                     <criterion name="Min side" eltype="QUAD_4">
#                        <critical_point name="" key="acc_min">3.458742</<critical_point>
#                        <critical_point name="" key="des_min">4.799901</<critical_point>
#                        <critical_point name="" key="ideal">5.0</<critical_point>
#                        <critical_point name="" key="des_max">5.182219</<critical_point>
#                        <critical_point name="" key="acc_max">6.423378</<critical_point>
#                     </criterion>
#                     <criterion name="Min side" eltype="TRI_3">
#                        <critical_point name="" key="acc_min">3.458742</<critical_point>
#                        <critical_point name="" key="des_min">4.799901</<critical_point>
#                        <critical_point name="" key="ideal">5.0</<critical_point>
#                        <critical_point name="" key="des_max">5.182219</<critical_point>
#                        <critical_point name="" key="acc_max">6.423378</<critical_point>
#                     </criterion>
#                </criteria>
#                <histogram name="Quality" min="0" max="1" nintervals="10">
#                     <interval min="0" max="">21</interval>
#                     <interval min="0.1" max="0.2">3</interval>
#                     <interval min="0.2" max="0.3">5</interval>
#                     <interval min="0.4" max="1">11</interval>
#                </histogram>
#           </metric>
#           ...
#      </mesh_quality>
#
#---------------------------------------------------------------------


namespace eval MeshReport {    

    namespace import ::IcXml::*
    
    variable _root_element_name "mesh_report"
    
    variable _xsl_file [file join [ic_xml_lib_path] .. style mesh_report.xsl]
    variable _css_file [file join [ic_xml_lib_path] .. style generic_report.css]    
    
    proc err {text}   { return [ic_xml_err   "MeshReport: $text"] }
    proc debug {text} { return [ic_xml_debug "MeshReport: $text"] }
}


#---------------------------------------------------------------------


## Test the MeshReport functions

proc MeshReport::test {} {
    
    foreach test {meshreport1} {
	
	set key [MeshReport::createDocument "name $test title Hello"]
	MeshReport::addSummaryData $key  "name \"Element counts\"" [list "QUAD_4 percentage 90" "TRI_3 percentage 10"]
	MeshReport::addQualityMetric $key "title asdf type qwer" "determinant 1"
	MeshReport::addDiagnosticCriterion $key Overlapping "key overlapping number 4"
	MeshReport::writeReport $key ${test}a.html html
	MeshReport::closeReport $key ${test}a.xml xml
	
	set key [MeshReport::openReport ${test}a.xml]
	MeshReport::addSummaryData $key  "name \"Element percentages\"" [list "QUAD_4 integer 285" "TRI_3 integer 215"]
	MeshReport::addQualityMetric $key "title qwer type oiyy" "distortion .5"
	MeshReport::addDiagnosticCriterion $key Penetrating "key penetrating number 12"
	MeshReport::closeReport $key ${test}b.xml xml

	file delete -force ${test}a.html
	# meshreport1a.xml & meshreport1b.xml are used in AssemblyReport::test
    }
    
    return [IcXmlReport::checkEmpty]
}


## Create a document with a root element. Returns the domKey.

proc MeshReport::createDocument { attributes } {
    return [IcXmlReport::createDocument "mesh_report" $attributes]
}


## 

proc MeshReport::addHeader { domKey addToObj children } {
    return  [IcXmlReport::addHeader $domKey $addToObj $children]
}


##

proc MeshReport::addSummary { domKey attributes } {
    return [IcXmlReport::ensureReportElement $domKey "mesh_summary" $attributes]
}


## 
## e.g.: 
##   

proc MeshReport::addSummaryData { domKey attributes children } {
    
    # don't write this elements without any children specified    
    if {"" == $children} {
	return ""
    }

    set summaryObj [IcXmlReport::ensureReportElement $domKey "mesh_summary"]
    
    set newObj [IcXmlReport::addDataSet $domKey $summaryObj $attributes $children]
    
    return $newObj
}


##

proc MeshReport::addQuality { domKey attributes } {
    return [IcXmlReport::ensureReportElement $domKey "mesh_quality" $attributes]
}


##
## e.g.:
##    MeshReport::addQualityMetric ...fixme...

proc MeshReport::addQualityMetric { domKey attributes children {histogramData ""} } {
    
    set qualityObj [IcXmlReport::ensureReportElement $domKey "mesh_quality"]
    
    set metricObj [IcXmlReport::addElement $domKey $qualityObj "metric" \
		       $attributes $children]
    
    if {"" != $histogramData} {
	set newObj [IcXmlReport::addHistogram $domKey $metricObj [lindex $histogramData 0] \
			[lindex $histogramData 1]]
    }
    
    return FIXME; #$qualityObj
}

##
## e.g.:
##    MeshReport::addQualityMetric ...fixme...
##
## <custom_quality>
##
##

proc MeshReport::addCustomQuality { domKey attributes {metricsData ""} {histogramData ""}} {
    
    set qualityObj [IcXmlReport::ensureReportElement $domKey "mesh_quality"]
    
    set custMetObj [IcXmlReport::addElement $domKey $qualityObj "custom_metric" \
		       $attributes "" ]
    
    set metDefObj []
    
    set histObj [IcXmlReport::addHistogram $domKey $metricObj [lindex $histogramData 0] \
		    [lindex $histogramData 1]]
    
    return FIXME; #$qualityObj
}


## FIXME-doc

proc MeshReport::addDiagnostics { domKey attributes } {
    return [IcXmlReport::ensureReportElement $domKey "mesh_diagnostics" $attributes]
}


## Add a diagnostic to the mesh_diagnostics block. FIXME-doc

proc MeshReport::addDiagnosticCriterion { domKey name children } {
    
    set diagObj [addDiagnostics $domKey ""]
    
    set elName     "criterion"
    set attributes "name $name"
    set newObj [IcXmlReport::addElement $domKey $diagObj $elName \
		    $attributes $children]
    
    return $newObj
}


## Open an XML file. Return a domKey

proc MeshReport::openReport { xml_file } {
    variable _root_element_name
    return [IcXmlReport::openReport $xml_file $_root_element_name]
}


## Depending on whether or not the given xml_file already exists, it will
## either open the existing, or create a new (in which case no filename association
## should be assumed). Returns the domKey.

proc MeshReport::appendReport { xml_file {attributes ""} } {
    
    if ![file exists $xml_file] {
	return [createDocument $attributes]
    } else {
	return [openReport $xml_file]
    }
}


## Write out the MeshReport associated with the given <em>domKey</em>
## to the path <em>file</em> in the format <em>format</em>.

proc MeshReport::writeReport { domKey file format } {
    variable _css_file
    variable _xsl_file
    
    set args ""
    
    if {("" != $_xsl_file) && [file exists $_xsl_file]} {
	append args "-xsl_file {$_xsl_file} "
    } elseif {"" != $_xsl_file}  {
	err "Warning: could not find XSL file $_xsl_file"
    }
    if {("" != $_css_file) && [file exists $_css_file]} {
	append args "-css_file {$_css_file} "
    } elseif {"" != $_css_file}  {
	err "Warning: could not find CSS file $_css_file"
    }
    
    return [IcXmlReport::writeReport $domKey "$file" $format $args]
}   


## Close the MeshReport associated with the given <em>domKey</em>
## and, if specified, to write it to the path <em>file</em> in the
## format <em>format</em>.

proc MeshReport::closeReport { domKey {file ""} {format ""} } {
    
    if {"" != $file} {
	set stat [MeshReport::writeReport $domKey $file $format]
    }
    return [IcXmlReport::closeDocument $domKey]
}
