#!/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.28 $ \$Author: soliday $"
set apsttk 1

APSApplication . -name SR-DCPS -version $CVSRevisionAuthor \
  -overview "SR-DCPS provides convenience controls for storage ring DC power supply convertors." 

if {$apsUpgrade} {
    set DcpsStatus "Ready..."
} else {
    set DcpsStatus "NOTE: This application is no longer used for general PS startup and\n"
    append DcpsStatus "conditioning.  Use the PEM procedure unless you have a specific reason not to."
}
APSScrolledStatus .status -parent .userFrame -width 80 -packOption "-fill both -expand true" \
  -textVariable DcpsStatus 

proc SetDcpsStatus {text} {
    global DcpsStatus
    set DcpsStatus $text
    update
    #    bell
}

proc MakeActionWidget {widget args} {
    global apsUpgrade
    set parent ""
    APSParseArguments {parent}
    set w $parent$widget
    frame $w -bd 4 -relief raised
    pack $w -side top -fill x 

    APSButton .execute -width "" -text EXECUTE \
      -command "ExecuteSrDcpsCommands ; APSDisableButton $w.execute.button" \
      -parent $w \
      -contextHelp "Executes the command configured by the various settings.  It must be enabled by the ENABLE button and may be disabled by the DISABLE button"
    APSDisableButton $w.execute.button
    APSButton .enableExec -width "" -text ENABLE -command "APSEnableButton $w.execute.button" -parent $w \
      -contextHelp "Enables the EXECUTE button."
    APSButton .disableExec -width "" -text DISABLE -command "APSDisableButton $w.execute.button" -parent $w \
      -contextHelp "Disables the EXECUTE button."
    if {!$apsUpgrade} {
        APSButton .slowturnon -width "" -text "SLOW TURN ON..." -command "exec SRSlowSectorTurnOn &" \
          -parent $w -contextHelp "Invokes a utility for slow turn on of Q, S, H, and V magnets.  Use only if you have trouble turning power supplies on the normal way."
    }
}

set currentlyRunning 0
proc ExecuteSrDcpsCommands {} {
    global SetValue ConfigFile CommandChoice apsUpgrade
    global SectorSelection DcpsSelection FamilyName currentlyRunning
    if {$CommandChoice==""} {
        SetDcpsStatus "You must select one of the command choices before pressing EXECUTE"
        return
    }
    set sectors [MakeSectorList [array get SectorSelection]]
    if {$CommandChoice=="configure" && $ConfigFile==""} {
        SetDcpsStatus "Configuration file must be given."
        return 
    }
    if {$currentlyRunning} {
        SetDcpsStatus "Please wait for current operation to finish."
        return 
    }
    if {$apsUpgrade} {
        set families ""
        foreach selection [lsort [array names DcpsSelection]] {
            if {$DcpsSelection($selection)} {
                lappend families $FamilyName($selection)
            }
        }
        if {[llength $families]} {
            set currentlyRunning 1
            SetDcpsStatus "Starting action=$CommandChoice for: [join $families ", "]"
            if [catch {APSUSrDcpsAction -families $families \
                         -action $CommandChoice \
                         -value $SetValue \
                         -sectors $sectors \
                         -configFile $ConfigFile \
                         -statusCallback SetDcpsStatus} result] {
                SetDcpsStatus "Error: $result"
                set currentlyRunning 0
            } else {
                if {$result != ""} {
                    SetDcpsStatus "$result"
                }
                if {($CommandChoice == "on") || ($CommandChoice == "off")} {
                    APSWaitWithUpdate -waitSeconds 5
                }
                SetDcpsStatus "Done with action=$CommandChoice for: [join $families ", "]"
                set currentlyRunning 0
            }
            
        }
    } else {
        foreach selection [array names DcpsSelection] {
            if {!$DcpsSelection($selection)} { continue }
            SetDcpsStatus "Working on $FamilyName($selection)"
            if {$FamilyName($selection)!="BM" && $sectors==""} {
                SetDcpsStatus "You must select one or more sectors for family $FamilyName($selection)"
                return
            }
            if {[string compare $CommandChoice "on"]!=0} {
                set pause 10
            } else {
                set pause 250
            }
            if [catch {APSSrDcpsAction -family $FamilyName($selection) -action $CommandChoice \
                         -value $SetValue -sectors $sectors -pause $pause \
                         -configFile $ConfigFile -statusCallback SetDcpsStatus} result] {
                SetDcpsStatus "Error: $result"
            } else {
                SetDcpsStatus "Done with $selection."
            }
        }
        SetDcpsStatus "Ok."
    }
}


proc MakeCommandChoiceWidget {widget args} {
    global SetValue ConfigFile CommandChoice apsUpgrade
    set parent ""
    APSParseArguments {parent}
    
    set CommandChoice ""

    set w $parent$widget
    frame $w -bd 4 -relief raised
    pack $w -side top -fill x

    label $w.title -text "DC Power Supply Commands" -relief ridge
    pack $w.title -side top -fill x
    
    frame $w.cb
    pack $w.cb -side top -fill x
    radiobutton $w.cb.on -value on -variable CommandChoice -relief ridge -text ON
    radiobutton $w.cb.off -value off -variable CommandChoice -relief ridge -text OFF
    radiobutton $w.cb.set -value set -variable CommandChoice -relief ridge -text SET
    if {!$apsUpgrade} {
        radiobutton $w.cb.settol -value setTol -variable CommandChoice -relief ridge -text "SET TOLER."
    }
    radiobutton $w.cb.config -value configure -variable CommandChoice -relief ridge -text CONFIGURE
    radiobutton $w.cb.cond -value forcecondition -variable CommandChoice -relief ridge -text CONDITION
    #    radiobutton $w.cb.cond -value condition -variable CommandChoice -relief ridge -text CONDITION
    radiobutton $w.cb.stopcond -value stopcond -variable CommandChoice -relief ridge -text "STOP COND."
    radiobutton $w.cb.listcond -value listcond -variable CommandChoice -relief ridge -text "LIST COND."
    radiobutton $w.cb.cycle -value setcycles -variable CommandChoice -relief ridge -text "SET CYCLES"
    if {$apsUpgrade} {
        radiobutton $w.cb.validate -value validateconnections -variable CommandChoice -relief ridge -text "VALIDATE CONNECTIONS"
        pack $w.cb.on $w.cb.off $w.cb.set $w.cb.config $w.cb.cond $w.cb.stopcond $w.cb.listcond $w.cb.cycle $w.cb.validate \
          -side left -fill x 
    } else {
        pack $w.cb.on $w.cb.off $w.cb.set $w.cb.settol $w.cb.config $w.cb.cond $w.cb.stopcond $w.cb.listcond $w.cb.cycle \
          -side left -fill x 
    }

    set SetValue 0
    if {$apsUpgrade} {
        set ConfigFile "/home/helios/oagData/sr/magnetConditioning/standardize.config"
    } else {
        set ConfigFile "/home/helios/oagData/sr/magnetConditioning/template.std"
    }
    frame $w.entries
    pack $w.entries -side top
    APSLabeledEntry .val -parent $w.entries -label "Value: " -textVariable SetValue -width 60 \
      -contextHelp "A setpoint value that will be sent to all selected power supplies if the SET or SET TOLER. command is used."
    APSLabeledEntry .cfile -parent $w.entries -label "Config file: " -textVariable ConfigFile -width 60 \
      -contextHelp "Select the correct file that will be used for the CONFIGURE command."
    APSButton .cfileChoose -parent $w.entries -width "" -command ChooseConfigFile  \
      -text "PICK FILE..." \
      -contextHelp "Use to bring up a file selection dialog to specify the file to be used for the CONFIGURE command."
    APSButton .cfiledef1 -parent $w.entries -width "" -text "STANDARDIZE DEFAULT" \
      -command "SetConfigFileDefault -type standardize" \
      -contextHelp "Sets the config file to the default one for standardization of the quads and sextupoles.  Also changes the power supply family selection."
    if {!$apsUpgrade} {
        APSButton .cfiledef3 -parent $w.entries -width "" -text "DIPOLE DEFAULT" \
          -command "SetConfigFileDefault -type dipole" \
          -contextHelp "Sets the config file to the default one for standardization of the dipole.  Also changes the power supply family selection."
    }
    APSButton .cfiledef2 -parent $w.entries -width "" -text "DEGAUSS DEFAULT" \
      -command "SetConfigFileDefault -type degauss" \
      -contextHelp "Sets the config file to the default one for degaussing.  Also changes the power supply family selection."
    if {!$apsUpgrade} {
        APSButton .reviewCycl -parent $w.entries -width "" -text "REVIEW CYCLES" -command ReviewCycles \
          -contextHelp "Use to review a number of cycles set for chosen magnet(s)."
    }
}

proc ReviewCycles {} {
    global command FamilyName DcpsSelection SectorSelection
    set command ""
    set sectors [MakeSectorList [array get SectorSelection]]
    if ![llength $sectors] {
        SetDcpsStatus "No sectors chosen"
        return
    }
    set families 0
    foreach fname [array names FamilyName] {
        set command [list exec cavget -pend=30]
        if $DcpsSelection($fname) {
            if {[string compare $FamilyName($fname) QS] == 0 || [string compare $FamilyName($fname) BM] == 0} {
                continue
            } else {
                lappend command -list=S
            }
            set sectorsList $sectors
            if {([string compare $FamilyName($fname) "C:BM"] == 0) || 
                ([string compare $FamilyName($fname) "C:H"] == 0) || 
                ([string compare $FamilyName($fname) "C:V"] == 0)} {
                if {[catch {exec sdds2stream \
                              -col=Sector,CUflag,CUdipoleExists /home/helios/oagData/sr/XAXSTF/sectors.sdds} results]} {
                    SetDcpsStatus "Error in ReviewCycles: $results"
                } else {
                    set sectorsList ""
                    foreach "sector flag bmFlag" $results {
                        if {([string compare $FamilyName($fname) "C:BM"] == 0) && ($bmFlag == 0)} {
                            continue
                        }
                        if {$flag} {
                            if {[lsearch -exact $sectors $sector] != -1} {
                                lappend sectorsList $sector
                            }
                        }
                    }
                    if {![llength $sectorsList]} {
                        SetDcpsStatus "No sectors for $FamilyName($fname)"
                        continue
                    }
                }
            }

            if [catch {MakeReviewCyclesList -family $FamilyName($fname) -sectors $sectorsList} result] {
                SetDcpsStatus "Error in ReviewCycles: $result"
            } else {
                eval lappend command $result
            }
            lappend command -label {-delim= } 

            incr families
            if [catch $command CValues] {
                SetDcpsStatus $CValues 
                continue
            } else {
                if [llength $CValues] {
                    set itemList ""
                    array set cycleArray $CValues
                    foreach name [array names cycleArray] {
                        lappend itemList $name=$cycleArray($name)
                    }
                    if {[llength $itemList] > 1} {
                        set itemList [SortList -sortList $itemList]
                    }
                    APSScrolledListWindow [APSUniqueName .scrList] \
                      -name "$fname Cycles Settings" -itemList $itemList -acceptButton 0 
                }
            }
        }
    }
    if !$families {
        SetDcpsStatus "No families chosen"
    }
}

proc SortList {args} {
    set sortList ""
    APSStrictParseArguments {sortList}
    set midstepList ""
    set finalsortList ""
    
    foreach name $sortList {
        set newName [string trimleft $name S]
        if {[string first A $newName] == 1 || [string first B $newName] == 1 \
              || [string first S $newName] == 1} {
            set newName 0$newName
        }
      	lappend midstepList $newName
    }
    set midstepList [lsort -increasing $midstepList]
    foreach midName $midstepList {
        if {[string index $midName 0] == 0} {
            set midName [string trimleft $midName 0]
        }
        lappend finalsortList S$midName
    }
    if [llength $finalsortList] {
        return $finalsortList
    }
}

#No longer used for APSU
proc MakeReviewCyclesList {args} {
    set family ""
    set sectors ""
    APSStrictParseArguments {family sectors}  
    global apsSrSkewName
    set lists ""

    if {[string compare $family QS] != 0} {
        lappend lists -list=[join $sectors ,]
    }

    switch $family {
        "QS" {
            set QSString
            set QSList ""
            APSMakeSrSkewNames
            foreach sec $sector {
                lappend QSList $apsSrSkewName($sec)
            }
            set QSString [join QSList ,]
            set lists -list=$QSString
        }
        "BM" { 
            set lists -list=S:BM
        }
        "C:BM"  { 
            lappend lists -list=C:BM -pend=10
        }
        "Q"  { 
            lappend lists -list=A:Q,B:Q -range=begin=1,end=5
        }
        "V"  { 
            lappend lists -list=A:V,B:V -range=begin=1,end=4
        }
        "H"  {
            lappend lists -list=A:H,B:H -range=begin=1,end=4
        }
        "C:V"  { 
            lappend lists -list=C:V1 -pend=10
        }
        "C:H"  {
            lappend lists -list=C:H1 -pend=10
        }
        "S"  { 
            lappend lists -list=A:S1,A:S2,A:S3,A:S4,B:S3,B:S2,B:S1
        }
        "MT" { 
            lappend lists -list=A:MT,B:MT
        }
        "QS4" { 
            lappend lists -list=A:QS4
        }
        default { 
            return -code error  "ReviewCycles: Invalid family $family."  
        }
    }
    if [string length $lists] {
        lappend lists -list=:StandardizeSUB.F
        return $lists
    } else {
        return -code error "Error in ProcessingForReviewCycles"
    }
}

set ConfigDir /home/helios/oagData/sr/magnetConditioning/

proc SetConfigFileDefault {args} {
    global ConfigFile ConfigDir DcpsSelection CommandChoice apsUpgrade
    set type ""
    APSStrictParseArguments {type}
    if {$apsUpgrade} {
        set sFile /home/helios/oagData/sr/magnetConditioning/standardize.config
        set dFile /home/helios/oagData/sr/magnetConditioning/degauss.config
    } else {
        set sFile /home/helios/oagData/sr/magnetConditioning/template.std
        set dFile /home/helios/oagData/sr/magnetConditioning/S_degauss.sdds
    }
    if {$apsUpgrade} {
        switch $type {
            standardize {
                set ConfigFile $sFile
                SetAllDcpsSelections 0
                set DcpsSelection(M) 1
                set DcpsSelection(Q) 1
                set DcpsSelection(Q7) 1
                set DcpsSelection(QD) 1
                set DcpsSelection(S) 1
                set DcpsSelection(SM1) 1
                set DcpsSelection(SM2) 1
            }
            degauss {
                set ConfigFile $dFile
                SetAllDcpsSelections 0
                set DcpsSelection(HCORRs) 1
                set DcpsSelection(VCORRs) 1
                set DcpsSelection(FH) 1
                set DcpsSelection(FV) 1
                set DcpsSelection(CH) 1
                set DcpsSelection(CV) 1
                set DcpsSelection(SQ) 1
                set DcpsSelection(QT) 1
                set DcpsSelection(MT) 1
                set DcpsSelection(CM) 1
            }
        }
    } else {
        switch $type {
            standardize {
                set ConfigFile $sFile
                SetAllDcpsSelections 0
                set DcpsSelection(QUADs) 1
                set DcpsSelection(SEXTs) 1
            }
            dipole {
                set ConfigFile $sFile
                SetAllDcpsSelections 0
                set DcpsSelection(DIPOLE) 1
                set DcpsSelection(C:DIPOLE) 1
            }
            degauss {
                set ConfigFile $dFile
                SetAllDcpsSelections 0
                set DcpsSelection(HCORRs) 1
                set DcpsSelection(C:HCORRs) 1
            }
        }
    }
    set CommandChoice configure
}

proc ChooseConfigFile {} {
    global ConfigFile ConfigDir
    set filename [APSFileSelectDialog .chooseConfigFile \
                    -listDir $ConfigDir]
    if {[string length $filename]!=0} {
        set ConfigFile $filename
        set ConfigDir [file dirname $filename]
    }
}


proc MakeSectorsWidget {widget args} {
    global SectorSelection
    set parent ""
    APSParseArguments {parent}
    set w $parent$widget
    frame $w -bd 4 -relief raised
    pack $w -side top -fill x

    label $w.title -text "Storage Ring Sector Selection" -relief ridge
    pack $w.title -side top -fill x

    frame $w.ops -bd 2
    pack $w.ops -side top -fill x
    APSButton .setAll -width "" -text "SELECT ALL" -command "SetAllSectors 1" -parent $w.ops 
    APSButton .clearAll -width "" -text "CLEAR ALL" -command "SetAllSectors 0" -parent $w.ops 
    APSButton .toggle -width "" -text "TOGGLE" -command "ToggleAllSectors" -parent $w.ops

    foreach zone {A B C D E F} {
        APSButton .setZone$zone -width "" -text "ZONE $zone" \
          -command "SetZoneSectors $zone" -parent $w.ops 
    }
    
    frame $w.check -bd 2 
    pack $w.check -side top -fill x
    set sector 1

    for {set quad 1} {$quad<5} {incr quad} {
        frame $w.check.q$quad 
        pack $w.check.q$quad -side top -fill x
        set start [expr ($quad-1)*10+1]
        set end   [expr $start+9]
        for {set sector $start} {$sector<=$end} {incr sector} {
            set cbLabel $sector
            if {$sector<10} {set cbLabel 0$sector}
            set SectorSelection($sector) 0
            checkbutton $w.check.q$quad.s$sector -text S$cbLabel \
              -variable SectorSelection($sector) -relief ridge 
            pack $w.check.q$quad.s$sector -side left -fill x
        }
    }
    
}

proc MakeDcpsWidget {widget args} {
    global DcpsSelection FamilyName apsUpgrade
    set parent ""
    APSParseArguments {parent}
    set w $parent$widget
    frame $w -bd 4 -relief raised
    pack $w -side top -fill x

    label $w.title -text "DC Power Supply Family Selection" -relief ridge
    pack $w.title -side top -fill x

    frame $w.ops -bd 2 
    pack $w.ops -side top -fill x
    APSButton .setAll -width "" -text "SET ALL" -command "SetAllDcpsSelections 1" -parent $w.ops 
    APSButton .clearAll -width "" -text "CLEAR ALL" -command "SetAllDcpsSelections 0" -parent $w.ops 
    
    frame $w.check -bd 2 
    pack $w.check -side top -fill x
    if {$apsUpgrade} {
        set choices "FH FV HCORRs VCORRs CH CV Q Q7 SQ S M MT CM QD QT SM1 SM2"
        set choiceText "Fast-H-Corr Fast-V-Corr H-Corr V-Corr Canted-H-Corr Canted-V-Corr Quad Quad-Q7 SkewQuad Sext M-Dipole M-DipoleTrim Canted-M-Dipole Q-Dipole Q-DipoleTrim S:M1 S:M2"
        set FamilyName(HCORRs) H
        set FamilyName(VCORRs) V
        set FamilyName(FH) FH 
        set FamilyName(FV) FV
        set FamilyName(CH) CH
        set FamilyName(CV) CV
        set FamilyName(SQ) SQ
        set FamilyName(QT) QT
        set FamilyName(M) M
        set FamilyName(MT) MT
        set FamilyName(CM) CM
        set FamilyName(Q) Q
        set FamilyName(Q7) Q7
        set FamilyName(QD) QD
        set FamilyName(S) S
        set FamilyName(SM1) SM1
        set FamilyName(SM2) SM2
    } else {
        set choices "DIPOLE QUADs SKEWs SEXTs HCORRs VCORRs TRIMs QS4s C:DIPOLE C:HCORRs C:VCORRs"
        set choiceText "DIPOLE QUADs SKEWs SEXTs HCORRs VCORRs TRIMs QS4s C:DIPOLE C:HCORRs C:VCORRs"
        set FamilyName(DIPOLE) BM
        set FamilyName(QUADs) Q
        set FamilyName(SKEWs) QS
        set FamilyName(SEXTs) S
        set FamilyName(HCORRs) H
        set FamilyName(VCORRs) V
        set FamilyName(TRIMs) MT
        set FamilyName(QS4s) QS4
        set FamilyName(C:DIPOLE) C:BM
        set FamilyName(C:HCORRs) C:H
        set FamilyName(C:VCORRs) C:V
    }
    foreach choice $choices text $choiceText {
        set DcpsSelection($choice) 0
        checkbutton $w.check.c$choice -text $text \
          -variable DcpsSelection($choice) -relief ridge 
        pack $w.check.c$choice -side left -fill x
    }
    SetAllDcpsSelections 0
}

proc SetAllDcpsSelections {value} {
    global DcpsSelection
    foreach name [array names DcpsSelection] {
        set DcpsSelection($name) $value
    }
}

proc SetAllSectors {value} {
    global SectorSelection
    for {set sector 1} {$sector<41} {incr sector} {
        set SectorSelection($sector) $value
    }
}

proc ToggleAllSectors {} {
    global SectorSelection
    for {set sector 1} {$sector<41} {incr sector} {
        set value [subst \$SectorSelection($sector)]
        set SectorSelection($sector) [expr $value?0:1]
    }
}

proc SetZoneSectors {zone} {
    global SectorSelection
    SetAllSectors 0
    switch $zone {
        A {lappend SectorList 2 3 4 5 6 7 8 9 }
        B {lappend SectorList 10 11 12 13 14 15 16 17}
        C {lappend SectorList 18 19 20 21 22 23}
        D {lappend SectorList 24 25 26 27 28 29}
        E {lappend SectorList 30 31 32 33 34 35}
        F {lappend SectorList 36 37 38 39 40  1}
        default {
            SetDcpsStatus "Invalid zone $zone"
        }
    }
    foreach sector $SectorList {
        set SectorSelection($sector) 1
    }
}

proc SetupSkewArray {} {
    global skewName
    for {set sector 1} {$sector<41} {incr sector} {
        set skewName($sector) ""
    }
    foreach sector {3 7 11 15 19 23 27 31 35 39} {
        set skewName($sector) "S${sector}A:QS"
    }
    foreach sector {1 5  9 13 17 21 25 29 33 37} {
        set skewName($sector) "S${sector}B:QS"
    }
}

SetupSkewArray
MakeDcpsWidget .dcps -parent .userFrame
MakeSectorsWidget .sectors -parent .userFrame
MakeCommandChoiceWidget .coms -parent .userFrame
MakeActionWidget .ops -parent .userFrame
