#!/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)]
APSStandardSetup

set env(EPICS_CA_AUTO_ADDR_LIST) YES
set env(EPICS_CA_ADDR_LIST) ""
wm geometry . +10+10

#set configDir /home/helios/oagData/sr/BPLDs/config
set configDir /home/oxygen/SHANG/APSU_test/BPLD_Config
set configDir /home/oxygen/DIAG/apsu/BPLD/BPLD_Config

proc SetStatus {text} {
    global bmBPMConfigStatus 
    set bmBPMConfigStatus "$text"
    update
}

set bmBPMConfigStatus "Note: 1) there must be 4 ID bpms in each sector\n       2) BM BPMs can not use ID BPMs."

proc SaveConfig {args} {
    set configFile ""
    APSParseArguments {configFile}
    global sectorList itemList description IDitemList configDir
    
    set dir $configDir
    if ![string length $configFile] {
	set filename BPLDConfig-[clock format [clock seconds] -format %Y-%j-%m%d:%H%M%S]
    } else {
	set filename $configFile
    }
   
    set bpmList ""
    set IDvalList ""
    set BMvalList ""
    set deviceList ""
    set error 0
    set msg ""
    foreach sector $sectorList {
	set IDcount 0
	set Sector [scan $sector S%d]
	set n1BPcount 0
	set n1APcount 0
	set n2BPcount 0
	set n2APcount 0
	foreach item $itemList {
	    set idname idBPM$sector$item
	    set bmname bmBPM$sector$item
	    global $idname $bmname
	    
	    lappend BMvalList [set $bmname]
	    lappend IDvalList [set $idname]
	    
	    if [set $idname] {
		incr IDcount
	    }
	    set n $Sector
	    if {$sector=="S01"} {
		set n1 40
	    } else {
		set n1 [expr $Sector-1]
	    }
	    set n2 [expr $Sector+1]
	    set str [string range $item 0 2]
	    switch $str {
		"n-1" {
		    set item [string replace $item 0 2 [format %02d $n1]]
		    if [set $idname] {
			incr n1BPcount
		    }
		}
		"n+1" {
		    set item [string replace $item 0 2 [format %02d $n2]]
		    if [set $idname] {
			incr n2APcount
		    }
		}
		default {
		    set item [regsub "n" $item [format %02d $n]]
		    if  [set $idname] {
			if [regexp {AP} $item] {
			    incr n1APcount
			} elseif [regexp {BP} $item] {
			    incr n2BPcount
			}
		    }
		}
	    }
	    lappend bpmList S$item
	    set item [regsub "AP" $item A:P]
	    set item [regsub "BP" $item B:P]
	    lappend deviceList S$item
	}
	if {$IDcount!=4} {
	    append msg "Error: $sector ID bpms !=4, you must select 4 bpms for each ID sector!\n"
	    SetStatus $msg
	    return
	}
	if {$n1BPcount==2 || $n1APcount==2} {
	    SetStatus "Error: both bpms for $sector ID1 are on same side!"
	    return
	}

	if {$n2BPcount==2 || $n2APcount==2} {
	    SetStatus "Error: both bpms for $sector ID2 are on same side!"
	    return
	}
    }
    if $error {
	SetStatus $msg
	return
    }
    if [catch {exec sddsmakedataset -pipe=out \
		   -par=Description,type=string "-data=[APSMakeSafeQualifierString $description]" \
		   -col=BPM,type=string -data=[join $bpmList ,] \
		   -col=DeviceName,type=string -data=[join $deviceList ,] \
		   -col=IDBPM,type=short -data=[join $IDvalList ,] \
		   -col=BMBPM,type=short -data=[join $BMvalList ,] \
		   | sddsxref -pipe=in $dir/BPLD_BPM_config.sdds $dir/$filename -match=BPM -leave=BPM } result] {
	return -code error "Error creating config file: $result"
    }
    
    set oldDir [pwd]
    catch {exec rm $dir/config.sdds}
    cd $dir
    exec ln -s $filename config.sdds
    cd $oldDir
    SetStatus "config saved to $filename"
    if ![APSYesNoPopUp "Write saved configuration into firmware?"] {
	return
    }
    if [catch {WriteConfig} result] {
	return -cod error "Error writing config into firmware: $result"
    }
    SetStatus "config writed to firm ware."
}

proc ReadConfig {args} {
    
    global BPLD itemList bmBPMCBWidget idBPMCBWidget sectorList configDir

    set tmpFile /tmp/[APSTmpString]
    APSAddToTmpFileList -ID bmbpld -fileList "$tmpFile.id $tmpFile.bm"
    set configFile $configDir/config.sdds
    
    APSSetSRSectorButtons -mode all-off -rootname bmBPM  -itemList $itemList -sectorList $sectorList
    APSSetSRSectorButtons -mode all-off -rootname idBPM  -itemList $itemList -sectorList $sectorList

    foreach sector $sectorList {
	set sector0 [scan $sector S%d]
	if [catch {exec sddsprocess $configFile $tmpFile.id -filter=col,IDBPM,0.5,1.5 -filter=col,BPLDSector,$sector0,$sector0 -nowarnings
	    exec sddsprocess $configFile $tmpFile.bm -filter=col,BMBPM,0.5,1.5 -filter=col,BPLDSector,$sector0,$sector0 -nowarnings } result] {
	    continue
	    return -code error "Error process config file1: $result"
	}
	set idList [exec sdds2stream -col=BPLDIndex $tmpFile.id]
#	puts "$sector $idList"
	set bmList [exec sdds2stream -col=BPLDIndex $tmpFile.bm]
	foreach index $idList {
	    set item [lindex $itemList [expr $index -1]]
	    set name idBPM$sector$item
	    global $name
	    $idBPMCBWidget($sector$item) invoke
	}
	foreach index $bmList {
	    set item [lindex $itemList [expr $index -1]]
	    set name bmBPM$sector$item
	    global $name
	    $bmBPMCBWidget($sector$item) invoke
	}
    }
    
}

proc CreateSpecialConfig {args} {
    set up P0
    set down P0
    APSParseArguments {up down}

    global sectorList idBPMCBWidget itemList configDir
    set configFile BPLDConfig-IDUp${up}Down${down}.sdds
   
    APSSetSRSectorButtons -mode all-off -rootname idBPM  -itemList $itemList -sectorList $sectorList
    
    switch $up {
	P0 {
	    set item1 {n-1BP0 nBP0}
	}
	P1 {
	    set item1 {n-1BP1 nBP1}
	}
    }
    switch $down {
	P0 {
	    set item2 {nAP0 n+1AP0}
	}
	P1 {
	    set item2 {nAP1 n+1AP1}
	}
    }
    set itemList1 [concat $item1 $item2]
    foreach sector $sectorList {
	foreach item $itemList1 {
	    set name idBPM$sector$item
	    global $name
	   # set $name 1
	    $idBPMCBWidget($sector$item) invoke
	}
    }
    set save 1
    if [file exist $configDir/$configFile] {
	if ![APSYesNoPopUp "$configFile already exist, overwrite it?"] {
	    SetStatus "$configFile already exist!"
	    set save 0
	}
    }
    if $save {
	SaveConfig -configFile $configFile
    }
    cd $configDir
    catch {exec rm config.sdds}
    exec ln -s $configFile config.sdds
    SetStatus "config.sdds is switched to $configFile."
    
}

proc WriteConfig {args} {
    global SectorList configDir
    #only three sectors available now
    #P0 distance 2.756
    #P1 distance 3.213
    set L(P0) 2.756
    set L(P1) 3.213
    set sectorList {1 3 5}
    set configFile $configDir/config.sdds
    #if ![APSYesNoPopUp "Write saved configuration into firmware?"] {
#	return
 #   }
    
    #if [catch {SaveConfig} result] {
#	return -code error "Error save current config: $result"
 #   }
    set tmpRoot /tmp/[APSTmpString] 
    
    set pvList ""
    set valList ""
    APSAddToTmpFileList -ID bpld -fileList "$tmpRoot.1 $tmpRoot.load"
    foreach sector $sectorList {
	set sectorf [format %02d $sector]
	if [catch {exec sddsprocess $configFile -filter=col,BPLDSector,$sector,$sector -filter=col,IDBPM,0.5,1.5 $tmpRoot.1 } result] {
	    return -code error "Error process data for sector $sector: $result"
	}
	set bpmList [exec sdds2stream -col=DeviceName $tmpRoot.1]
	set indexList [exec sdds2stream -col=BPLDIndex $tmpRoot.1]
	for {set i 1} {$i<=4} {incr i} {
	    set bpm$i [lindex $bpmList [expr $i-1]]
	    set index$i [lindex $indexList [expr $i-1]]
	}

	lappend pvList S${sectorf}-LMPS:BPLD:ID1:BPM-XY1_idx-SP
	lappend valList $index1
	lappend pvList S${sectorf}-LMPS:BPLD:ID1:BPM-XY2_idx-SP
	lappend valList $index2
	lappend pvList S${sectorf}-LMPS:BPLD:ID2:BPM-XY1_idx-SP
	lappend valList $index3
	lappend pvList S${sectorf}-LMPS:BPLD:ID2:BPM-XY2_idx-SP
	lappend valList $index4

	lappend pvList S${sectorf}-LMPS:BPLD:ID1:S1-SP
	if [regexp {P0} $bpm1] {
	    lappend valList -$L(P0)
	} elseif [regexp {P1} $bpm1] {
	    lappend valList -$L(P1)
	} else {
	    return -code error "invalid bpm - $bpm1 found!"
	}
	lappend pvList S${sectorf}-LMPS:BPLD:ID1:S2-SP
	if [regexp {P0} $bpm2] {
	    lappend valList $L(P0)
	} elseif [regexp {P1} $bpm2] {
	    lappend valList $L(P1)
	} else {
	    return -code error "invalid bpm - $bpm2 found!"
	}
	
	lappend pvList S${sectorf}-LMPS:BPLD:ID2:S1-SP
	if [regexp {P0} $bpm3] {
	    lappend valList -$L(P0)
	} elseif [regexp {P1} $bpm3] {
	    lappend valList -$L(P1)
	} else {
	    return -code error "invalid bpm - $bpm3 found!"
	}
	lappend pvList S${sectorf}-LMPS:BPLD:ID2:S2-SP
	if [regexp {P0} $bpm4] {
	    lappend valList $L(P0)
	} elseif [regexp {P1} $bpm4] {
	    lappend valList $L(P1)
	} else {
	    return -code error "invalid bpm - $bpm4 found!"
	}
    }
   # puts $tmpRoot.load
    if [catch {exec sddsmakedataset -col=ControlName,type=string -data=[join $pvList ,] \
		   -col=ValueString,type=string -data=[join $valList ,] $tmpRoot.load } result] {
	return -code error "Error creating load file: $result"
    }
    if [catch {exec sddscasr -restore $tmpRoot.load} result] {
	return -code error "Error writing config to firmware: $result"
    }
    SetStatus "Current configuration is loaded to firmware."

}

#########################following are GUI code#####################
APSApplication . -name SRBPLDBPMConfiguration -version 1 \
  -overview {.}


APSScrolledStatus .scrolled -parent .userFrame \
    -textVariable bmBPMConfigStatus \
    -width 85 -height 10 -lineLimit 1000 -label ""

set w1 .userFrame
for {set i 1} {$i<40} {incr i 2} {
    lappend sectorList S[format %02d $i]
}

set itemLabelList ""
set indexList ""
for {set i 1} {$i<=28} {incr i} {
    lappend indexList $i
}

set IDitemList {n-1BP1 n-1BP0 nAP0 nAP1 nBP1 nBP0 n+1AP0 n+1AP1}
set itemLabelList {n-1AP5 n-1AP6 n-1BP6 n-1BP5 n-1BP4 n-1BP3 n-1BP2 n-1BP1 n-1BP0 \
		       nAP0 nAP1 nAP2 nAP3 nAP4 nAP5 nAP6 nBP6 nBP5 nBP4 nBP3 nBP2 nBP1 nBP0 \
		       n+1AP0 n+1AP1 n+1AP2 n+1AP3 n+1AP4}

set itemList $itemLabelList
set IDMissingList ""
set BMMissingList ""
foreach sector $sectorList {
    foreach item $itemList {
	set idBPM$sector$item 0
	if { [regexp {P0} $item] || [regexp {P1} $item]} {
	    if [regexp {P0} $item] {
		set idBPM$sector$item 1
	    }
	    lappend BMMissingList $sector$item
	    continue
	} else {
	    lappend IDMissingList $sector$item
	}
    }
}
#only P1 and P0s are allowed for ID
#puts $BMMissingList

APSSRSectorButtons .bpm -parent $w1 -rootname idBPM -allButtons 0 \
    -label "BPLD ID BPM Configuration"  -sectorList $sectorList -orientation horizontal \
    -itemList $itemList -itemLabelList $itemLabelList -description "BPLD ID BPM Config" \
    -sectorControl 0 -packOption "-side top" -globalButtons 0 -missingList $IDMissingList

APSSetSRSectorButtons -mode all-off -rootname IDBPM  -itemList $itemList -sectorList $sectorList

set description ""
APSLabeledEntry .desc -parent .userFrame -label "Description: " -width 75 -textVariable description

APSButton .read -parent .userFrame -text "Read Config" -command ReadConfig
APSButton .save -parent .userFrame -text "Save Config" -command SaveConfig
APSButton .write -parent .userFrame -text "Write Config to Firmware" -command WriteConfig
APSButton .p0 -parent .userFrame -text "All P0s (ID)" -command "CreateSpecialConfig -up P0 -down P0"
APSButton .p1 -parent .userFrame -text "All P1s (ID)" -command "CreateSpecialConfig -up P1 -down P1"
APSButton .p01 -parent .userFrame -text "UpP0 DownP1 (ID)" -command "CreateSpecialConfig -up P0 -down P1"
APSButton .p11 -parent .userFrame -text "UpP1 DownP0 (ID)" -command "CreateSpecialConfig -up P1 -down P0"

ReadConfig
