
proc v3readers_defaults {} {
    global v3readers env tcl_platform
    
    if ![info exists v3readers(envvars)] {
	set v3readers(envvars) "VISUAL3_DIR VISUAL3P_ROOT MED_ROOT ICEM_ACN"
    }
    
    if ![info exists v3readers(path)] {
	set v3readers(path) ./result-interfaces
	foreach genv $v3readers(envvars) {
	    if [info exists env($genv)] {
		lappend v3readers(path) $env($genv)/icemcfd/result-interfaces
	    }
	}
    }
    
    set v3readers(domain_alias) [list icemcfd domain ICEMCFD DOMAIN \
				     "ICEM CFD" "icem cfd" readdomain]
    
    set v3readers(blocking_alias) \
	[list blocking BLOCKING Blocking readblocking]
    
    set v3readers(script_alias) [list script SCRIPT Script readscript]
}

proc v3readers_init {} {
    global v3readers
    v3readers_defaults
}

proc v3readers_append_path {dir} {
    v3readers_insert_path $dir end
}

proc v3readers_prepend_path {dir} {
    v3readers_insert_path $dir beg
}

proc v3readers_insert_path {dir pos} {
    global v3readers
    
    v3readers_init
    if ![string compare $pos end] {
	lappend v3readers(path) $dir
    } else {
	if ![string compare $pos beg] { set pos 0 }
	set v3readers(path) [linsert $v3readers(path) $pos $dir]
    }
}

proc v3readers_tcl_dir {pdir} {
    
    # Insure a unix style file name because of the dag gone
    # \ on windows and version problems so cannot use file nativename
	    
    set components [file split $pdir]
    set dir ""
    set ncomp [llength $components]
    for {set i 0} {$i < $ncomp} {incr i} {
	append dir [lindex $components $i]
	if {$i != $ncomp-1} { append dir / }
    }
    return $dir
}

proc v3readers_available {{v3prod v3p}} {
    global v3readers backend_info visual3_dir env
    global v3readers_available_init v3readers_format
    
    v3readers_init
    if ![info exists v3readers_available_init] {
	    set v3readers_available_init 1
	    if ![info exists visual3_dir] {
	        set visual3_dir .
	        foreach genv $v3readers(envvars) {
		        if [info exists env($genv)] {
		            set visual3_dir $env($genv)
		            break
		        }
	        }
	    }
	    foreach pdir $v3readers(path) {
	        set dir [v3readers_tcl_dir $pdir]
	        set afiles ""
	        switch $v3prod {
		        v3p - 0 {
		            #lappend afiles $dir/*_format_v3p.tcl
		        }	
                v3 - 1 {
		            lappend afiles $dir/*_format.tcl
		        }	
		        all - 2 {
		            #lappend afiles $dir/*_format_v3p.tcl $dir/*_format.tcl
		            lappend afiles $dir/*_format.tcl
		        }
	        }
	        if {$afiles == ""} continue
	        set allfiles [eval glob -nocomplain $afiles]
	        foreach ff $allfiles {
		        set next [file root [file tail $ff]]
		        regexp {([a-zA-Z0-9+-]*)_format(_v3p)?} $next dum key
		        if ![info exists v3readers_format($key)] {
		            if ![catch {uplevel \#0 source $ff} msg] {
			            set v3readers_format($key) 1
		            } else {
			            puts "failed to read $next:\n$msg"
		            }
		        }
	        }
	    }
    }
    
    set ret ""
    foreach bt [lsort [array names backend_info]] {
	    set bi $backend_info($bt)
	    lappend ret [list $bt $bi]
    }
    return $ret
}

proc v3readers_get_reader_label { reader_format } {
    return [v3readers_get_reader_data $reader_format 0]
}

proc v3readers_get_reader_name { reader_format } {
    return [v3readers_get_reader_data $reader_format 1]
}
# Key list returns list items as {reader_format reader_data}
#   where reader_data is a list composed of {label reader associated_array}
proc v3readers_get_reader_data { reader_format data_index } {
    set key [v3readers_available]
    foreach item $key {
        set type [lindex $item 0]
        if {$type == $reader_format} {
            set type_info [lindex $item 1]
            set data [lindex $type_info $data_index]
            return $data
        }
    }
    return ""
}

proc v3reader_backend_for {bt {v3prod v3p}} {
    global v3readers
    
    set cdesc [v3reader_backenddesc_for $bt $v3prod]
    if {$cdesc == ""} { return ""}
    
    set desc [lindex $cdesc 1]
    set alias [lindex $desc 0]
    if {[lsearch $v3readers(domain_alias) $alias] >= 0} { return domain }
    if {[lsearch $v3readers(blocking_alias) $alias] >= 0} { return blocking }
    
    set exec [v3reader_on_path [lindex $desc 1]]
    if {$exec != ""} { return $exec }
    
    return ""
}

proc v3reader_backenddesc_for {bt {v3prod v3p}} {
    global v3readers backend_info
    
    v3readers_available
    if [info exists backend_info($bt)] {
	return [list $bt $backend_info($bt)]
    }

    # ok, try bt as a human readable name

    set name [string toupper $bt]
    foreach bi [array names backend_info] {
	set desc $backend_info($bi)
	set compname [string toupper [lindex $desc 0]]
	if {[string compare $name $compname] == 0} {
	    return [list $bi $desc]
 	}
    }
    
    # last ditch gultch -- try known readers.  Leave till last because may
    # have external readers for each of these guys
    
    if {[lsearch $v3readers(domain_alias) $bt] >= 0} { return domain }
    if {[lsearch $v3readers(blocking_alias) $bt] >= 0} { return blocking }
    if {[lsearch $v3readers(script_alias) $bt] >= 0} { return script }
    
    return ""
}

proc v3reader_on_path {backend} {
    global v3readers tcl_platform

    set iswin [string compare $tcl_platform(platform) windows]
    set backend [file tail [file rootname $backend]]
    if !$iswin { set backend ${backend}.exe }
    foreach pdir $v3readers(path) {
	set dir [v3readers_tcl_dir $pdir]
	if [file executable $dir/$backend] { return $dir/$backend }
    }
    return ""
}

proc v3reader_match_init {init_file} {
    global v3readers
    
    if {$init_file == "" && [info exist env(ICEM_ACN)] && 
	[file exist $env(ICEM_ACN)/gateway_gui/v3_solver_match.tcl]} {
	set init_file $env(ICEM_ACN)/gateway_gui/v3_solver_match.tcl
    }
    
    if [file exist $init_file] {
	uplevel \#0 source $init_file
	v3_solvermatch_list
	return 1
    }
    return 0
}

proc v3reader_solver_match {solver_key} {
    global v3readers
    
    if {![info exist v3readers(match_init)] ||
	!$v3readers(match_init)} {
	if ![v3reader_match_init] { return "" }
    }
    
    if ![info exists v3readers(solverlist)] { return "" }
    foreach solverd $v3readers(solverlist) {
	set solvn [lindex $solverd 0]
	set fileext [lindex $solverd 1]
	
	if {[string match -nocase $solvn $solver_key]} {
	    return $solverd
	}
	
	# if that didn't work, try list of file extensions
	
	foreach fe $fileext {
	    if [string match -nocase $fe $solver_key] {
		return $solverd
	    }
	}
    }
    return ""
}

# Make list of variable descriptors matching the variable key

proc v3reader_variable_match {solver_key variable_key} {
    set solverd [v3reader_solver_match $solver_key]
    if {$solverd == ""} { return "" }
    return [v3reader_find_variable $solverd $variable_key]
}

proc v3reader_find_variable {solverd variable_key} {
    set vardlist ""
    set list_of_vars [lindex $solverd 2]
    foreach vd $list_of_vars {
	if {[string match -nocase [lindex $vd 0] $variable_key]} {
	    lappend vardlist [lindex $vd 1]
	}
    }
    return $vardlist
}

# Try and find variable for this solver in the result for the
# specified result type

proc v3reader_varlist_match {solver_key variable_list result_info \
				 reqtype} {
    
    set solverd [v3reader_solver_match $solver_key]
    if {$solverd == ""} { return "" }
    
    set vartable ""
    set resultd [lindex $result_info 5]
    foreach varkey $variable_list {
	# Get list of possible variable names in the result file
	# for this variable key.  First in list takes prescedence
    
	set varmatchd [v3reader_find_variable $solverd $varkey]
	set matchentry [list $varkey ""]
	if {$varmatchd != ""} {
	    set found 0
	    
	    foreach rd $resultd {
		set resname [string trim [lindex $rd 0]]
		set restype [lindex $rd 1]
		foreach vmd $varmatchd {
		    set base [lindex $vmd 0]
		    if {([string match -nocase $base $resname] ||
			 [string match -nocase ${base}_node $resname] ||
			 [string match -nocase ${base}_cell $resname] ||
			 [string match -nocase ${base}_cell_node $resname]) \
			    && ($reqtype==-1 || \
				    (($reqtype & $restype) != 0))} {
			
			set matchentry [list $varkey $resname]
			set found 1
			break
		    }
		}
		if $found { break }
	    }
	}
	lappend vartable $matchentry
    }
    return $vartable
}
		
