#!/bin/sh  
# \
  exec oagtclsh "$0" "$@"

set auto_path [linsert $auto_path 0  /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]

proc InitialSetup {} {
    set equationPVs ""
    set equationPVvars ""
    set resultPVs ""
    set resultPVvars ""
    global ca equation input

    foreach f $input {
        sdds load $f data
        if {![info exists data(Column.Equation)]} {
            continue
        }
        if {![info exists data(Column.ControlName)]} {
            puts stderr "ControlName column is missing"
            exit 1
        }
        foreach controlNames $data(Column.ControlName) equations $data(Column.Equation) {
            foreach cn $controlNames eq $equations {
                set newEq ""
                foreach element $eq {
                    if {[string range $element 0 2] == "ca:"} {
                        set pv [string range $element 3 end]
                        lappend equationPVs $pv
                        append newEq "\$ca($pv) "
                    } else {
                        append newEq "$element "
                    }
                }
                set newEq [string trim $newEq]
                if {[string length $newEq] != 0} {
                    lappend resultPVs $cn
                    set equation($cn) $newEq
                }
            }    
        }
    }
    if {$resultPVs == ""} {
        exit
    }

    foreach pv $resultPVs {
        lappend resultPVvars ca($pv)
    }
    set equationPVs [lsort -unique $equationPVs]
    foreach pv $equationPVs {
        lappend equationPVvars ca($pv)
    }

    pv toggleErrorMode
    if {[catch {pv linkw $resultPVvars $resultPVs} result]} {
        puts stderr "$result -- $resultPVs"
        exit 1
    }
    if {[catch {pv linkw $equationPVvars $equationPVs} result]} {
        puts stderr "$result -- $equationPVs"
        exit 1
    }
    foreach name $equationPVvars pv $equationPVs {
        pv umon $name "UpdateValues $pv"
    }
}

proc UpdateValues {pvName} {
    global ca equation debug
    if {(":PS:SupplyOnC" == [string range $pvName end-12 end]) || (":PS:SupplyOffC" == [string range $pvName end-13 end])} {
        if {$ca($pvName) == 0} {
            return
        }
    }
    
    set names ""
    foreach name [array names equation] {
        if {$name != $pvName} {
            lappend names ca($name)
        }
    }
    set states [pv info $names state]
    foreach state $states {
        if {[lindex $state 1] != "OK"} {
            exit
        }
    }
    foreach name [array names equation] {
        if {$name == $pvName} { continue }
        if {[catch {eval expr $equation($name)} value]} {
        } else {
            if {$debug != 0} {
                puts "Setting $name = $value"
            }
            if {$value != $ca($name)} {
                set ca($name) $value
                pv putq ca($name)
            }
        }
    }
    if {(":PS:SupplyOnC" == [string range $pvName end-12 end]) || \
        (":PS:SupplyOffC" == [string range $pvName end-13 end]) || \
        (":ResetSEQ" == [string range $pvName end-8 end])} {
        set ca($pvName) 0
        pv putq ca($pvName)
    }
}

append env(EPICS_CA_ADDR_LIST) " localhost"
set input ""
set debug 0
set args $argv

APSStandardSetup
if {[APSStrictParseArguments {input debug}]} {
    puts stderr "usage: sddspcasEquations -input <file1,file2,...>"
    exit 1
}
set input [split $input ,]
if {([llength $input] == 0)} {
    puts stderr "usage: sddspcasEquations -input <file1,file2,...>"
    exit 1
}

InitialSetup
UpdateValues ""

vwait forever





