
# **************************** APSMakeSConfigFrame *****************************
proc APSMakeSRConfigFrame {w args} {
    global sconfigreadfilename sconfigwritefilename scconfigopts
    
    if {[winfo exists $w]} {
        raise $w
        return
    }
    update
    toplevel $w
    wm title $w "SR Configuration File"
    
    # Set defaults if not already set
    if {![info exists sconfigreadfilename]} {
        if {[info exists corbitcfilename]} {
            set sconfigreadfilename $corbitcfilename
        } else {
            set sconfigreadfilename ""
        }
    }    
    if {![info exists sconfigwritefilename]} {
        if {[info exists corbitcfilename]} {
            set sconfigwritefilename $corbitcfilename
        } else {
            set sconfigwritefilename ""
        }
    }    
    if {![info exists sconfigopts]} {set scconfigopts replace}
    
    # Defaults
    if {![info exists sconfigwritefilename]} {set sconfigwritefilename .config}
    if {![info exists sconfigreadfilename]} {set sconfigreadfilename .config}
    
    # SR buttons
    APSMakeSRConfigButtons $w H V B
    
    if {([lsearch -exact $args read] != -1) && [file exists $sconfigreadfilename]} {
        APSReadSRConfigFile $sconfigreadfilename $scconfigopts
    }

    # Write frame
    APSFrame .writeframe -parent $w
    set frame $w.writeframe.frame
    
    APSButton .sconfigwritebutton -parent $frame \
      -text "Write Configuration File" \
      -command {APSWriteSRConfigFile $sconfigwritefilename} \
      -contextHelp "Writes a configuration\
       file for Corbit with the specified name. Only the\
       CorrectorNames and MonitorNames pages of the file will be\
       written, corresponding to the buttons checked or not\
       checked.  See the Corbit manual or the help for the\
       Replace, AND, Or buttons for more information on the logic\
       of configuration files."
    pack $frame.sconfigwritebutton -side left
    
    APSLabeledEntry .sconfigwritenameframe -parent $frame -label "File Name:" \
      -textVariable sconfigwritefilename -width 40 -contextHelp \
      "The name of the configuration file to be written."
    APSRepack $frame.sconfigwritenameframe -side right
    addfilebuttons $frame.sconfigwritenameframe \
      -variable sconfigwritefilename \
      -pattern *.config -checkValidity 0 -trim 1
    
    # Read frame
    APSFrame .readframe -parent $w
    set frame $w.readframe.frame
    
    set frame1 $frame.1
    frame $frame1
    pack $frame1
    
    APSButton .sconfigreadbutton -parent $frame1 \
      -text "Read Configuration File " \
      -command {APSReadSRConfigFile $sconfigreadfilename $scconfigopts} \
      -contextHelp "Reads a configuration\
       file for Corbit with the specified name.  This file will be used to\
       determine the monitors and correctors checked.  The current values\
       may be replaced, AND'ed, or OR'ed with the ones in the file.  The logic\
       is further described in the help for the buttons which choose these\
       options."
    pack $frame1.sconfigreadbutton -side left
    
    APSLabeledEntry .sconfigreadnameframe -parent $frame1 -label "File Name:" \
      -textVariable sconfigreadfilename -width 40 -contextHelp \
      "The name of the configuration file to be read."
    APSRepack $frame1.sconfigreadnameframe -side right
    addfilebuttons $frame1.sconfigreadnameframe -variable sconfigreadfilename \
      -pattern *.config -trim 1
    
    # Options frame
    set frame2 $frame.2
    frame $frame2
    pack $frame2
    
    APSRadioButtonFrame .sconfigoptsframe -parent $frame2 \
      -variable scconfigopts -orientation horizontal\
      -label "" -buttonList {Replace OR AND} \
      -valueList {replace or and} -contextHelp \
      "Determines how the corrector and monitor switches in the file\
       will be combined with the current ones.\n\nA full description of\
       the logic used for the configuration file is described in the\
       Corbit manual, which may be available under the main Help\
       menu.\n\nIf there\
       is a page in the configuration file with the parameter NameType\
       equal to CorrectorNames, then only\
       the names that are in the response matrix file and which are also\
       selected in that page will be used.  Otherwise, all the names in\
       the file will be selected.  For this dialog box, since\
       it is not known which names are in the response matrix file, it\
       will be assumed that they all are, except those for which the\
       corrector does not exist.\n\nAfter the names are selected in this way,\
       if there is a NotCorrectorNames page in the configuration file, then\
       the names selected in that page will be excluded.\n\nIt should be noted\
       that it is also possible, but not advised, to have parameters with the\
       names CorrectorNames, NotCorrectorNames, etc. in the response matrix\
       file.  These parameters have the same effect as the pages of the\
       same name in the configuration file.  They will be used only if they\
       exist and if there is no corresponding page in the configuration\
       file.\n\nThe situation is similar for monitors, and the pages have\
       the parameter NameType equal to MonitorNames or NotMonitorNames."
    APSRepack $frame2.sconfigoptsframe -side left

    # Description
    APSLabeledOutput .sdescriptionoutput -parent $frame2 -label "  Description:" \
      -textVariable sconfigdescription -width 48 -contextHelp \
      "The description of the last file read or written.  If the description\
       is longer than the box holds, it may be draggged sideways\
       with Button 2."
    APSRepack $frame2.sdescriptionoutput -side right    

    # Remove button
    APSButton .remove -parent $w -text Remove -command "destroy $w" \
      -contextHelp "Removes this dialog box."
    pack $w.remove -in $w -side top

    # Change labels
    update
    APSSetSConfigLabel H V B

}
# **************************** APSMakeSRConfigButtons ***************************
proc APSMakeSRConfigButtons {w args} {
    # The major frames in srbuttons will be packed in w
    global apsContextHelp
    global scorrlist smonlist
    global scorrDisableList smonDisableList
    global scconfigblabelw scconfighlabelw scconfigvlabelw
    
    set hflag ""
    set vflag ""
    set bflag ""
    set setdefaults 0
    
    # Make names if they don't exist
    if {![info exists scorrlist] || ![info exists smonlist]} {
        APSMakeSrBpmCorrList
    }
    # Make overall frame
    frame $w.frame
    pack $w.frame -side top
    set f $w.frame
    # BPM's
    if {[lsearch -exact $args B] != -1} {
        APSFrame .frameb -parent $f -label "Monitors" \
          -packOption "-side left"
        set scconfigblabelw $f.frameb.label
        set f1 $f.frameb.frame
        for {set n 0} {$n < 40} {incr n} {
            frame $f1.frameb${n}
            pack $f1.frameb${n} -side top
            label $f1.frameb${n}.label -text [format "%3d " [expr {$n+1}]] \
              -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
            pack $f1.frameb${n}.label -side left
            for {set m 0} {$m < 9} {incr m} {
                set i [expr {$n*9+$m}]
                set name [lindex $smonlist $i]
                set nameflag ${name}flag
                global $nameflag
                if {![info exists $nameflag]} {
                    set bflag B
                    set setdefaults 1
                }
                checkbutton $f1.s${name} -text "" -variable $nameflag \
                  -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
                  -command {APSSetSConfigLabel B}
                pack $f1.s${name} -in $f1.frameb${n} -side left
                set apsContextHelp($f1.s${name}) $name
                if {([info exists smonDisableList]) && ([lindex $smonDisableList $i] == 0)} {
                    $f1.s${name} configure -state disabled -cursor X_cursor
                }
            }
        }
        # Position toggle buttons
        frame $f1.framebtog
        pack $f1.framebtog -side top
        label $f1.framebtog.label -text "All " \
          -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
        pack $f1.framebtog.label -side left
        for {set m 0} {$m < 9} {incr m} {
            global sbtog${m}
            if {![info exists sbtog${m}]} {set sbtog${m} 0}
            checkbutton $f1.sbtog${m} -text "" -variable sbtog${m} \
              -command "APSToggleSRButtonsFlags $f1.sbtog${m} $m B" \
              -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
            pack $f1.sbtog${m} -in $f1.framebtog -side left
            set apsContextHelp($f1.sbtog${m}) \
              "Toggles all monitors in this position in the sector\
               on or off."
        }
        # Global buttons
        set f2 $f1.framebuttonsb
        frame $f2
        pack $f2 -side top
        APSButton .missingb -parent $f2 -text "Missing" \
          -command "APSSetSRNonexist" -contextHelp \
          "Sets all nonexistent monitors and correctors off.  Most \
           procedures do not turn nonexistent monitors and correctors \
           on in the first place, but you can turn them on by pushing \
           the individual buttons."
        APSRepack $f2.missingb -side left -padx 5 -pady 5 -fill both
        APSButton .allonb -parent $f2 -text "All On" \
          -command "APSSetSRButtonsFlags 1 B" -contextHelp \
          "Sets all monitor buttons on."
        APSRepack $f2.allonb -side left -padx 5 -pady 5 -fill both
        APSButton .alloffb -parent $f2 -text "All Off" \
          -command "APSSetSRButtonsFlags 0 B" -contextHelp \
          "Sets all monitor buttons off."
        APSRepack $f2.alloffb  -side left -padx 5 -pady 5 -fill both
    }
    
    # Horizontal
    if {[lsearch -exact $args H] != -1} {
        APSFrame .frameh -parent $f -label "H Correctors" \
          -packOption "-side left"
        set scconfighlabelw $f.frameh.label
        set f1 $f.frameh.frame
        for {set n 0} {$n < 40} {incr n} {
            frame $f1.frameh${n}
            pack $f1.frameh${n} -side top
            label $f1.frameh${n}.label -text [format "%3d " [expr {$n+1}]] \
              -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
            pack $f1.frameh${n}.label -side left
            for {set m 0} {$m < 8} {incr m} {
                set i [expr {$n*8+$m}]
                set name [lindex $scorrlist $i]
                set nameflag ${name}flag
                global $nameflag
                if {![info exists $nameflag]} {
                    set hflag H
                    set setdefaults 1
                }
                checkbutton $f1.s${name} -text "" -variable $nameflag \
                  -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
                  -command {APSSetSConfigLabel H}
                pack $f1.s${name} -in $f1.frameh${n} -side left
                set apsContextHelp($f1.s${name}) $name
                set $nameflag 0
                if {([info exists scorrDisableList]) && ([lindex $scorrDisableList $i] == 0)} {
                    $f1.s${name} configure -state disabled -cursor X_cursor
                }
            }
        }
        # Position toggle buttons
        frame $f1.framehtog
        pack $f1.framehtog -side top
        label $f1.framehtog.label -text "All " \
          -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
        pack $f1.framehtog.label -side left
        for {set m 0} {$m < 8} {incr m} {
            global shtog${m}
            if {![info exists shtog${m}]} {set shtog${m} 0}
            checkbutton $f1.shtog${m} -text "" -variable shtog${m} \
              -command "APSToggleSRButtonsFlags $f1.shtog${m} $m H" \
              -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
            pack $f1.shtog${m} -in $f1.framehtog -side left
            set apsContextHelp($f1.shtog${m}) \
              "Toggles all horizontal correctors in this position in the sector\
               on or off."
        }
        # Global buttons
        set f2 $f1.framebuttonsh
        frame $f2
        pack $f2 -side top
        APSButton .missingh -parent $f2 -text "Missing" \
          -command "APSSetSRNonexist" -contextHelp \
          "Sets all nonexistent monitors and correctors off.  Most \
           procedures do not turn nonexistent monitors and correctors \
           on in the first place, but you can turn them on by pushing \
           the individual buttons."
        APSRepack $f2.missingh -side left -padx 5 -pady 5 -fill both
        APSButton .allonh -parent $f2 -text "All On" \
          -command "APSSetSRButtonsFlags 1 H" -contextHelp \
          "Sets all horizontal corrector buttons on."
        APSRepack $f2.allonh -side left -padx 5 -pady 5 -fill both
        APSButton .alloffh -parent $f2 -text "All Off" \
          -command "APSSetSRButtonsFlags 0 H" -contextHelp \
          "Sets all horizontal corrector buttons off."
        APSRepack $f2.alloffh  -side left -padx 5 -pady 5 -fill both
    }
    
    # Vertical
    if {[lsearch -exact $args V] != -1} {
        APSFrame .framev -parent $f -label "V Correctors" \
          -packOption "-side left"
        set scconfigvlabelw $f.framev.label
        set f1 $f.framev.frame
        for {set n 0} {$n < 40} {incr n} {
            frame $f1.framev${n}
            pack $f1.framev${n} -side top
            label $f1.framev${n}.label -text [format "%3d " [expr {$n+1}]] \
              -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
            pack $f1.framev${n}.label -side left
            for {set m 0} {$m < 8} {incr m} {
                set i [expr {320+$n*8+$m}]
                set name [lindex $scorrlist $i]
                set nameflag ${name}flag
                global $nameflag
                if {![info exists $nameflag]} {
                    set vflag V
                    set setdefaults 1
                }
                checkbutton $f1.s${name} -text "" -variable $nameflag \
                  -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
                  -command {APSSetSConfigLabel V}
                pack $f1.s${name} -in $f1.framev${n} -side left
                set apsContextHelp($f1.s${name}) $name
                if {([info exists scorrDisableList]) && ([lindex $scorrDisableList $i] == 0)} {
                    $f1.s${name} configure -state disabled -cursor X_cursor
                }
            }
        }
        # Position toggle buttons
        frame $f1.framevtog
        pack $f1.framevtog -side top
        label $f1.framevtog.label -text "All " \
          -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
        pack $f1.framevtog.label -side left
        for {set m 0} {$m < 8} {incr m} {
            global svtog${m}
            if {![info exists svtog${m}]} {set svtog${m} 0}
            checkbutton $f1.svtog${m} -text "" -variable svtog${m} \
              -command "APSToggleSRButtonsFlags $f1.svtog${m} $m V" \
              -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
            pack $f1.svtog${m} -in $f1.framevtog -side left
            set apsContextHelp($f1.svtog${m}) \
              "Toggles all vertical correctors in this position in the sector\
               on or off."
        }
        # Global buttons
        set f2 $f1.framebuttonsv
        frame $f2
        pack $f2 -side top
        APSButton .missingv -parent $f2 -text "Missing" \
          -command "APSSetSRNonexist" -contextHelp \
          "Sets all nonexistent monitors and correctors off.  Most \
           procedures do not turn nonexistent monitors and correctors \
           on in the first place, but you can turn them on by pushing \
           the individual buttons."
        APSRepack $f2.missingv -side left -padx 5 -pady 5 -fill both
        APSButton .allonv -parent $f2 -text "All On" \
          -command "APSSetSRButtonsFlags 1 V" -contextHelp \
          "Sets all vertical corrector buttons on."
        APSRepack $f2.allonv -side left -padx 5 -pady 5 -fill both
        APSButton .alloffv -parent $f2 -text "All Off" \
          -command "APSSetSRButtonsFlags 0 V" -contextHelp \
          "Sets all vertical corrector buttons off."
        APSRepack $f2.alloffv  -side left -padx 5 -pady 5 -fill both
    }
    # Defaults
    if {$setdefaults} {APSSetSRButtonsDefaults $hflag $vflag $bflag}
}
# **************************** APSMakeSrBpmCorrList ***********************
proc APSMakeSrBpmCorrList {} {
    global scorrlist smonlist

    if {![info exists scorrlist]} {
        set scorrlist {}
        for {set i 1} {$i <= 40} {incr i} {
            lappend scorrlist \
              S${i}A:H1 S${i}A:H2 S${i}A:H3 S${i}A:H4 \
              S${i}B:H4 S${i}B:H3 S${i}B:H2 S${i}B:H1
        }
        for {set i 1} {$i <= 40} {incr i} {
            lappend scorrlist \
              S${i}A:V1 S${i}A:V2 S${i}A:V3 S${i}A:V4 \
              S${i}B:V4 S${i}B:V3 S${i}B:V2 S${i}B:V1
        }
    }
    if {![info exists smonlist]} {
        set smonlist {}
        for {set i 1} {$i <= 40} {incr i} {
            lappend smonlist \
              S${i}A:P1 S${i}A:P2 S${i}A:P3 S${i}A:P4 \
              S${i}B:P5 S${i}B:P4 S${i}B:P3 S${i}B:P2 S${i}B:P1
        }
    }
}
# **************************** APSReadSRConfigFile *************************
proc APSReadSRConfigFile {filename options} {
    global scorrlist smonlist sconfigdescription

    # Check file
    if {![file exists $filename]} {
	APSErrorDialog .acerror -errorMessage "Does not exist:\n  $filename" -unique 1
        return
    }
    # Get description
    catch {APSGetSDDSParameter -fileName $filename -page 1 \
             -parameter Description} parm
    if {[string length $parm] > 0} {
        set sconfigdescription $parm
    } else {
        set sconfigdescription "No description"
    }
    # Do included names first
    set monitorsfound 0
    set correctorsfound 0
    for {set i 1} { $i < 5} {incr i} {
        catch {APSGetSDDSParameter -fileName $filename -page $i \
                 -parameter NameType} parm
        if {[string length $parm] == 0} {
            break     ;# No more pages
        } elseif {![string compare $parm MonitorNames]} {
            set monitorsfound 1
        } elseif {![string compare $parm NotMonitorNames]} {
            continue
        } elseif {![string compare $parm CorrectorNames]} {
            set correctorsfound 1
        } elseif {![string compare $parm NotCorrectorNames]} {
            continue
        }
        # Loop over names
        set names [APSGetSDDSColumn -fileName $filename -column Name \
                     -page $i]
        set flags [APSGetSDDSColumn -fileName $filename -column Flag \
                     -page $i]
        set len [llength $names]
        for {set j 0} {$j < $len} {incr j} {
            set flag [lindex $flags $j]
            if {!$flag} continue
            set name [lindex $names $j]
            set nameflag0 ${name}flag0
            set $nameflag0 1
        }
    }
    # Set global monitor flags based on local flags that exist
    if {$monitorsfound} {
        for {set i 0} {$i < 360} {incr i} {
            set name [lindex $smonlist $i]
            set nameflag0 ${name}flag0
            set nameflag ${name}flag
            global $nameflag
            if {[info exists $nameflag0]} {
                switch -exact $options {
                    {or} {
                        set $nameflag [expr {[set $nameflag] | [set $nameflag0]}]
                    }
                    {and} {
                        set $nameflag [expr {[set $nameflag] & [set $nameflag0]}]
                    }
                    {default} {
                        set $nameflag [set $nameflag0]
                    }
                }
            } else {
                switch -exact $options {
                    {or} {
                    }
                    {and} {
                        set $nameflag 0
                    }
                    {default} {
                        set $nameflag 0
                    }
                }
            }
        }
    }
    # Set global corrector flags based on local flags that exist
    if {$correctorsfound} {
        for {set i 0} {$i < 640} {incr i} {
            set name [lindex $scorrlist $i]
            set nameflag0 ${name}flag0
            set nameflag ${name}flag
            global $nameflag
            if {![info exists $nameflag]} continue
            if {[info exists $nameflag0]} {
                switch -exact $options {
                    {or} {
                        set $nameflag [expr {[set $nameflag] | [set $nameflag0]}]
                    }
                    {and} {
                        set $nameflag [expr {[set $nameflag] & [set $nameflag0]}]
                    }
                    {default} {
                        set $nameflag [set $nameflag0]
                    }
                }
            } else {
                switch -exact $options {
                    {or} {
                    }
                    {and} {
                        set $nameflag 0
                    }
                    {default} {
                        set $nameflag 0
                    }
                }
            }
        }
    }
    # Do excluded names last
    for {set i 1} { $i < 5} {incr i} {
        catch {APSGetSDDSParameter -fileName $filename -page $i \
                 -parameter NameType} parm
        if {[string length $parm] == 0} {
            break     ;# No more pages
        } elseif {![string compare $parm MonitorNames]} {
            continue
        } elseif {![string compare $parm CorrectorNames]} {
            continue
        }
        # Loop over names
        set names [APSGetSDDSColumn -fileName $filename -column Name \
                     -page $i]
        set flags [APSGetSDDSColumn -fileName $filename -column Flag \
                     -page $i]
        set len [llength $names]
        for {set j 0} {$j < $len} {incr j} {
            set flag [lindex $flags $j]
            if {!$flag} continue
            set name [lindex $names $j]
            set nameflag ${name}flag
            global $nameflag
            if {![info exists $nameflag]} continue
            switch -exact $options {
                {or} {
                    set $nameflag [expr {[set $nameflag] | 0}]
                }
                {and} {
                    set $nameflag 0
                }
                {default} {
                    set $nameflag 0
                }
            }
        }
    }
    # Turn off non-existent ones
    APSSetSRNonexist
    # Change labels
    #    setsconfiglabel H V B
}
# **************************** APSetSConfigLabel *************************
proc APSSetSConfigLabel {args} {
    global scorrlist smonlist
    global scconfigblabelw scconfighlabelw scconfigvlabelw

    # Horizontal
    if {[lsearch -exact $args H] != -1} {
        set count 0
        for {set i 0} {$i < 320} {incr i} {
            set name [lindex $scorrlist $i]
            set nameflag ${name}flag
            global $nameflag
            if {[info exists nameflag]} {
                if {[set $nameflag]} {incr count}
            }
        }
        $scconfighlabelw config -text "H Correctors ($count)"
    }
    # Vertical
    if {[lsearch -exact $args V] != -1} {
        set count 0
        for {set i 320} {$i < 640} {incr i} {
            set name [lindex $scorrlist $i]
            set nameflag ${name}flag
            global $nameflag
            if {[info exists nameflag]} {
                if {[set $nameflag]} {incr count}
            }
        }
        $scconfigvlabelw config -text "V Correctors ($count)"
    }
    # BPM's
    if {[lsearch -exact $args B] != -1} {
        set count 0
        for {set i 0} {$i < 360} {incr i} {
            set name [lindex $smonlist $i]
            set nameflag ${name}flag
            global $nameflag
            if {[info exists nameflag]} {
                if {[set $nameflag]} {incr count}
            }
        }
        $scconfigblabelw config -text "Monitors ($count)"
    }
}
# **************************** APSSetSRNonexist ***************************
proc APSSetSRNonexist {} {
    global sbpmcorrnonexist

    set sbpmcorrnonexist [list \
                            S1A:H3 \
                            S1A:V3 \
                            S39B:H1 \
                            S39B:V1 \
                            S40A:H3 \
                            S40A:V3 \
                           ]

    # Set nonexistent ones to zero
    foreach name $sbpmcorrnonexist {
        set nameflag ${name}flag
        global $nameflag
        set $nameflag 0
    }
}
# **************************** APSSetSRButtonsDefaults ********************
proc APSSetSRButtonsDefaults {args} {
    global scorrlist smonlist
    global scorrDisableList smonDisableList

    # Make names if they don't exist
    if {![info exists scorrlist] || ![info exists smonlist]} {
        APSMakeSrBpmCorrList
    }
    # Horizontal
    if {[lsearch -exact $args H] != -1} {
        for {set i 0} {$i < 320} {incr i} {
            if {([info exists scorrDisableList]) && ([lindex $scorrDisableList $i] != 0)} {
                set name [lindex $scorrlist $i]
                set nameflag ${name}flag
                global $nameflag
                set $nameflag 1
            }
        }
    }
    # Vertical
    if {[lsearch -exact $args V] != -1} {
        for {set i 320} {$i < 640} {incr i} {
            if {([info exists scorrDisableList]) && ([lindex $scorrDisableList $i] != 0)} {
                set name [lindex $scorrlist $i]
                set nameflag ${name}flag
                global $nameflag
                set $nameflag 1
            }
        }
    }
    # BPM's
    if {[lsearch -exact $args B] != -1} {
        for {set i 0} {$i < 360} {incr i} {
            if {([info exists smonDisableList]) && ([lindex $smonDisableList $i] != 0)} {
                set name [lindex $smonlist $i]
                set nameflag ${name}flag
                global $nameflag
                set $nameflag 1
            }
        }
    }
    # Turn off non-existent ones
    APSSetSRNonexist
}
# **************************** APSSetSRButtonsFlags ***********************
proc APSSetSRButtonsFlags {val args} {
    global scorrlist smonlist

    # Make names if they don't exist
    if {![info exists scorrlist] || ![info exists smonlist]} {
        APSMakeSrBpmCorrList
    }
    # Horizontal
    if {[lsearch -exact $args H] != -1} {
        for {set i 0} {$i < 320} {incr i} {
            set name [lindex $scorrlist $i]
            set nameflag ${name}flag
            global $nameflag
            set $nameflag $val
        }
    }
    # Vertical
    if {[lsearch -exact $args V] != -1} {
        for {set i 320} {$i < 640} {incr i} {
            set name [lindex $scorrlist $i]
            set nameflag ${name}flag
            global $nameflag
            set $nameflag $val
        }
    }
    # BPM's
    if {[lsearch -exact $args B] != -1} {
        for {set i 0} {$i < 360} {incr i} {
            set name [lindex $smonlist $i]
            set nameflag ${name}flag
            global $nameflag
            set $nameflag $val
        }
    }
    # Turn off non-existent ones
    APSSetSRNonexist
    # Change labels
    APSSetSConfigLabel $args
}
# **************************** APSToggleSRButtonsFlags ********************
proc APSToggleSRButtonsFlags {w position args} {
    global scorrlist smonlist
    global scorrDisableList

    # Make names if they don't exist
    if {![info exists scorrlist] || ![info exists smonlist]} {
        APSMakeSrBpmCorrList
    }
    # Horizontal
    if {[lsearch -exact $args H] != -1} {
        for {set i $position} {$i < 320} {incr i 8} {
            set name [lindex $scorrlist $i]
            set nameflag ${name}flag
            global $nameflag
            global shtog${position}
            if {![info exists scorrDisableList] || ([lindex $scorrDisableList $i] != 0)} {
                set $nameflag [set shtog${position}]
            }
        }
    }
    # Vertical
    if {[lsearch -exact $args V] != -1} {
        for {set i [expr {320+$position}]} {$i < 640} {incr i 8} {
            set name [lindex $scorrlist $i]
            set nameflag ${name}flag
            global $nameflag
            global svtog${position}
            set $nameflag [set svtog${position}]
        }
    }
    # BPM's
    if {[lsearch -exact $args B] != -1} {
        for {set i $position} {$i < 360} {incr i 9} {
            set name [lindex $smonlist $i]
            set nameflag ${name}flag
            global $nameflag
            global sbtog${position}
            set $nameflag [set sbtog${position}]
        }
    }
    # Turn off non-existent ones
    APSSetSRNonexist
    # Change labels
    APSSetSConfigLabel $args
}
# **************************** APSWriteSRConfigFile ************************
proc APSWriteSRConfigFile {filename args} {
    global sconfigreadfilename sconfigwritefilename
    global scorrlist smonlist sconfigdescription
    global apsInfoDialogInput apsInfoDialogChoice

    # Check if file exists
    if {[file exists $sconfigwritefilename]} {
        set result \
          [tk_dialog .savewarn \
             "Warning" "File $sconfigwritefilename exists.\nOK to reuse?" \
             warning 0 OK Abort]
        if {$result != 0} {return}
    }
    # Prompt for description
    set apsInfoDialogInput ""
    set apsInfoDialogChoice ""
    set desc [APSInfoDialog .descinfo -name "Description" -width 65 \
                -infoMessage "Enter a description of the configuration"]
    if {![string compare $apsInfoDialogChoice CANCEL]} return
    set sconfigdescription $desc
    # Open file
    set file [open $filename w]
    # Header
    puts $file "SDDS1"
    puts $file "&description text=\"SR Correction Program Configuration File\""
    puts $file "  contents=\"SR Correction Program Configuration File\" &end"
    puts $file "&parameter name=Description type=string fixed_value=\"$desc\" &end"
    puts $file "&parameter name=NameType type=string &end"
    puts $file "&column name=Name type=string &end"
    puts $file "&column name=Flag type=short &end"
    puts $file "&data mode=ascii no_row_counts=1 additional_header_lines=1 &end"
    # Correctors
    puts $file ""
    puts $file "CorrectorNames"
    set len [llength $scorrlist]
    for {set i 0} {$i < $len} {incr i} {
        set name [lindex $scorrlist $i]
        set nameflag ${name}flag
        global $nameflag
        if {[set $nameflag]} {
            puts $file "$name 1"
        } else {
            puts $file "$name 0"
        }
    }
    # BPM's
    puts $file ""
    puts $file "MonitorNames"
    set len [llength $smonlist]
    for {set i 0} {$i < $len} {incr i} {
        set name [lindex $smonlist $i]
        set nameflag ${name}flag
        global $nameflag
        if {[set $nameflag]} {
            puts $file "$name 1"
        } else {
            puts $file "$name 0"
        }
    }
    # Close file
    close $file
    # Set variable for scorr
    global scconfigwritten
    set scconfigwritten 1
}


