#!/bin/sh  
# \
exec oagwish "$0" "$@"

# $Log: not supported by cvs2svn $

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)]

APSStandardSetup

set CVSRevisionAuthor "\$Revision: 1.1 $ \$Author: shang $"

set args $argv
set database /home/helios/SHANG/test/feedback/fb.sdds
set offline 0
APSParseArguments {database offline}

APSApplication . -name SROrbitFeedbackDiag -version $CVSRevisionAuthor \
  -overview "SR orbit feedback fault diagose system ."

set mainStatus ""
APSScrolledStatus .status -parent .userFrame -width 112 -height 5 -textVariable mainStatus 

APSRadioButtonFrame .off -parent .userFrame -label "Off line?" \
  -buttonList {Yes No} -valueList {1 0} -variable offline -orientation horizontal
proc SetMainStatus {text} {
    global mainStatus
    set mainStatus "[clock format [clock seconds] -format %H:%M:%S] $text"
    update      
}

proc LoadDatabase {args} {
    set database ""
    APSParseArguments {database}
    
    global DataBase treeNames baseElements topTree secondTree offline
    
    if [catch {sdds load $database data} result] {
        return -code error "LoadDatabase(1): $result"
    }
    set treeNames $data(Parameter.Label)
    set treeIDs $data(Parameter.ID)
    set treePVs $data(Parameter.PVNames)
    set treeDescs $data(Parameter.Description)
    set pages [llength $treeNames]
    
    set index 0
    set topTree [lindex $treeNames 0]
    set level 2
    set bases 0
    foreach tree $treeNames {
        global $tree
    }
    set baseElements ""
   
    foreach tree $treeNames {
        set ${tree}(treeID) [lindex $treeIDs $index]
        set ${tree}(treeDesc) [lindex $treeDescs $index]
        set ${tree}(treeName) $tree
        set ${tree}(treePV) [lindex $treePVs $index]
        
        set ${tree}(failed) 0
        set ${tree}(type) subTree
        foreach col $data(ColumnNames) {
            set ${tree}($col) [lindex $data(Column.$col) $index]
        }
        set idList [set ${tree}(ID)]
        set labelList [set ${tree}(Label)] 
        set descList [set ${tree}(Description)]
        set guidList [set ${tree}(Guidance)]
        set probList [set ${tree}(Probability)]
        foreach ID $idList label $labelList desc $descList guid $guidList prob $probList {
            global $label
            if {$ID>1000} {
                if [lsearch $baseElements $label]<0 {
                    lappend baseElements $label
                }
            }
            set ${label}(treeName) $label
            set ${label}(treeDesc) $desc
            set ${label}(guid) $guid
            set ${label}(treeID) $ID
            set ${label}(type) BASE
        }
        
        incr index
    }
    unset data
    set secondTree [set ${topTree}(Label)]
}

proc ShowTreeStatus {args} {
    set var ""
    APSParseArguments {var}

    global $var
    set dialogFrame .dialog${var}.userFrame
    APSDialogBox .dialog$var \
      -name "[set ${var}(treeDesc)]" \
      -contextHelp "Dialog status box for $var"
    
    APSFrame .f1 -parent $dialogFrame 
    APSLabel .label -parent $dialogFrame.f1.frame -text $var 
    APSLabel .status -parent $dialogFrame.f1.frame -text STATUS -packOption "-side right"
    
}

proc ShowElement {args} {
    set var ""
    APSParseArguments {var}

    global $var
    set ID [set ${var}(ID)]
    puts "$var $ID"  
}

set fbopen(Status) 0
set rmsDsp(Status) 0
set rmFailFailed 0
set hbErrorFailed 0
set hvTripFailed 0 
set largeRMSFailed 0
set beamdumpFailed 0
proc UpdateTop {args} {
    global TopFailed rmFailFailed hbErrorFailed hvTripFailed largeRMSFailed beamdumpFailed fbopen rmsDsp
    set TopFailed 0
    if {$fbopen(Status)==1} {
	set TopFailed 1
    } elseif {$rmsDsp(Status)==1} {
	set TopFailed 1
    } else {
	foreach var {rmFailFailed hbErrorFailed hvTripFailed largeRMSFailed beamdumpFailed} {
	    if [set $var] {
		set TopFailed 1
		break
	    }
	}
    }
}


proc ChangeWidget {args} {
    set label ""
    APSParseArguments {label}
    
    global ${label}Widget $label ${label}Failed 
  
    if [winfo exist .userFrame.tab.frame.tn] {
	if [regexp {rmFail} $label] {
	    .userFrame.tab.frame.tn select 0
	} elseif [regexp {hb} $label] {
	    .userFrame.tab.frame.tn select 1
	} elseif [regexp {hv} $label] {
	    .userFrame.tab.frame.tn select 2
	} elseif [regexp {largeRMS} $label] {
	    .userFrame.tab.frame.tn select 3
	}  elseif [regexp {beamdump} $label] {
	    .userFrame.tab.frame.tn select 4
	}
    }
    
    set varName [set ${label}(varName)]
    set value [set $varName]
    SetMainStatus "$label $value"
    
    set widget [set ${label}Widget]
    if $value {
       # $widget configure -selectcolor red
        if {$label!="Top"} {
            global TopWidget TopFailed
           # $TopWidget  configure -selectcolor red
	   # $TopWidget invoke
            set TopFailed 1
        }
    } else {
       # $widget configure -selectcolor white
	UpdateTop
    }
}

proc getRMpresector {args} {
    set sector ""
    APSParseArguments {sector}
    if {$sector=="dpbpm" || $sector=="dp"} {
	set presector 1
    } elseif {$sector==40} {
	set presector dpbpm
    } elseif {$sector==39} {
	set presector 40
    } else {
	set presector [expr $sector + 2]
    }
    return $presector
}

proc SelectAllBaseSectors {args} {
    set value ""
    set varList ""
    set type ""
    APSParseArguments {varList value type}
    global TopFailed rmFailFailed  hbErrorFailed rmVarList hbVarList rmSectorList hbSectorList
    eval global $varList
    foreach var $varList {
        set ${var}(Status) $value
    }
    switch $value {
	Fail {
	    switch $type {
		rm {
		    foreach var $rmVarList {
			global $var
			set $var 1
		    }
		set rmFailFailed 1
		}
		hb {
		foreach var $hbVarList {
		    global $var
		    set $var 1
		}
		    set hbErrorFailed 1
		}
	    }
	    set TopFailed 1
	}
	default {
	    switch $type {
		rm {
		    set rmFailFailed 0
		    foreach var $rmVarList {
			global $var
			set sector [scan $var rm%ld]
			if [catch {expr $sector/2} result] {
			    set sector dpbpm
			}
			set $var 0
			foreach label {reboot receiver cable} {
			    switch $label {
				reboot {
				    set presector [getRMpresector -sector $sector]
				    set var2 rm${presector}Reboot
				}
				receiver {
				    set var2 rmFail$sector
				}
				cable {
				    set var2 rmCable$sector
				}
			    }
			    global $var2
			    set status [set ${var2}(Status)]
			    if {$status=="Fail"} {
				set $var 1
				break
			    }
			}
			if [set $var] {
			    set rmFailFailed 1
			}
		    }
		    if $rmFailFailed {
			set TopFailed 1
		    } else {
			UpdateTop
		    }
		}
		hb {
		    set hbErrorFailed 0
		    foreach var $hbVarList {
			global $var
			set $var 0
			set sector [scan $var hb%ld]
			foreach label {hbDspStop hbSuspTask hbDspFail hbFSICFail} {
			    set var2 ${label}$sector
			    global $var2
			    set status [set ${var2}(Status)]
			    if {$status=="Fail"} {
				set $var 1
			    }
			}
			if [set $var] {
			    set hbErrorFailed 1
			}
		    }
		    if $hbErrorFailed {
			set TopFailed 1
		    } else {
			UpdateTop
		    }
		}
	    }
	}
    }
    if {$type=="hb"} {
	UpdateHBParentFromBase1
    }
    UpdateTop
  #  puts $varList
}
#reflective memory rmFail
proc MakeRMWidget {widget args} {
    set parent ""
    APSParseArguments {parent}
    global rmFail rmSectorList rmVarList
    eval global $rmFail(Label)
    set rmLabelList $rmFail(Label)
    set rmSectorList [regsub -all {rm} $rmLabelList ""]
    if {[llength $rmLabelList]!=[llength $rmSectorList]} {
        puts "Error: label and sector lengthes are different."
        exit 1
    }
    
    set rebootList ""
    set receiverList ""
    set cableList ""
    foreach sector $rmSectorList {
	if {$sector=="dp"} {
	    set sector dpbpm
	}
	lappend rebootList rm${sector}Reboot
	lappend receiverList rmFail$sector
	lappend cableList rmCable$sector
    }
    
    frame $parent.x1 
    pack $parent.x1 -side left
    frame $parent.x2
    pack $parent.x2 -side left
    frame $parent.x3
    pack $parent.x3 -side left
    set f1 $parent.x1
    set f2 $parent.x2
    set f3 $parent.x3
    label $f1.l -text "Sector"
    pack $f1.l -side top
    label $f2.l -text "  hbError  "
    pack $f2.l -side top
    label $f3.l -text "Base Elements (u: Unknown state   g: good    f:failed)"
    pack $f3.l -side top
   
    $f1 configure -bd 0
    $f2 configure -bd 0
    $f3 configure -bd 0
    
    #make sector labels
    set len [llength $rmSectorList]
    label $f1.label -text "all"
    pack $f1.label -side bottom
    for {set n $len} {$n>=0} {incr n -1} {
        if $n  {
            set sector [lindex $rmSectorList [expr $n-1]]
            if [catch {rpn $sector / 2} result] {
                #sector is string
                set text [format %3s $sector]
            } else {
                #sector is number
                set text [format %3d $sector]
            }
           # set text $sector
            label $f1.sector$n -text $text \
              -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
            pack $f1.sector$n -side bottom
        } else {
            label $f1.sector$n -text "   " \
              -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
            pack $f1.sector$n -side bottom
        }
    }
    global rmAll
    checkbutton $f2.all -text "" -variable rmAll -command "SelectAll -type rm"
    pack $f2.all -side bottom
    set rmVarList ""
    set labelList $rmFail(Label)
    for {set n $len} {$n>=0} {incr n -1} {
        if $n  {
            set sector [lindex $rmSectorList [expr $n-1]]
	    set label [lindex $labelList [expr $n-1]]
            if {$sector=="dp"} {
		set sector dpbpm
	    }
	    set var rm${sector}Error
	    global $var 
	    set $var 0
	    lappend rmVarList $var
	    set ${label}(varName) $var
	    set ${label}(widget) $f2.sector$n
           # set text $sector
            checkbutton $f2.sector$n -text "" -variable $var \
		-borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
		-command "UpdateRMParentAndChild -sector $sector -var $var"
            pack $f2.sector$n -side bottom
        } else {
            label $f2.sector$n -text "inter. level" \
              -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
            pack $f2.sector$n -side bottom
        }
    }
    
    # make vertical columns for checkbuttons vs item name
   
    set itemList {"pre_ioc_reboot" "receiver" "cable"}
    set nameList {reboot receiver cable}

    set index 1
    
    foreach item $itemList type {rm rmFail rmCable} {
        set var [lindex $nameList [expr $index -1]]
        frame $f3.$var
        pack $f3.$var -side left -expand 1 -fill y
        set labelList [set ${var}List]
        eval global $labelList
        global ${item}Check
        set ${item}Check 0
        frame $f3.$var.a
        pack $f3.$var.a -side bottom -fill x
        
        radiobutton $f3.$var.a.u -variable ${item}Status -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
          -command "SelectAllBaseSectors -varList \"$labelList\" -value Unknown -type rm" -text u -value Unknown -fg red
        pack $f3.$var.a.u -side left
        
        radiobutton $f3.$var.a.g -variable ${item}Status -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
          -command "SelectAllBaseSectors -varList \"$labelList\" -value Good -type rm" -text g -fg red -value Good 
        pack $f3.$var.a.g -side left

        radiobutton $f3.$var.a.f -variable ${item}Status -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
          -command "SelectAllBaseSectors -varList \"$labelList\" -value Fail -type rm" -text f -value Fail -fg red
        pack $f3.$var.a.f -side left
        for {set n $len} {$n>0} {incr n -1} {
            set sector [lindex $rmSectorList [expr $n-1]]
	    set presector [getRMpresector -sector $sector]
	    switch $var {
		reboot {
		    set label rm${presector}Reboot
		}
		receiver {
		    set label rmFail$sector
		}
		cable {
		    set label rmCable$sector
		}
	    }
	    global $label
            set ${label}(Status) Good
            frame $f3.$var.r$n 
            pack $f3.$var.r$n -side bottom -fill x
            radiobutton $f3.$var.r$n.u -text u  \
		-variable ${label}(Status) -value Unknown -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
		-command "UpdateRMFromBase -sector $sector -type $type -item $label"
            pack $f3.$var.r$n.u -side left  
            radiobutton $f3.$var.r$n.g -text g \
		-variable ${label}(Status) -value Good -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
		-command "UpdateRMFromBase -sector $sector -type $type -item $label"
            pack $f3.$var.r$n.g -side left  
            radiobutton $f3.$var.r$n.f -text "f   "  \
		-variable ${label}(Status) -value Fail -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
		-command "UpdateRMFromBase -sector $sector -type $type -item $label"
            pack $f3.$var.r$n.f -side left  
            
        }
        label $f3.$var.label -text "$item    " \
          -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
        pack $f3.$var.label -side bottom
        incr index
    }
}

proc UpdateHBParentFromBase {args} {
    set label ""
    set type ""
    APSParseArguments {label type}
    
    global hbSectorList  hbErrorFailed TopFailed  hbError $label
    set status [set ${label}(Status)]
    set sector [scan $label ${type}%ld]
    global hb$sector
    set var [set hb${sector}(varName)]
    set widget [set hb${sector}(widget)]
    global $var $widget
    if {$status=="Fail"} {
	set $var 1
	set hbErrorFailed 1
	set TopFailed 1
    } else {
	set value 0
	foreach label {hbDspStop hbSuspTask hbDspFail hbFSICFail} {
	    set var1 ${label}$sector
	    global $var1
	    set status [set ${var1}(Status)]
	    if {$status=="Fail"} {
		set $var 1
		set hbErrorFailed 1
		set TopFailed 1
		set value 1
		break
	    }
	    if {$status=="Unknown"} {
		set value 2
	    }
	}
	if !$value {
	    set $var 0
	}
	if [set $var] {
	    set TopFailed 1
	    set hbErrorFailed 1
	}
    }
    APSSRSectorButtonsClicked -widget $widget -var $var -selectcolor maroon
    UpdateHBParentFromBase1
    UpdateTop
}

proc UpdateHBParentAndChild {args} {
    set sector ""
    set var ""
    APSParseArguments {sector var}
    global hbSectorList  hbErrorFailed TopFailed $var hbError
    
    if ![string length $sector] {
	set sector [scan $var hb%ld]
    }
    global hbDspStop$sector hbSuspTask$sector hbDspFail$sector hbFSICFail$sector
    if [set $var] {
	set hbErrorFailed 1
	set TopFailed 1
	foreach label {hbDspStop hbSuspTask hbDspFail hbFSICFail} {
	    set nm ${label}$sector
	    set ${nm}(Status) Unknown
	}
    } else {
	set hbErrorFailed 0
	set labelList [lrange $hbError(Label) 1 end]
	foreach label $labelList  {
	    global $label
	    set var [set  ${label}(varName)]
	    eval global $var
	    if [set $var] {
		set rmFailFailed 1
		break
	    }
	}
	if $hbErrorFailed {
	    set TopFailed 1
	}
	foreach label {hbDspStop hbSuspTask hbDspFail hbFSICFail} {
	    set nm ${label}$sector
	    set ${nm}(Status) Good
	}
    }
    UpdateHBParentFromBase1
    UpdateTop
}


proc UpdateHBParentFromBase1 {args} {
    global hbBase1 hbErrorFailed TopFailed hbVarList
    global $hbBase1
    set status [set ${hbBase1}(Status)]
    if {$status=="Fail"} {
	set hbErrorFailed 1
	set TopFailed 1
    } elseif {$status=="Good"} {
	set hbErrorFailed 0
	foreach var $hbVarList {
	    global $var
	    if [set $var] {
		set hbErrorFailed 1
		break
	    }
	}
    }
    UpdateTop
}
#hbError
proc MakeHBWidget {widget args} {
    set parent ""
    APSParseArguments {parent}
    global hbError
    eval global $hbError(Label) hbSectorList hbBase1 hbVarList hbAll
    set hbBase1 [lindex $hbError(Label) 0]
    set hbLabelList [lrange $hbError(Label) 1 end]
    set hbSectorList [regsub -all {hb} $hbLabelList ""]
    
    set hbDspStopList ""
    set hbSuspTaskList ""
    set hbDspFailList ""
    set hbFSICFailList ""
    foreach label $hbLabelList {
        global $label
        set labelList [set ${label}(Label)]
        lappend hbDspStopList [lindex  $labelList 0]
        lappend hbSuspTaskList [lindex $labelList 1] 
        lappend hbDspFailList [lindex $labelList 2]
        lappend hbFSICFailList [lindex $labelList 3]
    }
    foreach sector $hbSectorList {
	lappend hbVarList hb${sector}Error
	set hb${sector}(varName) hb${sector}Error
    }
    APSFrame .w1 -parent $parent
   set ${hbBase1}(Status) Good
    APSRadioButtonFrame .base -parent $parent.w1.frame \
	-label "$hbBase1 (base element, parallel to following intermediate elements)" \
	-variable ${hbBase1}(Status) -buttonList {Good Fail Uknown} -valueList {Good Fail Unknown} \
	-commandList {UpdateHBParentFromBase1 UpdateHBParentFromBase1 UpdateHBParentFromBase1} \
	-orientation horizontal
    
    APSFrame .w2 -parent $parent -label "HB intermediate elements and their base elements"
   
    set len [llength $hbSectorList]
    frame $parent.w2.frame.x1 
    pack $parent.w2.frame.x1 -side left
    frame $parent.w2.frame.x2
    pack $parent.w2.frame.x2 -side left
    frame $parent.w2.frame.x3
    pack $parent.w2.frame.x3 -side left
    set f1 $parent.w2.frame.x1
    set f2 $parent.w2.frame.x2
    set f3 $parent.w2.frame.x3
    
    label $f1.l -text "Sector"
    pack $f1.l -side top
    label $f2.l -text "  rmError  "
    pack $f2.l -side top
    label $f3.l -text "Base Elements (u: Unknown state   g: good    f:failed)"
    pack $f3.l -side top

    label $f1.label -text "all"
    pack $f1.label -side bottom
    for {set n $len} {$n>=0} {incr n -1} {
        if $n  {
            set sector [lindex $hbSectorList [expr $n-1]]
            if [catch {rpn $sector / 2} result] {
                #sector is string
                set text [format %3s $sector]
            } else {
                #sector is number
                set text [format %3d $sector]
            }
	    # set text $sector
            label $f1.sector$n -text $text \
		-borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
            pack $f1.sector$n -side bottom
        } else {
            label $f1.sector$n -text "   " \
		-borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
            pack $f1.sector$n -side bottom
        }
    }
    
    checkbutton $f2.all -text "" -variable hbAll -command "SelectAll -type hb"
    pack $f2.all -side bottom
    set labelList $hbError(Label)
    for {set n $len} {$n>=0} {incr n -1} {
        if $n  {
            set sector [lindex $hbSectorList [expr $n-1]]
	    set label [lindex $labelList $n]
	    set var hb${sector}Error
	    global $var 
	    set $var 0
	    set ${label}(varName) $var
	    set ${label}(widget) $f2.sector$n
           # set text $sector
            checkbutton $f2.sector$n -text "" -variable $var \
		-borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
		-command "UpdateHBParentAndChild -sector $sector -var $var"
            pack $f2.sector$n -side bottom
        } else {
            label $f2.sector$n -text "inter. level" \
              -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
            pack $f2.sector$n -side bottom
        }
    }
    
    # make vertical columns for checkbuttons vs item name
    set itemList {hbDspStop hbSuspTask hbDspFail hbFSICFail}
    set nameList $itemList
    set index 1
    foreach item $itemList {
        set var [lindex $nameList [expr $index -1]]
        frame $f3.$var
        pack $f3.$var -side left -expand 1 -fill y
        set labelList [set ${var}List]
        eval global $labelList
        global ${item}Check
        set ${item}Check 0
        
        frame $f3.$var.a
        pack $f3.$var.a -side bottom -fill x
        
        radiobutton $f3.$var.a.u -variable ${item}Status -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
          -command "SelectAllBaseSectors -varList \"$labelList\" rm -value Unknown -type hb" -text u -value Unknown -fg red
        pack $f3.$var.a.u -side left
        
        radiobutton $f3.$var.a.g -variable ${item}Status -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
          -command "SelectAllBaseSectors -varList \"$labelList\" -value Good -type hb" -text g -fg red -value Good
        pack $f3.$var.a.g -side left

        radiobutton $f3.$var.a.f -variable ${item}Status -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
          -command "SelectAllBaseSectors -varList \"$labelList\" -value Fail -type hb" -text f -value Fail -fg red
        pack $f3.$var.a.f -side left
        
        for {set n $len} {$n>0} {incr n -1} {
            set label [lindex $labelList [expr $n-1]]
            set ${label}(Status) Good
            frame $f3.$var.r$n 
            pack $f3.$var.r$n -side bottom -fill x
            radiobutton $f3.$var.r$n.u -text u  \
              -variable ${label}(Status) -value Unknown -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
		-command "UpdateHBParentFromBase -label $label -type $item"
            pack $f3.$var.r$n.u -side left  
            radiobutton $f3.$var.r$n.g -text g \
		-variable ${label}(Status) -value Good -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0  \
		-command "UpdateHBParentFromBase -label $label -type $item"
            pack $f3.$var.r$n.g -side left  
            radiobutton $f3.$var.r$n.f -text f  \
		-variable ${label}(Status) -value Fail -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 \
		-command "UpdateHBParentFromBase -label $label -type $item"
            pack $f3.$var.r$n.f -side left  
            
        }
        label $f3.$var.label -text "  $item        " \
          -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0
        pack $f3.$var.label -side bottom
        incr index
    }
    return
}


#HV trip
proc MakeHVWidget {widget args} {
    set parent ""
    APSParseArguments {parent}
    global hvTrip
    eval global $hvTrip(Label)
    APSFrame $widget -parent $parent -packOption "-side top"
    
    set i 1
    foreach label $hvTrip(Label) {
        set ${label}(Status) Good
        APSRadioButtonFrame .base$i -parent $parent$widget.frame \
	    -label [format %25s $label] -orientation horizontal \
	    -variable ${label}(Status) -buttonList {Good Fail Uknown} -valueList {Good Fail Unknown} \
	    -commandList [list "UpdateParent -label $label -type hvTrip" "UpdateParent -label $label -type hvTrip"  "UpdateParent -label $label -type hvTrip"]
        incr i
    }
    return
}

proc UpdateChild {args} {
    set type ""
    APSParseArguments {type}
    global ${type}Failed TopFailed $type
    if {$type=="rmsDsp" || $type=="fbopen"} {
	return
    }
    switch $type {
	hvTrip -
	beamdump -
	largeRMS {
	    if [set ${type}Failed] {
		foreach label [set ${type}(Label)] {
		    global $label
		    set ${label}(Status) Unknown
		}
	    } else {
		foreach label [set ${type}(Label)] {
		    global $label
		    set ${label}(Status) Good
		}
	    }
	}
	rmFail {
	    UpdateRMChild
	}
	hbError {
	    UpdateHBChild
	}
    }
}

proc UpdateRMChild {args} {
    global rmFailFailed rmSectorList rmVarList
    
    foreach var $rmVarList {
	global $var
	set $var $rmFailFailed
	set sector [scan $var rm%ld]
	if [catch {expr $sector/2} result] {
	    set sector dpbpm
	}
	foreach label {Reboot rmFail rmCable} {
	    if {$label=="Reboot"} {
		set presector [getRMpresector -sector $sector]
		set var1 rm${presector}$label
	    } else {
		set var1 ${label}$sector
	    }
	    global $var1
	    set status [set ${var1}(Status)]
	    if ![set $var] {
		set ${var1}(Status) Good
	    } else {
		set ${var1}(Status) Unknown
	    }
	}
    }
}

proc UpdateHBChild {args} {
    global hbErrorFailed hbSectorList hbVarList hbBase1
    global $hbBase1
    if !$hbErrorFailed {
	set ${hbBase1}(Status) Good
    } else {
	set ${hbBase1}(Status) Unknown
    }
    foreach var $hbVarList {
	global $var
	set $var $hbErrorFailed
	set sector [scan $var hb%ld]
	foreach label {hbDspStop hbSuspTask hbDspFail hbFSICFail} {
	    set var1  ${label}$sector
	    global $var1
	    set status [set ${var1}(Status)]
	    if ![set $var] {
		set ${var1}(Status) Good
	    } else {
		set ${var1}(Status) Unknown
	    }
	}
    }
}

proc UpdateParent {args} {
    set label ""
    set type ""
    APSParseArguments {label type}
    global $label ${type}Failed TopFailed $type
    set status [set ${label}(Status)]
    if {$status=="Fail"} {
	set ${type}Failed 1
	set TopFailed 1
    } elseif {$status=="Good"} {
	set ${type}Failed 0
	foreach label [set ${type}(Label)] {
	    global $label
	    set status [set ${label}(Status)]
	    if {$status=="Fail"} {
		set ${type}Failed 1
		break
	    }
	}
	if [set ${type}Failed] {
	    set TopFailed 1
	}
    }
}


#large RMS
proc MakeRMSWidget {widget args} {
    set parent ""
    APSParseArguments {parent}
    global largeRMS
    eval global $largeRMS(Label)
    APSFrame $widget -parent $parent -packOption "-side top"
    
    set i 1
    foreach label $largeRMS(Label) {
        set ${label}(Status) Good
        APSRadioButtonFrame .base$i -parent $parent$widget.frame \
	    -label [format %25s $label] -orientation horizontal \
	    -variable ${label}(Status) -buttonList {Good Fail Uknown} -valueList {Good Fail Unknown} \
	    -commandList [list "UpdateParent -label $label -type largeRMS" "UpdateParent -label $label -type largeRMS"  "UpdateParent -label $label -type largeRMS"]
        incr i
    }
    
}

#0r6 beam dump
proc MakeBeamDumpWidget {widget args} {
    set parent ""
    APSParseArguments {parent}

    global beamdump
    eval global $beamdump(Label)
    
     APSFrame $widget -parent $parent -packOption "-side top"
    
    set i 1
    foreach label $beamdump(Label) {
        set ${label}(Status) Good
        set text [set ${label}(treeDesc)]
        set sform [format "%%%lds" 79]
        set text [format $sform $text]
        APSRadioButtonFrame .base$i -parent $parent$widget.frame \
	    -label $text -orientation horizontal \
	    -variable ${label}(Status) -buttonList {No-problem Fail Uknown} -valueList {Good Fail Unknown} \
	    -commandList [list "UpdateParent -label $label -type beamdump" "UpdateParent -label $label -type beamdump"  "UpdateParent -label $label -type beamdump"]
        incr i
    }
}

proc BringUpDatapoolIOCFailHelp {args} {
    set type ""
    APSParseArguments {type}
    switch $type {
        DSPFailed {
            set text "Try to reboot/power cycle ioc; try to reset DSP/CPU load."
        }
        irmLoadFailed {
            set text "check NFS mount.                                    "
        }
        closeLoopFailed {
            set text "Check the RTFB 'Combined Err/Std Dev' screen under 'Stats' on the RTFB top level screen.\nIf all bars are filled, then:\n1, place datapool in scalar mode.\n2, use the 'Set Bpm Setpoints to Zero' button on the SRFB Orbit Feedback Control Screen \n  to zero the scalar bpm setpoints."
        }
        scalarVectorDiff {
            set text "The scalar values come directly from the BSP100s \n while the vector values are those received by \n RTFB DSPs via fiber links from the BSP100s and \n placed in the reflective memory for \n use by datapool orbit correction.\n\n Try to unlock the corresponding MFI100 using the MFI100 engineering screen.\n\n If there is checksum error, replace the transmitter/receiver module, or replace the MFI100 card"
        }
        default {
            set text ""
        }
    }
    if ![string length $text] {
        return
    }
    if [winfo exist .datapoolHelp] {
        destroy .datapoolHelp
    }
    APSInfoWindow .datapoolHelp -name "Datapool IOC $type Diag" -modal 1 -width 60 -infoMessage $text
    global $type
    set $type 0
           
}

proc MakeDatapoolIOCWidget {widget args} {
    set parent ""
    APSParseArguments {parent}
    
    APSFrame $widget -parent $parent -packOption "-side top"
   
    checkbutton $parent$widget.frame.dp1 -text "No loop time, DSP not working                             " -variable DSPFailed \
        -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 -command "BringUpDatapoolIOCFailHelp -type DSPFailed"
    pack $parent$widget.frame.dp1

    
    checkbutton $parent$widget.frame.dp2 -text "Can not load inverse response matrix                      " -variable irmLoadFailed \
        -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 -command "BringUpDatapoolIOCFailHelp -type irmLoadFailed"
    pack $parent$widget.frame.dp2
    
    checkbutton $parent$widget.frame.dp3 -text "BPM setpoint issue -- RTFB could not close loop           " -variable closeLoopFailed \
        -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 -command "BringUpDatapoolIOCFailHelp -type closeLoopFailed"
    pack $parent$widget.frame.dp3


    checkbutton $parent$widget.frame.dp4 -text "Large Difference between vector and scalar mode for a BPM " -variable scalarVectorDiff \
        -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 -command "BringUpDatapoolIOCFailHelp -type scalarVectorDiff"
    pack $parent$widget.frame.dp4


}

proc MakeDSPWidget {widget args} {
    set parent ""
    APSParseArguments {parent}
    
    APSFrame $widget -parent $parent -packOption "-side top"
   
    checkbutton $parent$widget.frame.dp1 -text "DSP hang up, no change on loop time" -variable DSPHangup \
        -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 -command "BringUpDSPFailHelp -type DSPHangup"
    pack $parent$widget.frame.dp1
}

proc BringUpDSPFailHelp {args} {
    set type ""
    APSParseArguments {type}
    
    switch $type {
        DSPHangup {
            set text "Check ioc console to see if dsp program is loaded.\nTry to reboot ioc; power cycle VME crate; reseat the DSP; replace VME crate."
        }
        default {
            return
        }
    }
    if [winfo exist .dspHelp] {
        destroy .dspHelp
    }
    APSInfoWindow .dspHelp -name "DSP Hang Up" -modal 1 -width 60 -infoMessage $text
    global $type
    set $type 0
}

proc MakeTabWidget {args} {
    set parent ""
    set tree ""
    APSParseArguments {parent tree}

    global $tree
    set label [set ${tree}(Label)]

    set treeName [set ${tree}(treeName)]
    puts "$label $treeName"
    
    
    
}

#check subtree which only has base elements
proc CheckSubTree {args} {
    set tree ""
    APSParseArguments {tree}
    
    global $tree database baseDialogResponse 
    set baseList [set ${tree}(Label)]
    eval global $baseList
    set varName [set ${tree}(varName)]
    global $varName
    
    set badList ""
    set goodList ""
    foreach base $baseList {
        set status [set ${base}(Status)]
        switch $status {
            Good {
                lappend goodList $base
            }
            Fail {
                lappend badList $base
            }
        }
    }
    set option ""
    if [llength $goodList] {
        append option " -goodElements=[join $goodList ,]"
    }
    if [llength $badList] {
        append option " -badElements=[join $badList ,]"
    }
    set tmpRoot /tmp/[APSTmpString]
    if [catch {eval exec convert_to_bdd \
                 $database -pipe=out -failedSubTrees=$tree  $option \
                 | sddssort -pipe -col=DIF,decreasing \
                 | sddsprocess -pipe=in \"-test=col,DIF 0 >\" \
                 $tmpRoot.$tree -nowarnings } result] {
        return -code error $result
    }
    set rows [exec sdds2stream -rows=bar $tmpRoot.$tree]
    if !$rows {
        APSAlertBox [APSUniqueName .] \
          -errorMessage "All base elements of $tree are claimed to be good! Some must be wrong for $tree to be faulted."
        return 1
    }
    set baseList [exec sdds2stream -col=Label $tmpRoot.$tree]
    set ok 1
    global baseDialogResponse BaseStatus baseText
    foreach base $baseList  {
	set BaseStatus [set ${base}(Status)]
	set baseDialogResponse 0
        ShowBaseElement -base $base
	tkwait variable baseDialogResponse
        if {$baseDialogResponse=="cancelled"} {
            SetMainStatus "Fault tree calculation was cancelled."
            return 0
        }
	if {$baseDialogResponse=="Next"} {
	    $baseText delete 1.0 end
	}
	set ${base}(Status) $BaseStatus
        set status [set ${base}(Status)]
        if {$status!="Good"} {
            set treeOK 0
            set ok 0
        }
    }
    if [winfo exist .base] {
	destroy .base
    }
    set widget ""
    if [info exist ${tree}(widget)] {
        set widget [set ${tree}(widget)]
    }
    if $ok {
        SetMainStatus "$tree has beed fixed."
        set $varName 0
        if [string length $widget] {
            $widget configure -selectcolor \#d9d9d9
        }
    } else {
        set $varName 1
        if [string length $widget] {
         #   $widget configure -selectcolor red
        }
    }
    
    SetMainStatus "$varName [set $varName]"
    file delete -force $tmpRoot.$tree
    return $ok
}

proc CheckTrees {args} {
    global database treeNames Top 
    eval global $treeNames
    set topOK 1
    
    foreach tree {rmFail hbError} {
        set labelList [set ${tree}(Label)]
        set varName1 [set ${tree}(varName)]
        global $varName1
        set treeOK 1
        foreach label $labelList {
            global $label
            set id [set ${label}(treeID)]
            if {$id<1000} {
                set varName [set ${label}(varName)]
                global $varName
                if [set $varName] {
                    set treeOK 0
                }
            } else {
                #base elements
                global $label
                set status [set ${label}(Status)]
                if {$status=="Fail"} {
                    set treeOK 0
                    set topOK 0
                }
            }
        }
        if $treeOK {
            set $varName1 0
        } else {
            set $varName1 1
            ChangeWidget -label $tree
            set topOK 0
        }
    }
    
    foreach tree {hvTrip largeRMS beamdump} {
        set varName [set ${tree}(varName)]
        global $varName
        set treeOK 1
        SetMainStatus "$tree [set $varName]"
        if [set $varName] {
            set topOK 0
        }
    }

    global fbopen rmsDsp
    #top base elements
    foreach base {fbopen rmsDsp} {
        set status [set ${base}(Status)]
        if {$status!=0 && [string compare $status "Good"]!=0} {
            set topOK 0
        }
    }
    if $topOK {
        set TopFailed 0
    } else {
        set TopFailed 1
    }
    return $topOK
}

proc ComputeTop {args} {
    global Top TopFailed database baseElements baseDialogResponse BaseStatus
    eval global $baseElements
    if !$TopFailed {
        SetMainStatus "Top tree is not selected."
        return
    }
    set goodList ""
    set badList ""
    foreach base $baseElements {
        set status [set ${base}(Status)]
        switch $status {
	    0 -
            Good {
                lappend goodList $base
            }
	    1 -
            Fail {
                lappend badList $base
            }
        }
    }
    set option ""
    if [llength $goodList] {
        append option " -goodElements=[join $goodList ,]"
    }
    if [llength $badList] {
        append option " -badElements=[join $badList ,]"
    }
    set tmpRoot /tmp/[APSTmpString]
    if [catch { eval exec /home/helios/SHANG/epics/extensions/src/SDDS/SDDSaps/O.linux-x86_64/convert_to_bdd \
                 $database -pipe=out -failedSubTrees=Top $option \
                  | sddssort -pipe -col=DIF,decreasing \
                  | sddsprocess -pipe=in \"-test=col,DIF 0 >\" \
                  $tmpRoot.top -nowarnings } result] {
        return -code error $result
    }
    set baseList [exec sdds2stream -col=Label $tmpRoot.top]
    set ok 1
    global baseDialogResponse 
    foreach base $baseList {
	set baseDialogResponse 0
	set BaseStatus ${base}(Status)
        ShowBaseElement -base $base
	tkwait variable baseDialogResponse
        if {$baseDialogResponse=="cancelled"} {
            SetMainStatus "Fault tree calculation was cancelled."
            return
        }
	set ${base}(Status) $BaseStatus
        set status [set ${base}(Status)]
        if {$status!="Good"} {
            set ok 0
	    if [regexp {rmsDsp} $base] {
		set ${base}(Status) 1
	    }
	    if [regexp {fbopen} $base] {
		set ${base}(Status) 1
	    }
        } else {
	    if [regexp {rmsDsp} $base] {
		set ${base}(Status) 0
	    }
	    if [regexp {fbopen} $base] {
		set ${base}(Status) 0
	    }
	}
    }
    if [winfo exist .base] {
	destroy .base
    }
    if $ok {
        set TopFailed 0
        SetMainStatus "Fault has been fixed."
    } else {
        set TopFailed 1
    }
    ChangeWidget -label Top
}

proc Compute {args} {
    global database treeNames TopFailed baseDialogResponse BaseStatus
    eval global $treeNames
   
    set ok [CheckTrees]
    if {$ok && !$TopFailed} {
        SetMainStatus "No fault tree found/checked."
        return
    }
    
    set topOK 1
    set tmpRoot /tmp/[APSTmpString]
    foreach tree {rmFail hbError} {
        set labelList [set ${tree}(Label)]
        set varName1 [set ${tree}(varName)]
        global $varName1
        if ![set $varName1] {
            continue
        }
        set treeOK 1
        foreach label $labelList {
            global $label
            set id [set ${label}(treeID)]
            if {$id<1000} {
                set varName [set ${label}(varName)]
                global $varName
                if [set $varName] {
                    if [catch {CheckSubTree -tree $label} ok] {
                        SetMainStatus "$ok."
                        return 1
                    }
                    if !$ok {
                        set treeOK 0
                    }
                }
            } else {
                #base elements
                global $label  baseDialogResponse BaseStatus
                set status [set ${label}(Status)]
		set BaseStatus $status
                if {$status!="Good" && $status!=0} {
                    ShowBaseElement -base $label
		    tkwait variable baseDialogResponse
		    set  ${label}(Status) $BaseStatus
                    set status [set ${label}(Status)]
                    if {$status!="Good" && $status!=0} {
                        set treeOK 0
                    } else {
                     #   set ${label}(Status) 0
                    }
                }
            }
        }
        if $treeOK {
            SetMainStatus "$tree has been fixed."
            set $varName1 0
            ChangeWidget -label $tree
        } else {
            set $varName1 1
            ChangeWidget -label $tree
            set topOK 0
        }
    }
    
    foreach tree {hvTrip largeRMS beamdump} {
        set varName [set ${tree}(varName)]
        global $varName
        SetMainStatus "$tree [set $varName]"
        if [set $varName] {
            set ok [CheckSubTree -tree $tree]
            if $ok {
                set $varName 0
            } else {
                set topOK 0
            }
            ChangeWidget -label $tree
        }
    }

    global fbopen rmsDsp
    #top base elements
    foreach base {fbopen rmsDsp} {
        set status [set ${base}(Status)]
        SetMainStatus "$base $status"
	set BaseStatus ""
        if {$status} {
            ShowBaseElement -base $base
	    tkwait variable baseDialogResponse
	    set ${base}(Status) $BaseStatus
            set status [set ${base}(Status)]
            if {$status!="Good"} {
                set topOK 0
		set ${base}(Status)  1
            } else {
                set ${base}(Status) 0
            }
            ChangeWidget -label $base
        }
    }
    if $topOK {
        SetMainStatus "Fault has been fixed."
        set TopFailed 0
        ChangeWidget -label Top
    } else {
        SetMainStatus "Fault has not been totally fixed."
        set TopFaile 1
        ChangeWidget -label Top
    }
    if [winfo exist .base] {
	destroy .base
    }
    SetMainStatus "done."
}

proc ShowBaseElement1 {args} {
    set base ""
    APSParseArguments {base prob}

    global $base baseDialogResponse 
    set baseDialogResponse 0
    APSDialogBox .base -name "$base checkout" \
      -cancelCommand "set baseDialogResponse cancelled" -okCommand "set baseDialogResponse ok"
   # APSLabel .prob -parent .base.userFrame -text "Fault probability: $prob."
    APSLabel .desc -parent .base.userFrame  -text "Description: [set ${base}(treeDesc)]"
    set labelList [split [set ${base}(guid)] "\n"]
    set maxLen 1
    set index 0
    foreach label $labelList {
        if !$index {
            set label "Guidance: [string trim $label]"
            set len [string length $label]
            set str   "         "
        } else {
            if [regexp {Action} $label] {
                set label [string trim $label]
                set str "       "
            } else {
                set label "$str [string trim $label]"
            }
            set len [string length $label]
            if {$len>$maxLen} {
                set maxLen $len
            }
        }
        set sform [format "%%%lds" $len]
        set result [format $sform $label]
        APSLabel .guid$index -parent .base.userFrame -text "$result"
        incr index
        puts $index
    }
   # APSLabel .guid -parent .base.userFrame  -text "Guidance: [set ${base}(guid)]\n"
    
    APSRadioButtonFrame .result -parent .base.userFrame -label "\nPlease check the result for $base after checking:" \
      -buttonList {No-problem/Failed-but-Fixed Unresolved} -valueList {Good Fail} \
      -variable ${base}(Status)
    
    tkwait variable baseDialogResponse
    
}

proc CreateBaseShowWidget {args} {
    global BaseStatus baseDialogResponse baseText
    toplevel .base
    wm title .base "Base checkout"
    set width 95
    set height 35
    frame .base.userFrame -relief raised -bd 2 -width $width -height 35
    pack .base.userFrame -side top -fill both -expand 1
    frame .base.userFrame.f1 -bd 2 -relief ridge
    pack .base.userFrame.f1 -fill both -expand 1 -side top
    text .base.userFrame.f1.text -width $width -height 8 -bd 1 -relief raised -setgrid 1 -wrap word \
	-yscrollcommand ".base.userFrame.f1.scroll set" -font "courier 11"
    set baseText .base.userFrame.f1.text 
    scrollbar .base.userFrame.f1.scroll -command ".base.userFrame.f1.text yview"
    pack .base.userFrame.f1.scroll -side right -fill y
    pack .base.userFrame.f1.text -side left -fill both -expand 1
    APSRadioButtonFrame .result -parent .base.userFrame -label "\nPlease check the result after checking:" \
	-buttonList {No-problem/Failed-but-Fixed Unresolved} -valueList {Good Fail} \
	-variable BaseStatus
    frame .base.userFrame.buttonRow  -relief raised -bd 2
    pack .base.userFrame.buttonRow  -side top -fill both -expand 1
    APSButton .ok -parent .base.userFrame.buttonRow -text NEXT \
	-command "set baseDialogResponse Next" -highlight 1 
    APSButton .cancel -parent .base.userFrame.buttonRow -text "Cancel" \
	-command "set baseDialogResponse cancelled;destroy .base"
    set grapList [grab current .base]
    focus .base
    catch {grab .base}
   # tkwait window .base
    catch {grab set $gradList}
}

proc ShowBaseElement {args} {
    set base ""
    APSParseArguments {base}
    global $base baseDialogResponse baseText
    if ![winfo exist .base] {
	CreateBaseShowWidget
    }
    wm title .base "$base checkout"
    $baseText delete 1.0 end
    $baseText insert end "Description: [set ${base}(treeDesc)]\n\n"
    set labelList [split [set ${base}(guid)] "\n"]
    set maxLen 1
    set index 0
    foreach label $labelList {
        if !$index {
            #$baseText insert end "Guidance: [string trim $label]\n\n"
	    set label "Guidance: [string trim $label]\n"
            set len [string length $label]
            set str   "         "
        } else {
            if [regexp {Action} $label] {
                set label [string trim $label]
                set str "       "
            } else {
                set label "$str [string trim $label]"
            }
            set len [string length $label]
            if {$len>$maxLen} {
                set maxLen $len
            }
        }
        set sform [format "%%%lds" $len]
        set result [format $sform $label]
	$baseText insert end "$result\n"
        incr index
    }
}


LoadDatabase -database $database

APSFrame .top -parent .userFrame -label "Top"
set ${topTree}(varName) ${topTree}Failed
checkbutton .userFrame.top.frame.but -text "[set ${topTree}(treeDesc)]" -variable ${topTree}Failed \
   -borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 -command "ChangeWidget -label $topTree"
pack .userFrame.top.frame.but
set ${topTree}Widget .userFrame.top.frame.but
ChangeWidget -label $topTree
APSFrame .second -parent .userFrame -label "Second level"
APSFrameGrid .grid -parent .userFrame.second.frame -yList {y1 y2}
set w1 .userFrame.second.frame.grid.y1
set w2 .userFrame.second.frame.grid.y2
set labelList ""
set treeIDList ""
set index 1

foreach tree $secondTree {
    if {$index>4} {
	set parent $w2
    } else {
	set parent $w1
    }
    set label [set ${tree}(treeName)]
    set id [set ${tree}(treeID)]
    set ${label}(varName) ${label}Failed
    set varName ${label}Failed
    if {$id>1000} {
        set text "[set ${tree}(treeDesc)](BASE)  "
        set ${label}(Status) 0
        set varName ${label}(Status)
    } else {
        set text "[set ${tree}(treeDesc)]   "
        lappend labelList "[set ${tree}(treeDesc)]"
        lappend treeIDList $tree
    }
    set ${tree}(varName) $varName
    checkbutton $parent.c$label -text $text -variable $varName \
	-borderwidth 1 -padx 0 -pady 0 -highlightthickness 0 -command "ChangeWidget -label $label;UpdateChild -type $label"
    pack $parent.c$label -side left
    set ${label}Widget $parent.c$label
    ChangeWidget -label $label
    incr index
}

set rmsDsp(Status) Unknown
proc CheckStatus {args} {
    global treeNames fbopen rmsDsp TopFailed offline
    eval global $treeNames
    set topValue 0

    if $offline {
        SetMainStatus "CheckStatus only does not work in offline, since it needs reading the PV values."
        return
    }
    SetMainStatus "Check tree status using PVs..."
    foreach tree $treeNames {
	
        set pvList [set ${tree}(treePV)]
        if [string length $pvList] {
            if [catch {exec cavget -list=[join $pvList ,] -pend=10 -printErrors } valList] {
                return -code error "Unable read $pvList: $valList"
            }
            set varName [set ${tree}(varName)]
            global $varName
            set val1 [string trim [string toupper [lindex $valList 0]]]
            set val2 [string trim [string toupper [lindex $valList 1]]]
            
            switch $val1 {
                "OK" {
                    set value 0
                }
                0 {
                    set value 0
                }
                default {
                    set value 1
                    set topValue 1
                }
            }
            if ![string length $val2] {
                set $varName $value
            } elseif {!$value} {
                switch $val2 {
                    "OK" {
                        set value 0
                    }
                    0 {
                        set value 0
                    }
                    default {
                        set value 1
                        set topValue 1
                    }
                }
                set $varName $value
            } else {
                set $varName 1
                set topValue 1
            }
        }
	UpdateChild -type $tree
    }
    
    if [catch {exec cavget -list=[join $fbopen(treePV) ,] -pend=10 -printErrors} valList] {
        return -code error "Unable read FB realtime status: $valList"
    }
    set h [lindex $valList 0]
    set v [lindex $valList 1]
    if {$h=="Open" || $v=="Open"} {
        set fbopen(Status) 1
        set topValue 1
    } else {
        set fbopen(Status) 0
    }
    set TopFailed $topValue
    SetMainStatus "done."
}


proc UpdateRMFromBase {args} {
    set sector ""
    set type ""
    set item ""
    APSParseArguments {sector type item}
    global $item  TopFailed rmFailFailed rmSectorList rmVarList TopWidget
    eval global $rmVarList
    set status [set ${item}(Status)] 
    if ![string length $sector] {
	set sector [scan $item ${type}%ld]
	if [catch {expr $sector/2} result] {
	    #sector is not a number
	    set sector dpbpm
	}
    }
    global rm${sector}
    set varname [set rm${sector}(varName)]
    set widget [set rm${sector}(widget)]
    global $varname $widget
    if {$status=="Fail"} {
	set $varname 1
	set rmFailFailed 1
	set TopFailed 1
    } else {
	#set $varname 0
	set value 0
	foreach label {Reboot rmFail rmCable} {
	    if {$label=="Reboot"} {
		set presector [getRMpresector -sector $sector]
		set var1 rm${presector}$label
	    } else {
		set var1 ${label}$sector
	    }
	    global $var1
	    set status [set ${var1}(Status)]
	    if {$status=="Fail"} {
		set $varname 1
		set value 1
		break
	    }
	    if {$status=="Unknown"} {
		set value 2
	    }
	}
	if {!$value} {
	    set $varname 0
	}
	if [set $varname] {
	    set TopFailed 1
	    set rmFailFailed 1
	} else {
	    #check all others, if one is bad, the parents are bad; otherwise, unselect parents also
	    set rmFailFailed 0
	    foreach var $rmVarList {
		if [set $var] {
		    set rmFailFailed 1
		    break
		}
	    }
	}
    }
  #  APSSRSectorButtonsClicked -widget $widget -var $varname -selectcolor maroon
    UpdateTop
    
}

proc SelectAll {args} {
    set type ""
    APSParseArguments {type}
    global rmVarList rmAll hbVarList hbAll
    eval global $rmVarList 
    eval global $hbVarList
    switch $type {
	rm {
	    foreach var $rmVarList {
		set $var $rmAll
		UpdateRMParentAndChild -var $var
	    }
	}
	hb {
	    foreach var $hbVarList {
		set $var $hbAll
		UpdateHBParentAndChild -var $var
	    }
	}
    }
    
}

proc UpdateRMParentAndChild {args} {
    set sector ""
    set var ""
    APSParseArguments {sector var}
    global rmSectorList  rmFail TopFailed $var rmFailFailed
    
    if ![string length $sector] {
	set sector [scan $var rm%ld]
	if [catch {expr $sector /2} result] {
	    set sector dpbpm
	}
    }
    if {$sector=="dp"} {
	set sector dpbpm
    }
    
    set presector [getRMpresector -sector $sector]
    global rm${presector}Reboot rmFail$sector rmCable$sector
    if [set $var] {
	set rmFailFailed 1
	set TopFailed 1
	set rm${presector}Reboot(Status) Unknown
	set rmFail${sector}(Status) Unknown
	set rmCable${sector}(Status) Unknown
    } else {
	set rmFailFailed 0
	foreach label $rmFail(Label) {
	    global $label
	    set var [set  ${label}(varName)]
	    eval global $var
	    if [set $var] {
		set rmFailFailed 1
		break
	    }
	}
	if $rmFailFailed {
	    set TopFailed 1
	}
	set rm${presector}Reboot(Status) Good
	set rmFail${sector}(Status) Good
	set rmCable${sector}(Status) Good
    }
    UpdateTop
}

#pv linkw fbopen(Status) SRFB:GBL:Hor:CloseLoopBO
#pv umon fbopen(Status) "ChangeWidget -label fbopen"
 set fbopen(treePV) "SRFB:GBL:Hor:CloseLoopBO SRFB:GBL:Vert:CloseLoopBO"
set rmsDsp(Status) 0
set frameIndex -1

lappend labelList "Datapool IOC"
lappend labelList "DSP"
set widgetList [APSTabFrame .tab -parent .userFrame -label "" \
                  -labelList $labelList \
                  -frameIndexVariable frameIndex -height 600 -width 800]

for {set i 0} {$i<[llength $widgetList]} {incr i} {
    set parent [lindex $widgetList $i]
    set tree [lindex $treeIDList $i]
  #  MakeTabWidget -parent $parent -tree $tree
}

MakeRMWidget .rm -parent [lindex $widgetList 0]
MakeHBWidget .hb -parent [lindex $widgetList 1]
MakeHVWidget .hv -parent [lindex $widgetList 2]
MakeRMSWidget .rms -parent [lindex $widgetList 3]
MakeBeamDumpWidget .beam -parent [lindex $widgetList 4]
MakeDatapoolIOCWidget .datapool -parent [lindex $widgetList 5]
MakeDSPWidget .dsp -parent [lindex $widgetList 6]

APSButton .check -parent .userFrame -text "Check Status" -command CheckStatus -contextHelp "check the status of middle levels that are connected to PVs."
#APSButton .but -parent .userFrame -text "Diagnosis" -command "Compute" -contextHelp "computing by known failed sub trees."
#APSButton .but1 -parent .userFrame -text "Compute Top Tree" -command "ComputeTop" -contextHelp "Compute the probability of base elements assuming all sub trees could be wrong."
#APSButton .but1 -parent .userFrame -text "Diagnosis" -command "ComputeTop" -contextHelp "computing by known failed sub trees."
APSButton .but2 -parent .userFrame -text "Diagnose" -command "Compute" -contextHelp "computing by known failed sub trees."
