#!/bin/sh
# \
exec oagwish "$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)]
APSDebugPath
set CVSRevisionAuthor "\$Author: soliday $"

proc DoIt {} {
    global operation devList value APSDevSendDebug useCavput deviceType
        
    set supportedDevList [APSDevSend -releaseLinks 0  -group $deviceType -operation $operation]
    set APSDevSendDebug 0

    set devToDo ""
    foreach dev $devList {
        global $dev
        if {[set $dev] && [lsearch -exact $supportedDevList $dev]!=-1} {
            lappend devToDo $dev
        }
    }
    if [llength $devToDo]==0 {
        return -code error "No such operation."
    }

    if [string match Set* $operation]==1 {
        APSDevSend -releaseLinks 0  -group $deviceType -operation $operation -deviceList $devToDo -value $value -timeout 10 -cavput $useCavput
    } elseif {[string match Turn* $operation] || [string match Stop* $operation] || \
                [string match Start* $operation]} {
        APSDevSend -releaseLinks 0  -group $deviceType -operation $operation -deviceList $devToDo -timeout 10 -cavput $useCavput
    } else {
        set resultList [APSDevSend -releaseLinks 0  -group $deviceType -operation $operation -deviceList $devToDo -timeout 30 -cavput $useCavput]
        set tmpFile /tmp/[APSTmpString]
        set fid [open $tmpFile w]
        foreach dev $devToDo result $resultList {
            puts $fid [format "%30s %s" $dev $result]
        }
        close $fid
        APSFileDisplayWindow [APSUniqueName .] \
          -fileName $tmpFile -deleteOnClose 1
    }
}

set args $argv
set beamline ""
APSStrictParseArguments {beamline}

if {$beamline == "par"} {
    set name "PAR PS Utility"
    set deviceType PSOps
    set deviceFile PSOps.pvTable
    set beamlineDir $beamline
} elseif {$beamline == "booster"} {
    set name "BTS PS Utility"
    set deviceType PSOps
    set deviceFile BTSOps.pvTable
    set beamlineDir $beamline
} elseif {$beamline == "leutl"} {
    set name "LEUTL PS Utility"
    set deviceType LTPToEndPSOps
    set deviceFile LTPToEndPSOps.pvTable
    set beamlineDir "linac"
} elseif {$beamline == "linac"} {
    set name "Linac PS Utility"
    set deviceType LinacPS
    set deviceFile PSOps.pvTable
    set beamlineDir $beamline
} elseif {$beamline == "interleaving"} {
    set name "Interleaving PS Utility"
    set deviceType LTPToEndPSOps
    set deviceFile LTPToEndPSOps.pvTable
    set beamlineDir "linac"
} else {
    puts "Usage: LinacPSUtil -beamline <beamline>\n\nValid beamlines include linac, leutl, par and booster\n"
    exit
}

APSApplication . -name $name \
  -overview "Allows executing ganged operations on power supplies."

set status ""
APSScrolledStatus .status -parent .userFrame -textVariable status -width 60

proc setStatus {text} {
    APSSetVarAndUpdate status $text
}

setStatus "Working..."
update

set apsPSDeviceFile /home/helios/oagData/deviceConfig/${beamlineDir}/$deviceFile

set devList [exec sddssort $apsPSDeviceFile -pipe=out -column=DeviceName -unique \
        | sdds2stream -pipe -column=DeviceName]
set opList [exec sddssort $apsPSDeviceFile -pipe=out -column=Operation -unique \
        | sdds2stream -pipe -column=Operation]

foreach dev $devList {
    set $dev 0
}
set quadList ""
set hcorrList ""
set vcorrList ""
set otherList ""
if {$beamline == "linac"} {
    foreach dev $devList {
	if [string match *QM* $dev] {
	    lappend quadList $dev
	} elseif [string match *HZ* $dev] {
	    lappend hcorrList $dev
	} elseif [string match *VL* $dev] {
	    lappend vcorrList $dev
	} else {
	    lappend otherList $dev
	}
    }
} elseif {($beamline == "par") || 
	  ($beamline == "booster") || 
	  ($beamline == "leutl")} {
    foreach dev $devList {
	if [string match *Q* $dev] {
	    lappend quadList $dev
	} elseif [string match *H* $dev] {
	    lappend hcorrList $dev
	} elseif [string match *V* $dev] {
	    lappend vcorrList $dev
	} else {
            if {([string range $dev 0 2] != "LTP") && ([string range $dev 0 2] != "PTB")} {
                lappend otherList $dev
            }
	}
    }
} elseif {($beamline == "interleaving")} {
    foreach dev $devList {
	if [string match *Q* $dev] {
#	    lappend quadList $dev
	} elseif [string match *H* $dev] {
#	    lappend hcorrList $dev
	} elseif [string match *V* $dev] {
#	    lappend vcorrList $dev
	} else {
            if {([string range $dev 0 2] == "LTP") || ([string range $dev 0 2] == "PTB")} {
                lappend otherList $dev
            }
	}
    }
}

foreach type {quad hcorr vcorr other} name {Quad HC VC Other} {
    if {($beamline == "interleaving") && ($name != "Other")} {
        continue
    }
    APSCheckButtonFrame .$type -parent .userFrame -label "$name devices" \
      -buttonList [set ${type}List] -variableList [set ${type}List] -orientation horizontal \
      -limitPerRow 8 -allNone 1
}

set operation [lindex $opList 0]
APSRadioButtonFrame .op -parent .userFrame -label "Operation" \
  -valueList $opList -buttonList $opList -variable operation -orientation horizontal \
  -limitPerRow 4

set value 0
APSLabeledEntry .value -parent .userFrame -label "Value (for set operations): " \
    -textVariable value

set useCavput 1
APSRadioButtonFrame .cavput -parent .userFrame -label "Use cavput" \
    -valueList {1 0} -buttonList {Yes No} -variable useCavput -orientation horizontal \
    -limitPerRow 4 -contextHelp \
    "You may use cavput for output operations.  Try this if you have problems controlling supplies."

APSButton .doIt -parent .userFrame -text "Do It" -command DoIt

if {[catch {APSLinkToDeviceConfigPVs -device $beamlineDir} result]} {
  puts "APSLinkToPARPVs: $result"
}

setStatus "Ready."
update
