## <h3>Regression testing functions</h3>

## General resultlib read function.  Reads the files specified by the
## file list using the reader specified by the backend.  If create
## is one, the unstruct/struct meshes will be recreated

proc ic_regression_list {args} {
    regression_parse_list config
    
    if ![info exists config(action)] { set config(action) run}
    if ![info exists config(match)]  { set config(match) "-fuzzy"}
    if ![info exists config(mesh)]   { set config(mesh) "-info"}
    if ![info exists config(rfint)]  { set config(rfint) "" }
    
    regression_check_config config
    
    ic_regression_test_rfint $config(rfint) $config(action) $config(cfile) \
	$config(match) $config(mesh) $config(compareopts) \
	$config(prec) $config(tstep) $config(dir) $config(cstyle) \
	$config(factory) $config(meshimpl)
}

## Carry out regression test.
## action: create or run
##
## cfile: is the comparison file name.  If the macro $D is in the name,
## the directory given by the dir parameter will be substituted for it.
##
## All of the rest of the arguments are optional.
##
## match: {-exact | -fuzzy} If -exact, then the all portions of the mesh
## comparison must match exactly.  If -fuzzy, then the comparison does not
## have to be exact (ie, allow discrepancies up to certain percentage
## of the checks).
##
## mesh: {-mapped | -info | -nofamily | -nofamilycounts | -grid |
## -elements | -all}* this list tells what the regression test will match. 
## If -mapped is specified, then the nodes of the mesh are mapped  to the
## comparison mesh.  If -info in list, the counts of nodes, elements,
## structured domains, families and family members will all be checked.
## If -nofamily is specified with -info, the family name portion of the
## mesh will not be checked.  If no family counts is specified, the family
## names will be checked, but no match in counts of the family members
## will be required.  If -grid is specified, then the nodes of the mesh
## will be checked.  If -elements is specified, then the finite elements
## will be checked.  If -nofamily (or -nofamilycounts) specified with
## -elements, then the family id will not be checked.  If -all is
## specified, then information, grid and elements will all be checked.
## The -nofamily and -nofamilycounts will still act as qualifiers in
## this case.
##
## compareopts any additional comparison options.  The match and grid
## arguments set the basic comparison options for the regression test.
## users can augument the comparison (for instance changing the tolerances
## for distances) by setting this option.  These options will be appended
## to those determined by the match and mesh options
##
## prec: {double | float} precision of grid coordinates.  Default is double.
##
## tstep: timestep to load.  Reserved for future use.
##
## dir: is the directory the comparison file can be found.  Default is
## env(REGRESSION_DIR) if set, or the current working directory if not.
## Only used if $D is in the comparison file name.
##
## cstyle: is the style of the comparison file.  The only options are script
## or domain; CGNS is reserved for future use.
##
## factory the factory for the backend for the comparison file.  If
## not given, it will use the domain factory which has an internal domain
## file reader (only relevent in case of the comparision file style not
## being a script file).
##
## meshimpl the mesh implementation.  If not given, this will use
## med_impl

proc ic_regression_test {action cfile \
			     {match "-fuzzy"} \
			     {mesh "-info"} \
			     {compareopts ""} {prec double} {tstep 0} \
			     {dir ""} {cstyle domain} \
			     {factory ""} {meshimpl ""}} {
    return [ic_regression_test_rfint "" $action $cfile $match $mesh \
		$compareopts $prec $tstep $dir $cstyle $factory $meshimpl]
}

## The only difference between this proc and ic_regression_test is that
## it allows the mesh to be computed externally.  For instance, load
## mesh tests would use this interface as opposed to 
## regression_test interface

proc ic_regression_test_rfint {rfint action cfile \
				   {match "-fuzzy"} \
				   {mesh "-info"} \
				   {compareopts ""} {prec double} {tstep 0} \
				   {dir ""} {cstyle domain} \
				   {factory ""} {meshimpl ""}} {
    if {$rfint == ""} {
	set rfint [ic_regression_createinterface]
    }
    
    set ret "Unknown status"
    set copts [ic_regression_compareopts $match $mesh $compareopts]
    switch $action {
	run {
	    
	    if {$factory == ""} {
		catch {med_fact__rg delete}
		set factory [rf_factory_icem med_fact__rg]
	    }
	    
	    if {$meshimpl == ""} {
		catch {med__rg delete}
		set meshimpl [rf_med_unsstr med__rg]
	    }
	    mess "regression_test_rfint $rfint $dir $cstyle \
			   $cfile $prec 0 \"\" $copts $factory $meshimpl\n"
	    set rgres [regression_test_rfint $rfint $dir $cstyle \
			   $cfile $prec 0 "" $copts $factory $meshimpl]
	    
	    set stat [lindex $rgres 0]
	    switch $stat {
		0 {
		    set ret "Test failed"
		}
		
		1 {
		    set ret "Test succeeded"
		}
		
		default {
		    set ret "Test succeeded within tolerance"
		}
	    }
	}
	
	create {
	    set rgres [regression_create_rfint $rfint $dir $cstyle $cfile \
			   $prec 0 "" $copts 1]
	    set file [lindex $rgres 0]
	    set ret "Creation of \"$file\" succeeded"
	}
	
	default {
	    error "Action $action is not recognized."
	}
    }
    set rgres [lreplace $rgres 0 0 $ret]
    return $rgres
}

proc ic_regression_createinterface {} {
    global uns_cur str_cur
    
    catch {rfint_rg delete}
    set rfint [rf_med_interface rfint_rg]
    if {$rfint == ""} {
	error "Could not create regression interface"
    }
    
    if ![info exists uns_cur] {
	set use_uns ""
    } else {
	set use_uns $uns_cur
    }
	
    if ![info exists str_cur] {
	set use_str ""
    } else {
	set use_str $str_cur
    }
    
    $rfint configure_mesh $use_uns $use_str
    return $rfint
}

proc ic_regression_compareopts {match mesh compareopts} {
    set copts ""
    set fz 1
    
    if {$match == "-exact"} {set fz 0}
    
    set mp 0
    set info 0
    set fam 1
    set famdesc 1
    set grid 0
    set conn 0
    
    foreach l $mesh {
	switch -- $l {
	    -mapped {
		set mp 1
	    }
	    
	    -info {
		set info 1
	    }
	    
	    -nofamily {
		set fam 0
	    }
	    
	    -nofamilycounts {
		set famdesc 0
	    }
	    
	    -grid {
		set grid 1
	    }
	    
	    -elements {
		set conn 1
	    }
	    
	    -all {
		set grid 1
		set conn 1
		set info 1
	    }
	}
    }
    
    if {$info} {
	if $fz {
	    set gs -fuzzydesc
	} else {
	    set gs -desc
	}
    } else {
	set gs -nodesc
    }
    set copts "$gs"
	
    if {$fam} {
	if $fz {
	    set gs -fuzzyfamily
	} else {
	    set gs -family
	}
    } else {
	set gs -nofamily
    }
    append copts " $gs"
	
    if {$famdesc} {
	if $fz {
	    set gs -fuzzyfamdesc
	} else {
	    set gs -famdesc
	}
    } else {
	set gs -nofamdesc
    }
    append copts " $gs"
	
    if {$grid} {
	if $fz {
	    set gs -fuzzygrid
	} else {
	    set gs -grid
	}
    } else {
	set gs -nogrid
    }
    append copts " $gs"
	
    if {$conn} {
	if $fz {
	    set gs -fuzzyconn
	} else {
	    set gs -conn
	}
    } else {
	set gs -noconn
    }
    append copts " $gs"
	
    if {$mp && ($conn || $grid)} {
	append copts " -mapmesh"
    }
    
    append copts " $compareopts"
    return $copts
}

