#!/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.1 $ \$Author: shang $"

set stConfig  /home/helios/oagData/controlFiles/Linac/conditioning/LinacStd.sdds
set degConfig /home/helios/oagData/controlFiles/Linac/conditioning/LinacDegauss.sdds

proc SetStatus {text} {
    global status
    set status $text
    update
}

proc SelectStandardizeMagnets {args} {
    set all 0
    APSParseArguments {all}
    
    for {set sn 1} {$sn<=5} {incr sn} {
        global stL${sn}List
        foreach var [set stL${sn}List] {
	    global $var
            set $var $all
        }
    }
}

proc SelectDegaussMagnets {args} {
    set all 0
    APSParseArguments {all}
    
    foreach deg {L1 L2 L3 L4 L5 L1:PG1 L1:RG1 L1:RG2} {
        global deg${deg}List
        foreach var [set deg${deg}List] {
	    if {$var!="L1:PG1:SC1:HZ" && $var!="L1:PG1:SC1:VL" } {
		global $var
		set $var $all
	    }
        }
    }
}


proc GetSelectedList {args} {
    set rootname ""
    APSParseArguments {rootname}
    
    
    set selectedList ""
 
    foreach type {L1 L2 L3 L4 L5} {
	global ${rootname}${type}List
        foreach item [set ${rootname}${type}List] {
	    global $item
            if [set $item] {
                lappend selectedList $item
            }
        }
    }
    if {$rootname=="deg"} {
        global degL1:PG1List degL1:RG1List degL1:RG2List
        foreach type {L1:PG1 L1:RG1 L1:RG2} {
            foreach item [set ${rootname}${type}List] {
		global $item
                if [set $item] {
                    lappend selectedList $item
                }
            }
        }
    }
    return $selectedList
}

proc StartConditioning {args} {
    set rootname ""
    APSParseArguments {rootname}
    
    global stConfig degConfig  Standardize Degauss
    set selectedList [GetSelectedList -rootname $rootname]
    
    set config [set ${rootname}Config]
    set tmpRoot /tmp/[APSTmpString].$rootname
    if [catch {exec sddsmakedataset $tmpRoot.1 -col=DeviceName,type=string \
		   -data=[join $selectedList ,] } result] {
	return -code error $result
    }
    #need filter out PS that are powered off
    if [catch {exec sddsprocess $tmpRoot.1 -edit=col,ControlName,DeviceName,ei/:readyCC/ -pipe=out \
		   | sddscasr -save -pipe \
		   | sddsprocess -pipe -scan=col,Value,ValueString,%lf \
		   | tee $tmpRoot.2 \
		   | sddsprocess -pipe -filter=col,Value,0.5,1.5 -nowarnings \
		   | sddsconvert -pipe=in $tmpRoot.1a -retain=col,DeviceName } result] {
	return -code error $result
    }
    set rows [exec sdds2stream -rows=bar $tmpRoot.1a]
    if !$rows {
	SetStatus "No power-on power supply selected for conditioning."
	return
    }
    if [catch {exec sddsprocess $tmpRoot.2 -pipe=out -filter=col,Value,0,0 -nowarnings\
		   | sdds2stream -pipe -col=DeviceName} offList] {
	return -code error $offList
    }
    foreach pv $offList {
	global $pv 
	set $pv 0
    }

    if [catch {exec sddsselect $config $tmpRoot.1a $tmpRoot.config1 -match=ControlName=DeviceName} result] {
	return -code error $result
    }
    APSAddToTmpFileList -ID condition -fileList "$tmpRoot.1 $tmpRoot.config1 $tmpRoot.config"
    SetStatus "config file is $tmpRoot.config"
    switch $rootname {
	st {
	    SetStatus "Start standardizing ..."
	    if [catch {exec sddsprocess $tmpRoot.config1 $tmpRoot.config \
			   "-reprint=col,Approach,$Standardize(Approach)" \
			   "-redefine=col,Minutes,$Standardize(Minutes),type=long" \
			   "-redefine=col,Seconds,$Standardize(Seconds),type=long" \
			   "-redefine=col,NumCycles,$Standardize(NumCycles),type=long" } result] {
		return -code error $result
	    }
	    if [catch {exec standardize $tmpRoot.config } result] {
		return -code error $result
	    }
	}
	deg {
	    SetStatus "Start degaussing ..."
	    if [catch {exec sddsprocess $tmpRoot.config1 $tmpRoot.config \
			   "-redefine=col,DecayMinutes,$Degauss(Minutes),type=long" \
			   "-redefine=col,DecaySeconds,$Standardize(Seconds),type=long" \
			   "-redefine=col,NumDecay,$Degauss(Number),type=long" } result] {
		return -code error $result
	    }
	    if [catch {exec degauss  $tmpRoot.config} result] {
		return -code error $result
	    }
	}
    }
    
    SetStatus "done."
}

proc CheckConditioning {args} {
    set rootname ""
    APSParseArguments {rootname}

    set selectedList [GetSelectedList -rootname $rootname]
    switch $rootname {
        st {
            set type standardizing
        }
        deg {
            set type degaussing
        }
    }
    if ![llength $selectedList] {
        SetStatus "No magnets selected for $type."
        return
    }
  
    if [catch {exec cavget -list=[join $selectedList ,] -list=:CnditVal -pend=20 -printErrors} valList] {
	catch {exec cavget -list=[join $selectedList ,] -list=:CnditVal -label} valList
        return -code error [join $valList ,]
    }
    set tmpRoot /tmp/[APSTmpString].cnditval
    if [catch {exec sddsmakedataset -pipe=out -col=PowerSupply,type=string -data=[join $selectedList ,] \
                   -col=ConditioningStatus,type=short -data=[join $valList ,] \
                   | sddsprintout -pipe=in $tmpRoot.print \
                   "-title=Conditioning status of $type PVs:\nred (-1) means spoiled\nblue (0) means in process\nblack (1) means finished normally\n" \
                   -col=PowerSupply -col=ConditioningStatus } result] {
        return -code error $result
    }
    set displayW  [APSUniqueName .diff] 
    APSFileDisplayWindow $displayW  -fileName $tmpRoot.print -width 50 -height 50 -printCommand "enscript -r"
    APSWaitWithUpdate -waitSeconds 1
    set data [${displayW}.userFrame.file.text get 1.0 end]
    set indexList ""
    set index1List ""
    set n 1
    foreach line [split $data \n] {
        if {[lindex $line end] == -1} {
            append indexList "$n.0 [expr {$n + 1}].0 "
        } elseif {[lindex $line end] == 0} {
            append index1List "$n.0 [expr {$n + 1}].0 "
        }
        incr n
    }
    if {[llength $indexList]} {
        eval ${displayW}.userFrame.file.text tag add tag1 $indexList
    }
    if [llength $index1List] {
        eval ${displayW}.userFrame.file.text tag add tag2 $index1List
    }
    ${displayW}.userFrame.file.text tag configure tag1 -foreground red
    ${displayW}.userFrame.file.text tag configure tag2 -foreground blue 
}

proc CreateStandardizeFrame {args} {
    set parent ""
    APSParseArguments {parent}
 
    global stL1List stL2List stL3List stL4List stL5List stConfig 
    
    APSFrame .f -parent $parent 
    $parent.f.frame configure -relief flat -bd 0
    foreach sn {1 2 3 4 5} {
	if [catch {exec sddsprocess $stConfig -match=col,Beamline=L$sn -pipe=out \
		       | sdds2stream -pipe -col=ControlName} result] {
	    return -code error $result
	} 
	set stL${sn}List $result 
	eval global [join $result]
	APSFrame .l$sn -parent $parent.f.frame -packOption "-side left -anchor ne" -label "L$sn Supplies"  
	$parent.f.frame.l$sn.frame configure -relief flat -bd 0
	APSCheckButtonFrame .l$sn -parent $parent.f.frame.l$sn.frame  -label "" -variableList $result \
	    -buttonList $result -allNone 1
    }
    
   # foreach sn {1 2 3 4 5} {
   #     APSCheckButtonFrame .l$sn -parent $parent -label "L$sn" -variableList [set stL${sn}VarList] \
   #         -buttonList [set stL${sn}List] -allNone 1 -orientation horizontal
    #}
    global Standardize
    set Standardize(Minutes) 1
    set Standardize(Seconds) 0
    set Standardize(NumCycles) 4
    set Standardize(Approach) below
    APSFrame .f1 -parent $parent 
    set w $parent.f1.frame
    APSLabeledEntryFrame .min -parent $w -label "Standardize time (minutes and seconds):" -variableList {Standardize(Minutes) Standardize(Seconds)} \
        -width 20 -orientation horizontal 
    APSLabeledEntry .num -parent $w -label "Number of Cycles:" -textVariable Standardize(NumCycles) -width 20 -packOption "-anchor w"
    APSRadioButtonFrame .app -parent $w -label "Approach:" -variable Standardize(Approach) -buttonList {Above Below} \
	-valueList {above below} -orientation horizontal
    APSButton .all -parent $w -text "Select All" -command "SelectStandardizeMagnets -all 1"
    APSButton .non -parent $w -text "Select None" -command "SelectStandardizeMagnets -all 0" 
    APSButton .check -parent $w -text "Check Conditioning" -command "CheckConditioning -rootname st"
    APSButton .cond -parent $w -text "Start Conditioning" -command "StartConditioning -rootname st"
}

proc CreateDegaussFrame {args} {
    set parent ""
    APSParseArguments {parent}
 
    global degL1List degL2List degL3List degL4List degL5List degL1:PG1List degL1:RG1List degL1:RG2List degConfig
    
    APSFrame .f -parent $parent 
    $parent.f.frame configure -relief flat -bd 0
    
    foreach deg {L1:PG1 L1:RG1 L1:RG2 L1 L2 L3 L4 L5} { 
	if [catch {exec sddsprocess $degConfig -match=col,Beamline=$deg -pipe=out \
		       | sdds2stream -pipe -col=ControlName} result] {
	    return -code error $result
	}
	set deg${deg}List [join $result]
	eval global [join $result]
	APSFrame .l$deg -parent $parent.f.frame -packOption "-side left -anchor ne" -label "$deg Supplies"  
	$parent.f.frame.l$deg.frame configure -relief flat -bd 0
	set buttonList [APSCheckButtonFrame .l$deg -parent $parent.f.frame.l$deg.frame \
			    -label "" -variableList [join $result] \
			    -buttonList [join  $result]  -allNone 1]
	if {$deg=="L1:PG1"} {
	    set index [lsearch $result L1:PG1:SC1:HZ]
	    [lindex $buttonList $index] configure -state disabled 
	    set index [lsearch $result L1:PG1:SC1:VL]
	    [lindex $buttonList $index] configure -state disabled  
	}
    }
    APSFrame .f1 -parent $parent
    set w $parent.f1.frame
    global Degauss
    set Degauss(Minutes) 1
    set Degauss(Seconds) 0
    set Degauss(Number) 5
    APSLabeledEntryFrame .n1 -parent $w -label "Decay time (minutes/seconds):" -width 20 -variableList {Degauss(Minutes) Degauss(Seconds)} -orientation horizontal
    APSLabeledEntry .n2 -parent $w -label "Number of decays:" -width 20 -packOption "-anchor w" -textVariable Degauss(Number) 
    APSButton .all -parent $w -text "Select All" -command "SelectDegaussMagnets -all 1 -rootname deg"
    APSButton .non -parent $w -text "Select None" -command "SelectDegaussMagnets -all 0 -rootname deg"
    APSButton .check -parent $w -text "Check Conditioning" -command "CheckConditioning -rootname deg"
    APSButton .con -parent $w -text "Start Conditioning" -command "StartConditioning -rootname deg"
}


APSApplication . -name LinacPowerSupplyConditioningTest -version $CVSRevisionAuthor -overview \
    "Linac Power Supply Conditioning."

set status ""
APSScrolledStatus .status -parent .userFrame -width 60 \
  -textVariable status
set widgetList [APSTabFrame .sel -parent .userFrame -label "" \
                    -labelList "Standardization Degauss" \
                    -width 1250 -height 450]

set stW [lindex $widgetList 0]
set degW [lindex $widgetList 1]

CreateStandardizeFrame -parent $stW
CreateDegaussFrame -parent $degW
