#!/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)]
set CVSRevisionAuthor "\$Revision: 1.13 $ \$Author: soliday $"

APSApplication . -name "SRRFPhaseSliders" -version $CVSRevisionAuthor \
  -overview "Provides SR rf phase sliders that are automatically configured for the present operating mode. The mode may be changed in realtime and the sliders will still work."

set status "Ready."

# lists of PVs and corresponding tcl variables
set pvList {S6:WGS:modeSelect SRF:K1:PS1:Ch0 SRF:K2:PS1:Ch0 \
              SRF:K3:PS1:Ch0 SRF:K4:PS1:Ch0 BRF:S:PS1:Ch0_1AO}
set varList {WGSMode S1phase S2phase S3phase S4phase rfSBPhase}


if {[pv linkw $varList $pvList] || \
      [pv umon WGSMode ProcessWGSModeChange] || \
      [pv umon S1phase ProcessPhaseChange] || \
      [pv umon S2phase ProcessPhaseChange] || \
      [pv umon S3phase ProcessPhaseChange] || \
      [pv umon S4phase ProcessPhaseChange] || \
      [pv umon rfSBPhase ProcessPhaseChange] } {
    global errorCode
    APSAlertBox [APSUniqueName .] \
      -errorMessage "Unable to connect to $pvList: $errorCode"
    exit 1
}

proc ProcessPhaseChange {} {
    global varList
    eval global $varList rf3637Station rf40Station
    global rf3637Phase rf40Phase rfSBPhase
    foreach var $varList {
        set $var [subst \$$var]
    }
    set rf3637Phase [subst \$S${rf3637Station}phase]
    set rf40Phase [subst \$S${rf40Station}phase]
}

set LastWGSMode ""
proc ProcessWGSModeChange {} {
    global varList LastWGSMode status rf3637Station rf40Station
    eval global $varList
    set WGSMode $WGSMode
    if [string compare $LastWGSMode $WGSMode] {
        set LastWGSMode $WGSMode
        switch $WGSMode {
            "Mode 7" -
            "Mode 11" {
                set rf3637Station 2
                set rf40Station 4
                set status "Using K2 for 36/37 and K4 for 40"
            }
            "Mode 1" -
            "Mode 8" -
            "Mode 9" {
                set rf3637Station 2
                set rf40Station 1
                set status "Using K2 for 36/37 and K1 for 40"
            }
            "Mode 10" {
                set rf3637Station 3
                set rf40Station 4
                set status "Using K3 for 36/37 and K4 for 40"
            }
            "Mode 12" {
                set rf3637Station 3
                set rf40Station 1
                set status "Using K3 for 36/37 and K1 for 40"
            }
            default {
                APSAlertBox [APSUniqueName .] -errorMessage \
                  "Unknown rf mode: $WGSMode" 
                exit 1
            }
        }
    }
    ProcessPhaseChange
}

proc MovePhase {dir cavities} {
    global highLimits lowLimits
    if [lsearch -exact [list 3637 40] $cavities]!=-1 {
        global rf${cavities}Station varList rf${cavities}Increment
        eval global $varList
        set var S[subst \$rf${cavities}Station]phase
        set phase [subst \$S[subst \$rf${cavities}Station]phase]
        set delta [subst \$rf${cavities}Increment]
        set temp [expr $phase+$dir*$delta]
        if {($temp > $highLimits($var)) || ($temp < $lowLimits($var))} {
            APSSetVarAndUpdate status "Phase limit reached"
            bell
            return
        }
        set $var $temp
        if [pv putw $var] {
            global errorCode status
            set status $errorCode
            update
        }
        APSSetVarAndUpdate rf${cavities}Phase $temp
    } else {
        global rfSBIncrement rfSBPhase
        set temp [expr $rfSBPhase+$dir*$rfSBIncrement]
        if {($temp > $highLimits(rfSBPhase)) || ($temp < $lowLimits(rfSBPhase))} {
            APSSetVarAndUpdate status "Phase limit reached"
            bell
            return
        }
        set rfSBPhase $temp
        if [pv putw rfSBPhase] {
            global errorCode status
            set status $errorCode
            update
        }
    }
}

proc MakeRFSlider {widget args} {
    set parent ""
    set label ""
    set cavities ""
    set cavitiesLabel ""
    APSStrictParseArguments {parent label cavities cavitiesLabel}

    APSFrame $widget -parent $parent -label $label 
    
    set w $parent$widget.frame
    
    APSButton .down -parent $w -text "<-" -command "MovePhase -1 $cavities" \
      -contextHelp "Moves the phase for $label down by the increment." -fastClick 1
    APSButton .up -parent $w -text "->" -command "MovePhase 1 $cavities" \
      -contextHelp "Moves the phase for $label up by the increment." -fastClick 1
    global rf${cavities}Increment rf${cavities}Phase
    set rf${cavities}Increment 1
    set rf${cavities}Phase 0
    APSLabeledOutput .phase -parent $w -label " Phase: " \
      -textVariable rf${cavities}Phase -width 8 \
      -contextHelp "Shows the phase for $label"
    APSLabeledEntry .incr -parent $w -label "Phase increment: " \
      -textVariable rf${cavities}Increment -width 8 \
      -contextHelp "Sets the phase increment for $label"
}

proc getControlLimits {} {
    global varList lowLimits highLimits
    set lowList [pv info $varList drvl]
    set highList [pv info $varList drvh]
    foreach var $varList item $lowList item2 $highList {
        set lowLimits($var) [lindex $item 1]
        set highLimits($var) [lindex $item2 1]
    }
}

set status Working...

APSScrolledStatus .status -parent .userFrame -textVariable status \
  -width 50

APSLabeledOutput .wgsMode -parent .userFrame -label "Present rf mode: " \
  -contextHelp "The presently selected rf switch mode." -textVariable WGSMode

MakeRFSlider .sliderSB -parent .userFrame -label "SR/Booster" \
  -cavities SB
MakeRFSlider .slider3637 -parent .userFrame -label "S36/37" \
  -cavities 3637 
MakeRFSlider .slider40 -parent .userFrame -label "S40" \
  -cavities 40

getControlLimits

set status Ready.
update
ProcessWGSModeChange
ProcessPhaseChange
