#!/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

# $Log: not supported by cvs2svn $
# Revision 1.8 2012/01/25 shang
# added 12 turns configuration, and added TurnMarkerInterval parameter (column) to the configuration file.
# to set the turn marker interval to 3888 for 12 turns config.
#
# Revision 1.7  2011/01/26 17:34:55  shang
# made the sampleMode values to be consistent with IOC values.
#
# Revision 1.6  2011/01/26 15:41:02  shang
# changed the sample mode value of "bunchPattern" to "BunchPattern", because "BunchPattern" is one of the values of sample mode PV.
#
# Revision 1.5  2010/12/15 22:29:11  shang
# added "Generate1", "Install1" button to generate one configuration and install it; changed the "Generate All" button to generate
# configs for all presets, and fixed bugs in "Install All" button.
#
# Revision 1.4  2010/12/14 21:31:19  shang
# fixed a typo
#
# Revision 1.3  2010/12/14 21:14:29  shang
# replaced invalid command "setStatusText" by "SetStatus"
#
# Revision 1.2  2010/09/29 17:03:23  shang
# fixed a bug of "Install" button that presetsList variable was not defined.
#
# Revision 1.1  2010/09/29 16:44:55  shang
# first version for generating FPGA bpm waveforms.
#

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

proc SetStatus {text} {
    global status
    set status "[clock format [clock seconds] -format %H:%M:%S]  $text"
    update
}

proc GetConfiguration {args} {
    global iocList presetConfigurationData  presetConfigurationLabelList
    set tmpFile /tmp/[APSTmpString].config
    if [catch {exec sddsprocess /home/helios/oagData/SCR/requestFiles/SBPMWaveform.config $tmpFile \
                 -match=par,Location=Accel,BPMType=FPGA,&} result] {
        return -code error $result
    }
    
    if [catch {sdds load $tmpFile fpgaData} result] {
        return -code error $result
    }
    set iocList $fpgaData(Parameter.IOCName)
    set page 0
    foreach name $iocList {
        global $name
        set ${name}(bpmList) [lindex $fpgaData(Column.BPM) $page]
        incr page
    }

    unset fpgaData
    
    if [catch {exec sddsxref /home/helios/oagData/SCR/preferredChoices/SBPMWaveform.sdds \
                 /home/helios/oagData/sr/BPMcontrolRAM/presetConfigurations $tmpFile.presets \
                 -match=ChoiceName=Label -take=* -nowarnings } result] {
        return -code error $result
    }
    if [catch {sdds load $tmpFile.presets presetConfigurationData} result] {
        return -code error $result
    }
    set presetConfigurationLabelList [lindex $presetConfigurationData(Column.Label) 0]
    ReadTurnMarkerOffset
}

proc GetTurnsPerWrap {args} {
    global PlaneMode CommutationMode TurnsPerWrap TurnMarkerInterval
    
    set turns [expr ([regexp {[12]} $PlaneMode] + 1) * ([regexp {[12]} $CommutationMode] + 1)]
    if {$PlaneMode=="xy2"} {
        set turns 4
    }
    if {$PlaneMode=="xy1" && $CommutationMode=="ab1"} {
        set turns 2
    }
    if {$TurnMarkerInterval==3888} {
        set turns 1
    }
    set TurnsPerWrap $turns
    return $turns
}

set configChosen 0
proc SetConfiguration {args} {
    set index ""
    APSParseArguments {index}

    global presetConfigurationData  configuration scrReference configChosen
    global PlaneMode CommutationMode SampleMode BunchPattern SamplesPerBunch
    global TurnMarkerOffset TransitionDeadTime TurnsPerWrap TurnMarkerInterval
    set BunchPatternLabel [lindex [lindex $presetConfigurationData(Column.Label) 0] $index]
    SetStatus "$BunchPatternLabel was selected."
    
    set PlaneMode        [lindex [lindex $presetConfigurationData(Column.PlaneMode) 0] $index]
    set CommutationMode  [lindex [lindex $presetConfigurationData(Column.CommutationMode) 0] $index]
    set SampleMode       [lindex [lindex $presetConfigurationData(Column.SampleMode) 0] $index]
    set BunchPattern     [lindex [lindex $presetConfigurationData(Column.BunchPattern) 0] $index]
    set SamplesPerBunch  [lindex [lindex $presetConfigurationData(Column.SamplesPerBunch) 0] $index]
    set TurnMarkerInterval [lindex [lindex $presetConfigurationData(Column.TurnMarkerInterval) 0] $index]
    
    set TransitionDeadTime [lindex [lindex $presetConfigurationData(Column.TransitionDeadTime) 0] $index]
    set scrReference [lindex [lindex $presetConfigurationData(Column.Suffix) 0] $index]
    set TurnsPerWrap [GetTurnsPerWrap]
    set AccumulatorMode $PlaneMode
    if {$SampleMode=="single"} {
	set SampleMode Single
    }
    set configChosen 1
}

proc ReadTurnMarkerOffset {args} {
    global iocList TurnMarkerOffset
    
    if [catch {exec cavget -list=[join $iocList ,] -list=:TurnMarkerOffsetLO -pend=10 } valList] {
        return -code error $valList
    }
    foreach ioc $iocList val $valList {
        set TurnMarkerOffset($ioc) $val
    }
}

proc LoadTurnMarkerOffsetFromSCR {args} {
    global TurnMarkerOffset  ReadWaveformsFromSCR dialogBoxResponse snapDir
    SetStatus "Reading turn marker offset from SCR ..."
   
    set ReadWaveformsFromSCR(ShortFilename) ""
    set dialogBoxResponse 0
    APSDialogBox .diag  -cancelCommand "set dialogBoxResponse cancel" \
      -okCommand "set dialogBoxResponse ok"  -name "Select SCR"
    APSAddSCRDialog .scr -parent .diag.userFrame -system SBPMWaveform \
      -label "Choose SCR file for viewing" \
      -arrayName ReadWaveformsFromSCR \
      -defaultFile $ReadWaveformsFromSCR(ShortFilename)
    tkwait window .diag

    if {$dialogBoxResponse=="cancel"} {
        SetStatus "read SCR waveforms was cancelled."
        return
    }
    if ![string length $ReadWaveformsFromSCR(ShortFilename)] {
        SetStatus "No SCR file chosen."
        return
    }

    set tmpFile /tmp/[APSTmpString]
    if [catch {exec sddsprocess $snapDir/$ReadWaveformsFromSCR(ShortFilename) -match=col,ControlName=*TurnMarkerOffsetLO $tmpFile} result] {
        SetStatus "Error in obtaining turn marker offset from SCR: $result"
        return
    }
    set pvs [exec sdds2stream -col=ControlName $tmpFile]
    set values [exec sdds2stream -col=ValueString $tmpFile]
    foreach pv $pvs val $values {
        set ioc [regsub {:TurnMarkerOffsetLO} $pv ""]
        set TurnMarkerOffset($ioc) $val
    }
    update
}

proc LoadSCR {args} {
    global SnapshotFile snapDir
    if ![file exist $snapDir/$SnapshotFile] {
	SetStatus "$SnapshotFile does not exist."
	return
    }
    if ![APSYesNoPopUp "Are you sure to load $SnpshotFile into SCR?"] {
	return
    }
    SetStatus "Loading $snapDir/$SnapshotFile into IOC..."
    set logFile /tmp/[APSTmpString]
    if [catch {exec sddscasr -restore $snapDir/$SnapshotFile \
		   -logFile=$logFile - -pendIOTime=100 \
		   -waveform=directory=$snapDir,onefile,rootname=[file root $SnapshotFile],extension=.waveform.gz} result] {
	return -code error "Error in loading SCR: $result"
    }
    SetStatus "done."
}
set snapDir /home/helios/oagData/SCR/snapshots/SBPMWaveform
set SCRDescription ""
proc GenerateSnapshot {args} {
    set secondSample 0
    APSParseArguments {secondSample}
    global TurnMarkerOffset iocList PlaneMode CommutationMode BunchPattern SampleMode SamplesPerBunch \
      TransitionDeadTime TurnsPerWrap TurnMarkerInterval snapDir configuration env configChosen individualPlaneMode comments
    global SnapshotFile SCRDescription secondSampleDelay secondSamplesPerBunch forOperation
    set requestFile /home/helios/oagData/SCR/requestFiles/SBPMWaveform.req
    
    if {!$configChosen} {
        SetStatus "Preset was not chosen."
        return
    }
    
    SetStatus "Generating waveform..."
    set tmpRoot /tmp/[APSTmpString]
    set fileList ""
    if {$SampleMode=="BunchPattern"} {   
        set sampleMode bunchPattern=$BunchPattern
    } else {
        set sampleMode $SampleMode
    }
    set len [expr $TurnsPerWrap*$TurnMarkerInterval]
    if $len>=2048 {
        set offset [expr $len-2048]
    } else {
        for {set i 2} {$i<=12} {incr i} {
            set len0 [expr $i*$len]
            if $len0>=2048 {
                break
            }
        }
        set offset [expr $len0 - 2048]
    }
    set fileList ""
    SetStatus "Generating control RAMs..."
    if $secondSample {
        set secondSampleOpt "-secondSampleBunch=delay=$secondSampleDelay,samplesPerBunch=$secondSamplesPerBunch"
    } else {
        set secondSampleOpt ""
    }
    foreach ioc $iocList {
	if !$individualPlaneMode {
            if {$forOperation && ($ioc=="S1A" || $ioc=="S38A") } {
                #make S1A and S38A special for tune measurement, where S1A:P2, S38A:P2 -- single bunch x plane no commutation only
                # where S1A:P4, S38A:P4 -- single bunch y plane no commutation only
                if [catch {eval exec sddsgencontrolbits $tmpRoot.$ioc -scopeArrayLength=4096 -RAMArrayLength=3888 \
                             -turnsPerWrap=$TurnsPerWrap -controlRAMFile=$tmpRoot.$ioc.RAM \
                             -planeMode=$PlaneMode,x,$PlaneMode,y  -commutationMode=$CommutationMode \
                             $secondSampleOpt \
                             $secondSampleOpt \
                             \"-sampleMode=$sampleMode,single,$sampleMode,single\" -samplesPerBunch=$SamplesPerBunch \
                             -turnMarkerOffset=$TurnMarkerOffset($ioc) -transitionDeadTime=$TransitionDeadTime \
                             -scopeTriggerIndexOffset=$offset -turnMarkerInterval=$TurnMarkerInterval } result] {
                    return -code error "Error in generating controlbits for $ioc (operation): $result"
                }
            } else {
                if [catch {eval exec sddsgencontrolbits $tmpRoot.$ioc -scopeArrayLength=4096 -RAMArrayLength=3888 \
                             -turnsPerWrap=$TurnsPerWrap -controlRAMFile=$tmpRoot.$ioc.RAM \
                             -planeMode=$PlaneMode -commutationMode=$CommutationMode \
                             $secondSampleOpt \
                             \"-sampleMode=$sampleMode\" -samplesPerBunch=$SamplesPerBunch \
                             -turnMarkerOffset=$TurnMarkerOffset($ioc) -transitionDeadTime=$TransitionDeadTime \
                             -scopeTriggerIndexOffset=$offset -turnMarkerInterval=$TurnMarkerInterval} result] {
                    return -code error "Error in generating controlbits for $ioc: $result"
                }
            }
	} else {
	    set sector [scan $ioc S%ld]
	    if [regexp {A} $ioc] {
		set itemList {A:Pj A:P2 A:P3 A:P4}
	    } else {
		set itemList {B:P5 B:P4 B:P3 B:P2}
	    }
	    set planeMode ""
	    foreach item $itemList {
		set var fpgaS${sector}$item
		global $var
		if [set $var] {
		    set pl x
		} else {
		    set pl y
		}
		if ![string length $planeMode] {
		    set planeMode -planeMode=$pl
		} else {
		    append planeMode ,$pl
		}
	    }
	    if [catch {eval exec sddsgencontrolbits $tmpRoot.$ioc -scopeArrayLength=4096 -RAMArrayLength=3888 \
                         -turnsPerWrap=$TurnsPerWrap -controlRAMFile=$tmpRoot.$ioc.RAM \
                         $secondSampleOpt \
                         $planeMode -commutationMode=$CommutationMode \
                         \"-sampleMode=$sampleMode\" -samplesPerBunch=$SamplesPerBunch \
                         -turnMarkerOffset=$TurnMarkerOffset($ioc) -transitionDeadTime=$TransitionDeadTime \
                         -scopeTriggerIndexOffset=$offset -turnMarkerInterval=$TurnMarkerInterval} result] {
		return -code error "Error in generating controlbits for $ioc: $result"
	    }
	}
        if [catch {exec sddsprocess $tmpRoot.$ioc.RAM -reprint=par,WaveformPV,${ioc}:AcqControlSetWF -pipe=out \
                     | sddsconvert -pipe=in $tmpRoot.$ioc.RAM1 -retain=col,Index,Waveform -retain=par,Time,TimeStamp,WaveformPV 
            exec sddsprocess $tmpRoot.$ioc.RAM -reprint=par,WaveformPV,${ioc}:AcqControlGetWF -pipe=out \
                     | sddsconvert -pipe=in $tmpRoot.$ioc.RAM2 -retain=col,Index,Waveform -retain=par,Time,TimeStamp,WaveformPV } result] {
            retun -code error "Error in reprint waveformPV parameter: $result"
        }
        lappend fileList $tmpRoot.$ioc.RAM1 $tmpRoot.$ioc.RAM2
    }
    if [catch {eval exec sddscombine $fileList $tmpRoot.waveform} result] {
        return -code error "Error in combining waveforms: $result"
    }
    SetStatus "Saving SBPMWaveform ..."
    if $individualPlaneMode  {
        set desc "$comments $env(USER)"
    } else {
        if ![string length $SCRDescription] {
            set desc "$configuration $env(USER)"
        } else {
            set desc "$SCRDescription $env(USER)"
        }
    }
    if [catch {APSSaveMachine -machine SBPMWaveform -description "$desc" \
                   -routine 0  \
                   -pendIOTime 60 -pingTimeOut 100 \
                   -statusCallback SetStatus} result] {
        APSAlertBox [APSUniqueName .] -errorMessage "Error doing save: $result"
        return
    }
    set snapshot [file root [lindex $result 0]]
    SetStatus "$snapshot saved."
    SetStatus "Modifying waveforms ..."
    if [catch {exec sddsxref $tmpRoot.waveform $snapDir/$snapshot.waveform.gz -transfer=par,Time,TimeStamp \
                 -leave=* $snapDir/$snapshot.waveform -nowarnings} result] {
        return -code error "unable to transfer parameters: $result"
    }
    exec rm  $snapDir/$snapshot.waveform.gz
    catch {exec gzip  $snapDir/$snapshot.waveform}
    catch {exec chmod -w $snapDir/$snapshot.waveform}
    eval file delete -force [glob $tmpRoot.*]
    if [catch {sdds load $snapDir/$snapshot.gz snapData} result] {
        return -code error "Unable to load $snapshot."
    }
    SetStatus "Modifying snapshot ..."
    set valueList ""
    foreach name [lindex $snapData(Column.ControlName) 0] val [lindex $snapData(Column.ValueString)  0] {
        set ioc [lindex [split $name :] 0]
        if [regexp {CommutationMode} $name] {
            lappend valueList $CommutationMode
        } elseif [regexp {AccumulatorMode} $name] {
            if !$individualPlaneMode {
		lappend valueList $PlaneMode
	    } else {
		set sector [scan $name S%ld]
		set bpm [regsub S$sector $name ""]
		set bpm [regsub {:AccumulatorMode} $bpm ""]
		set var fpgaS${sector}$bpm
		global $var
		if [set $var] {
		    lappend valueList x
		} else {
		    lappend valueList y
		}
	    }
        } elseif [regexp {BunchPatternSO} $name] {
            lappend valueList "$BunchPattern"
        } elseif [regexp {PlaneMode} $name] {
	    if !$individualPlaneMode {
		lappend valueList $PlaneMode
	    } else {
		set sector [scan $name S%ld]
		set bpm [regsub S$sector $name ""]
		set bpm [regsub {:PlaneMode} $bpm ""]
		set var fpgaS${sector}$bpm
		global $var
		if [set $var] {
		    lappend valueList x
		} else {
		    lappend valueList y
		}
	    }
        } elseif [regexp {SampleMode} $name] {
            lappend valueList $SampleMode
        } elseif [regexp {SamplesPerBunchLO} $name] {
            lappend valueList $SamplesPerBunch
        } elseif [regexp {TransitionLO} $name] {
            lappend valueList $TransitionDeadTime
        } elseif [regexp {TurnMarkerIntervalLO} $name] {
            lappend valueList $TurnMarkerInterval
        } elseif [regexp {TurnMarkerOffsetLO} $name] {
            lappend valueList $TurnMarkerOffset($ioc)
        } elseif [regexp {TurnsPerWrapLO}  $name] {
            lappend valueList $TurnsPerWrap
        } else {
            lappend valueList $val
        }
    }
    set snapData(Column.ValueString) [list $valueList]
    
    SetStatus "Saving $snapshot ..."
    if [catch {sdds save $snapDir/$snapshot snapData} result] {
        return -code error "Unable to save data: $result"
    }
    SetStatus "compressing $snapshot..."
    catch {file delete $snapDir/$snapshot.gz}
    if [catch {exec gzip $snapDir/$snapshot} result] {
        return -code error "Error in gziping $snapshot."
    }
    set SnapshotFile $snapshot.gz
    SetStatus "new SCR file $SnapshotFile was generated."
    
    return $SnapshotFile
}

proc Install {args} {
    set all 0
    APSParseArguments {all}
    global SnapshotFile snapDir configuration snapshotList presetsList snapshot1 preset1
   # if ![info exist SnapshotFile] {
   #     SetStatus "No file was generated yet."
   #     return
   # }
    if !$all {
        if ![info exist snapshot1] {
            SetStatus "The snapshot generated by \"Generate1\" button was not generated."
            return
        }
        if ![string length $snapshot1] {
            SetStatus "No new snapshot generated."
            return
        }
        if ![APSYesNoPopUp "Are you sure to install $snapshot1  to $preset1?"] {
            SetStatus "Install to $preset1 was cancelled."
            return
        }
        SetStatus "Working on installation of preferred/reference file..."
        if [catch {APSSCRInstallPreferredFile -system SBPMWaveform -choice $preset1 \
                     -filename $snapshot1} result] {
            SetStatus "$result"
            return
        }
        set snapshot1 ""
        SetStatus "Preferred/reference $preset1 installed."
        return
    }
    if {![info exist snapshotList] || ![llength $snapshotList]} {
        SetStatus "No files generated."
        return
    }
    foreach snapshot $snapshotList preset $presetsList {
        if ![APSYesNoPopUp "Are you sure to install $snapshot  to $preset?"] {
            SetStatus "Install to $preset was cancelled."
            continue
        }
        SetStatus "Working on installation of preferred/reference file..."
        if [catch {APSSCRInstallPreferredFile -system SBPMWaveform -choice $preset \
                     -filename $snapshot} result] {
            SetStatus "Error in install $preset: $result"
            continue
        }
        SetStatus "Preferred/reference $preset installed."
    }
}

set TurnMarkerInterval 324

proc GenerateAll {args} {
    set all 0
    APSParseArguments {all}
    global configuration presetConfigurationLabelList snapshotList presetsList configChosen snapshot1 preset1 individualPlaneMode
    set snapshotList ""
    set presetsList ""
    
    if $all {
        set configuration [lindex $presetConfigurationLabelList 0]
        set type [lindex $configuration 0]
        set index 0
        foreach preset $presetConfigurationLabelList {
            SetStatus "Generating waveform for $preset ..."
            set configuration "$preset"
            SetConfiguration -index $index
            after 1000
            update
            set snapshot [GenerateSnapshot]
            lappend snapshotList $snapshot
            lappend presetsList $preset
            incr index
        }
    } else {
        if {!$configChosen} {
            SetStatus "Preset was not chosen."
            return
        }
        set snapshot  [GenerateSnapshot]
        set snapshot1 $snapshot
        set preset1 $configuration
    }
    SetStatus "done."
}

proc ReadPlaneConfig {args} {
    global fpgaItemList planeConfig srButtonParent
    if ![file exist $planeConfig] {
	SetStatus "$planeConfig does not exist."
	return
    }
    set varList [exec sdds2stream -col=variable $planeConfig]
    set planeList [exec sdds2stream -col=plane $planeConfig]
    foreach var $varList plane $planeList {
	global $var
	switch $plane {
	    x {
		set $var 1
	    } 
	    y {
		set $var 0
	    }
	}
	set index [scan $var fpgaS%ld]
	set item [regsub fpgaS${index} $var ""]
	set inx [lsearch $fpgaItemList $item]
	set widget $srButtonParent.sector$index.item$inx
	APSSRSectorButtonsClicked -widget $widget -var $var -selectcolor blue
	
	update
    }
}
set planeConfig /home/helios/oagData/sr/FPGAbpm/inputFiles/planeSelctionConfig.sdds
proc SavePlaneConfig {args} {
    global fpgaItemList planeConfig
    set configDir /home/helios/oagData/sr/FPGAbpm/inputFiles 
    set filename [APSNextGenerationedName -directory $configDir \
		      -name planeSelctionConfig.sdds-0000 -separator - -newFile 1]
    SetStatus "save plane config..."
    set oldDir [pwd]
    cd $configDir
    set index 1
    for {set sector 1} {$sector<41} {incr sector} {
	foreach item $fpgaItemList {
	    set var fpgaS${index}$item
	    global $var
	    if [set $var] {
		lappend planeList x
	    } else {
		lappend planeList y
	    }
	    lappend bpmList S${sector}$item
	    lappend sectorList $sector
	    lappend varList $var
	}
	incr index
    }
    if [catch {exec sddsmakedataset $configDir/$filename -col=BPMName,type=string -data=[join $bpmList ,] \
		   -col=plane,type=string -data=[join $planeList ,] \
		   -col=sector,type=long -data=[join $sectorList ,] \
		   -col=variable,type=string -data=[join $varList ,]} result] {
	return -code error $result
    }
    catch {exec rm $planeConfig}
    exec ln -s $filename $planeConfig
    cd $oldDir
    SetStatus "done."
}

set forOperation 0
proc CreateWidgets {args} {
    global iocList TurnMarkerOffset  presetConfigurationLabelList configuration
    global PlaneMode CommutationMode BunchPattern SampleMode SamplesPerBunch \
      TransitionDeadTime TurnsPerWrap TurnMarkerInterval individualPlaneMode forOperation
    set parent ""
    APSParseArguments {parent}
    
    set individualPlaneMode 0
    APSRadioButtonFrame .plane -parent $parent -label "Use plane selection defined in \"PlaneSelection\" tab for generating control bits?" \
	-buttonList {Yes No} -valueList {1 0} -orientation horizontal -variable individualPlaneMode \
	-contextHelp "if Yes, each bpm's plane mode is defined here, otherwise, the plane mode of all bpms is defined in tab \"Others\" where all bpms have the same plane mod."
    
    APSRadioButtonFrame .op -parent $parent -label "Generate for operation use?" -buttonList {Yes No} -valueList {1 0} \
      -variable forOperation -orientation horizontal \
      -contextHelp "for operation, S1A:P2 and S38A:P2 should be single bunch, x plane no commutation; S1A:P4 and S38A:P4 should be single bunch, y plane no commuation."
    APSComboboxFrame .preset -parent $parent -label "Configuration:" \
      -packOption "-fill x" \
      -textVariable configuration \
      -itemList $presetConfigurationLabelList \
      -width 60 \
      -editable 0 \
      -callback "SetConfiguration -index" \
      -contextHelp "Select a presets, the selecte preset defines the plane mode, sample mode ect. parameters for generating the
SBPMWaveform SCR references."
    
    
    set widgetList [APSTabFrame .tab -parent $parent -label "" \
                      -labelList {TurnMarkerOffset Others PlaneSelection} -width 950 -height 500]
    set w1 [lindex $widgetList 0]
    set w2 [lindex $widgetList 1]
    set w3 [lindex $widgetList 2]
    APSFrame .turn -parent $w1 -label "Turn Marker Offset"
    APSFrameGrid .grid -parent $w1.turn.frame -xList {a b c d}
    set aparent $w1.turn.frame.grid.a
    set bparent $w1.turn.frame.grid.b
    set cparent $w1.turn.frame.grid.c
    set dparent $w1.turn.frame.grid.d
    set wList [list $aparent $bparent $cparent $dparent]
    set index 0
    foreach ioc $iocList {
        if {$index<4} {
            set parent1 [lindex $wList $index]
        } else {
            set index 0
            set parent1 [lindex $wList $index]
        }
        APSLabeledEntry .s$ioc -parent $parent1 -label $ioc -textVariable TurnMarkerOffset($ioc) \
          -width 15
        incr index
    }
    set width 50
    #make other parameter's widget
    
    APSRadioButtonFrame .planeMode -parent $w2 \
      -label "Plane Mode" -variable PlaneMode \
      -orientation horizontal \
      -buttonList [list x y "x/y every turn" "x/y every two turns"] \
      -valueList "x y xy1 xy2" \
      -contextHelp "Select how the plane switch should vary."  \
      -commandList {"GetTurnsPerWrap" "GetTurnsPerWrap" "GetTurnsPerWrap" "GetTurnsPerWrap"}
    
    APSRadioButtonFrame .sampleMode -parent $w2 \
      -label "Sample Mode" -variable SampleMode \
      -orientation horizontal \
      -buttonList [list Continuous Single "Bunch Pattern"] \
      -valueList [list Continuous Single BunchPattern] \
      -contextHelp "Select the sample mode. \"Bunch pattern\" refers to the bunch pattern (also known as fill pattern) in the bunch pattern entry box." 
    APSRadioButtonFrame .commutationMode -parent $w2 \
      -label "Commutation Mode" -variable CommutationMode \
      -orientation horizontal \
      -buttonList [list 0 180 "0/180 every turn" "0/180 every two turns"] \
      -valueList "a b ab1 ab2" \
      -contextHelp "Select how the 0/180 phase shifter commutation switch should vary." \
      -commandList {"GetTurnsPerWrap" "GetTurnsPerWrap" "GetTurnsPerWrap" "GetTurnsPerWrap"}
    APSLabeledEntry .transitionDeadTime -parent $w2 \
      -label "Transition Dead time (clock cycles)" -textVariable TransitionDeadTime \
      -contextHelp "Enter a value for transition dead time cycles, the time the state of the ADC output is unknown." -width $width
    
    APSLabeledEntry .bunchPattern -parent $w2 \
	-label "Bunch Pattern:" -textVariable BunchPattern \
      -contextHelp "Enter a name for the bunch pattern. Must be one of the presets of SRBunchTrain." -width $width
    APSLabeledEntry .samples -parent $w2 \
      -label "Samples per Bunch" -textVariable SamplesPerBunch \
      -contextHelp "Enter an integer value for samples per bunch, e.q. 5." -width $width
    APSLabeledEntry .wrap -parent $w2 \
      -label "Turns per wrap:" -textVariable TurnsPerWrap -width $width \
      -contextHelp "the number of turns of the repetition period."
    APSLabeledEntry .interval -parent $w2 \
      -label "Turn marker interval:" -textVariable TurnMarkerInterval -width $width \
      -contextHelp "TurnMarkerInterval of one turn, e.q. 324."
    global SCRDescription secondSampleDelay secondSamplesPerBunch
    set secondSampleDelay 141
    set secondSamplesPerBunch 30
    APSLabeledEntry .desc -parent $w2 -label "SCR description:" -textVariable SCRDescription -width 80 \
      -contextHelp "enter the description for generating SCR snapshots."
    APSLabeledEntry .secondsampledelay -parent $w2 -label "Second sample delay" -textVariable secondSampleDelay -width $width
    APSLabeledEntry .secondsamples -parent $w2 -label "Second samples per bunch" -textVariable secondSamplesPerBunch -width $width

    APSButton .load -parent $parent -text "Read TurnMarkerOffset from SCR" -command "LoadTurnMarkerOffsetFromSCR" \
        -contextHelp "load turn marker offset from selected SCR file."
    APSButton .gen -parent $parent -text "Generate1" -command "GenerateAll -all 0" \
        -contextHelp "generating timing control in SCR format for selected configuration."
    APSButton .install1 -parent $parent -text "Install1" -command "Install -all 0" \
	-contextHelp "install the generated SCR file by \"Generate1\" button as reference for selected configuration."
    APSButton .load1 -parent $parent -text "Load" -command "LoadSCR" \
	-contextHelp "load freshly created SCR into ioc."
    APSButton .all -parent $parent -text "Generate All" -command "GenerateAll -all 1" \
        -contextHelp "Generating waveform for all patterns."
    APSButton .install -parent $parent -text "Install All" -command "Install -all 1" \
      -contextHelp "install the generated SCR files generated by \"Generate All\" button as reference."

    APSButton .sec -parent $parent -text "Generate with second sample" -command "GenerateSnapshot -secondSample 1"
    
    #make plane selection
    APSLabel .label -parent $w3 -text "Use following check buttons to select x/y plane for each bpm,\n\ blue (select) for x plane, grey (deselect) for y plane"
    global planeSelVarList fpgaItemList planeConfig srButtonParent
    set fpgaItemList {A:Pj A:P2 A:P3 A:P4 B:P5 B:P4 B:P3 B:P2}
    #set index 1
    for {set sector 1} {$sector<=40} {incr sector} {
	foreach bpm $fpgaItemList {
	    lappend planeSelVarList fpgaS${sector}$bpm
	}
	#incr 1
    }
    APSFrame .f1 -parent $w3 
    APSFrame .f2 -parent $w3
    
    set f1 $w3.f1.frame
    set f2 $w3.f2.frame
    $f1 configure -bd 0
    $f2 configure -bd 0
    APSSRSectorButtons .plane -parent $f1 -rootname fpga -orientation horizontal -label "" -color0 blue \
	-itemList $fpgaItemList -sectorControl 1 -itemLabelList $fpgaItemList
    set srButtonParent $f1.plane.frame.f1
    APSLabeledEntry .config -parent $f2 -label "Read Config:" -textVariable planeConfig \
	-width 70 -contextHelp "read plane selection from file."
    APSLabeledEntry .comment -parent $f2 -label "Comments:" -textVariable comments -width 70
    APSButton .read -parent $f2.config -packOption "-side right" -text "Read" -command ReadPlaneConfig -size small
    APSButton .save -parent $f2.config -packOption "-side right" -text "Save" -command SavePlaneConfig -size small
    if [file exist $planeConfig] {
	ReadPlaneConfig
    }
}

set status ""

APSApplication . -name "FPGABpmWaveformConfig" \
  -version $CVSRevisionAuthor \
  -overview "FPGA bpm waveform configuration generator."

APSScrolledStatus .status -parent .userFrame -textVariable status -width 70 \
    -height 8 -packOption "-fill both -expand true"

GetConfiguration
CreateWidgets -parent .userFrame
