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

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

APSApplication . -name SnapshotSequenceRestore -version $CVSRevisionAuthor \
      -overview "This application takes as input a snapshot sequence file created by SnapshotSequenceRecorder.  It then sequentially restores each snapshot in the sequence."


#
# This procedure is run just after APSFileSelectDialog is run.
# It completes the process of picking the snapshot sequence.
# It reads some data from the snapshot sequence, just as the
# sequence description and the list of snapshots.
#

proc ReadSequenceFile {args} {
    set sequenceFile ""
    set statusCallback APSNoOp
    APSStrictParseArguments {sequenceFile statusCallback descriptionWidget sequenceDescriptionWidget}
    eval $statusCallback {"Reading sequence file $sequenceFile"}
    if [catch {sdds open $sequenceFile r} fid] {
        return -code error "ReadSequenceFile: $fid"
    }
    if [catch {sdds getParameter $fid SequenceDescription -page 0} SequenceDescription] {
        return -code error "ReadSequenceFile: $SequenceDescription"
    }
    set SequenceDescription [lindex $SequenceDescription 0]
    foreach item {Type Description Snapshot System PreStepPause PostStepPause} {
        global ${item}List ${item}
        if [catch {sdds getColumn $fid $item -page 0} ${item}List] {
            return -code error "ReadSequenceFile: [set ${item}List]"
        }
        set ${item} [lindex [set ${item}List] 0]
    }
    global sequenceStep sequenceSteps
    set sequenceStep 0
    set sequenceSteps [llength $TypeList]

    $descriptionWidget insert end "$Description"
    $sequenceDescriptionWidget insert end "$SequenceDescription"
    eval $statusCallback {"Ready."}
}

proc ResetSequence {args} {
    global sequenceStep sequenceSteps descriptionWidget DescriptionList
    if {$sequenceStep==$sequenceSteps} {
        set sequenceStep 0
        $descriptionWidget delete 1.0 end
        $descriptionWidget insert end [lindex $DescriptionList $sequenceStep]
    }
}

# makes widgets for showing information about the next
# sequence step.

proc MakeSequenceStepWidgets {widget args} {
    set parent ""
    APSStrictParseArguments {parent}
    
    APSFrame $widget -parent $parent -label "Next Sequence Step" 
    set w $parent$widget.frame
    APSFrame .descr -parent $w -label "Snapshot Step Description:" -relief flat 
    APSScrolledText .snapDescr -parent $w.descr.frame -name "Snapshot Step Description" \
      -width 60 -height 3 
    global descriptionWidget 
    set descriptionWidget $w.descr.frame.snapDescr.text

    global PreStepPause PostStepPause Type
    APSLabeledOutput .prestepPause -parent $w -label "Pre-Step Pause (s): " \
      -width 30 -textVariable PreStepPause -contextHelp \
      "For automatic sequence mode, shows the pause prior to executing the step."
    APSLabeledOutput .poststepPause -parent $w -label "Post-Step Pause (s): " \
      -width 30 -textVariable PostStepPause -contextHelp \
      "For automatic sequence mode, shows the pause after executing the step."
    APSLabeledOutput .type -parent $w -label "Type: " \
      -width 30 -textVariable Type -contextHelp \
      "Type is either snapshot or breakpoint.  A breakpoint is a null operation that causes a pause during automatic sequencing."
}

proc MakeActionButtons {widget args} {
    set parent ""
    APSStrictParseArguments {parent}

    APSFrame $widget -parent $parent -label "" 
    set w $parent$widget.frame

    APSButton .restoreNext -parent $w -text "Restore Next" \
      -command "RestoreSequence -oneStep 1 -widgetRoot $w" \
      -contextHelp "Restores the next snapshot, which is described above.  After restoring, the script waits for user input again."
    APSButton .restoreRest -parent $w -text "Restore Remainder" \
      -command "RestoreSequence -widgetRoot $w" \
      -contextHelp "Sequentially restores all of the remaining snapshots in the sequence.  Unless there are breakpoints in the sequence, this is done without stopping for user input."
    APSButton .abort -parent $w -text "Abort" -command "AbortRestoration -widgetRoot $w" \
      -contextHelp "Aborts restoration of a snapshot or a sequence."
    APSButton .pause -parent $w -text "Pause" -command "PauseRestoration -widgetRoot $w" \
      -contextHelp "Pauses restoration of a sequence."
    APSButton .resume -parent $w -text Resume -command "ResumeRestoration -widgetRoot $w" \
      -contextHelp "Resumes restoration of a sequence."
    APSButton .resetSequence -parent $w -text Reset -command "ResetSequence" \
      -contextHelp "Resets a sequence to allow running it again."
    APSDisableButton $w.abort.button 
    APSDisableButton $w.pause.button 
    APSDisableButton $w.resume.button
    global abortRestoration pauseRestoration
    set abortRestoration 0
    set pauseRestoration 0
}

proc RestoreSequence {args} {
    set oneStep 0
    set widgetRoot ""
    APSStrictParseArguments {widgetRoot oneStep}
    global sequenceStep sequenceSteps pauseRestoration abortRestoration descriptionWidget
    set pauseRestoration 0
    set abortRestoration 0
    APSEnableButton $widgetRoot.pause.button
    APSDisableButton $widgetRoot.resume.button
    APSEnableButton $widgetRoot.abort.button
    APSDisableButton $widgetRoot.restoreNext.button 
    APSDisableButton $widgetRoot.restoreRest.button 
    set tmpFile /tmp/[APSTmpString]
    APSAddToTempFileList $tmpFile
    while {$sequenceStep<$sequenceSteps} {
        foreach item {Type Description Snapshot System PreStepPause PostStepPause} {
            global ${item}List ${item}
            set $item [lindex [set ${item}List] $sequenceStep]
        }
        $descriptionWidget delete 1.0 end
        $descriptionWidget insert end "$Description"
        if $abortRestoration break
        if $PreStepPause>0 {
            APSSetVarAndUpdate status "Executing Pre-Step Pause of $PreStepPause seconds"
            APSWaitWithUpdate -waitSeconds $PreStepPause -updateInterval 1 \
              -abortVariable abortRestoration
        }
        if $abortRestoration break
        if $pauseRestoration {
            APSSetVarAndUpdate status "Paused...press Resume to continue."
            WaitForResume
            APSSetVarAndUpdate status Resumed.
        }
        if $abortRestoration break
        if [string compare $Type breakpoint]==0 {
            PauseRestoration -widgetRoot $widgetRoot
            APSSetVarAndUpdate status "Paused for breakpoint...press Resume to continue."
            WaitForResume
            APSSetVarAndUpdate status Resumed.
        } else {
            APSSetVarAndUpdate status "Restoring snapshot $Snapshot..."
            if [catch {exec sddsconvert $Snapshot $tmpFile -delete=column,ControlMode
                    exec sddscasr -restore $tmpFile} result] {
                APSSetVarAndUpdate status "Error: $result"
                if {![APSMultipleChoice [APSUniqueName .] \
                        -question "Error occurred. Now what?" \
                        -labelList {Abort Continue} -returnList {0 1}]} {
                    APSSetVarAndUpdate status "Aborted due to error."
                    break
                }
            }
        }
        incr sequenceStep
        if $abortRestoration break
        if $PostStepPause>0 {
            APSSetVarAndUpdate status "Executing Post-Step Pause of $PostStepPause seconds"
            APSWaitWithUpdate -waitSeconds $PostStepPause -updateInterval 1 \
              -abortVariable abortRestoration
        }
        if $oneStep break
    }
    if $abortRestoration {
        APSSetVarAndUpdate status "Aborted."
    } 
    if {$sequenceStep==$sequenceSteps} {
        APSSetVarAndUpdate status "End of sequence."
    }
    APSDisableButton $widgetRoot.pause.button
    APSDisableButton $widgetRoot.resume.button
    APSDisableButton $widgetRoot.abort.button
    APSEnableButton $widgetRoot.restoreNext.button 
    APSEnableButton $widgetRoot.restoreRest.button 
}

proc WaitForResume {} {
    global pauseRestoration abortRestoration
    while 1 {
        after 1000
        update
        if {!$pauseRestoration || $abortRestoration} {
            break
        }
    }
}

proc AbortRestoration {args} {
    set widgetRoot ""
    APSStrictParseArguments {widgetRoot}
    global abortRestoration pauseRestoration
    APSDisableButton $widgetRoot.pause.button
    APSDisableButton $widgetRoot.resume.button
    APSDisableButton $widgetRoot.abort.button
    APSEnableButton $widgetRoot.restoreNext.button 
    APSEnableButton $widgetRoot.restoreRest.button 
    set abortRestoration 1
    set pauseRestoration 0
}

proc ResumeRestoration {args} {
    set widgetRoot ""
    APSStrictParseArguments {widgetRoot}
    global pauseRestoration
    if $pauseRestoration {
        APSEnableButton $widgetRoot.pause.button
        APSDisableButton $widgetRoot.resume.button
        set pauseRestoration 0
    }
}

proc PauseRestoration {args} {
    set widgetRoot ""
    APSStrictParseArguments {widgetRoot}
    global pauseRestoration
    APSDisableButton $widgetRoot.pause.button
    APSEnableButton $widgetRoot.resume.button
    set pauseRestoration 1
}

set sequenceFile ""
set args $argv
APSStrictParseArguments {sequenceFile}

set status ""
APSScrolledStatus .status -parent .userFrame -textVariable status -width 80 \
      -height 4

APSFrame .descr -parent .userFrame -label "Sequence Description" -relief flat 
APSScrolledText .scroll -parent .userFrame.descr.frame -name "" \
  -width 60 -height 3
set sequenceDescriptionWidget .userFrame.descr.frame.scroll.text

MakeSequenceStepWidgets .seqstep -parent .userFrame
set descriptionWidget .userFrame.seqstep.frame.descr.frame.snapDescr.text 

MakeActionButtons .action -parent .userFrame

if {![string length $sequenceFile] || ![file exists $sequenceFile]} {
    set sequenceFile [APSFileSelectDialog .refSeq1 -parent .userFrame]
}
ReadSequenceFile -sequenceFile $sequenceFile \
  -statusCallback "APSSetVarAndUpdate status" \
  -descriptionWidget $descriptionWidget \
  -sequenceDescriptionWidget $sequenceDescriptionWidget
