

set debugSddsmonitorSlave 0

proc APSSddsmonitorSlaveCallback {fid flagVariable} {
    # callback routine for sddsmonitor subprocess in single-shot mode
    gets $fid input
    global $flagVariable
    global debugSddsmonitorSlave
    after 500
    if $debugSddsmonitorSlave {
        puts stderr "APSSddsmonitorSlaveCallback: $input"
    }
    if [string compare $input "Type <cr> to read, q to quit:"]==0 {
        set $flagVariable 1
        return
    }
    if [string compare $input "Done."]==0 {
        set $flagVariable 2
        return
    }
    if [string length $input] {
        # unknown string
        puts stderr "$input"
        return
    }
}

proc APSStartSddsmonitorSlave {args} {
    set ID ""
    set sddsmonitorOptions ""
    set sddsmonitorProgram sddsmonitor
    set preacquireCommand ""
    APSStrictParseArguments {ID sddsmonitorOptions sddsmonitorProgram preacquireCommand}
    if [string length $ID]==0 {
        return -code error "APSStartSddsmonitorSlave: ID is blank"
    }
    global debugSddsmonitorSlave
    foreach item {apsSlaveMonProcFid apsSlaveMonProcFlag apsSlaveModProcCommand} {
        global $item$ID
        set $item$ID ""
    }

    if [string length [set apsSlaveMonProcFid$ID]] {
        # Subprocess already running.
        return
    }

    # start subprocess
    set command "|$sddsmonitorProgram "
    append command $sddsmonitorOptions
    append command " -single=stdout "
    set apsSlaveMonProcFid$ID [open $command r+]
    set apsSlaveModProcCommand$ID "$preacquireCommand"
    if $debugSddsmonitorSlave  {
        puts stderr "Command: $command"
    }
    # set up callbacks when there is data on the pipe from the subprocess
    set apsSlaveMonProcFlag$ID 0
    fileevent [set apsSlaveMonProcFid$ID] readable \
      "APSSddsmonitorSlaveCallback [set apsSlaveMonProcFid$ID] apsSlaveMonProcFlag$ID"
    APSWaitForSddsmonitorSlave -ID $ID
}

proc APSWaitForSddsmonitorSlave {args} {
    set ID ""
    APSStrictParseArguments {ID}
    if ![string length $ID] {
        return -code error "APSWaitForSddsmonitorSlave: ID is blank."
    }
    
    global apsSlaveMonProcFlag$ID apsSlaveMonProcFid$ID debugSddsmonitorSlave
    if $debugSddsmonitorSlave {
        puts stderr "APSWaitForSddsmonitorSlave: [set apsSlaveMonProcFlag$ID]"
    }
    if [set apsSlaveMonProcFlag$ID]==0 {
        tkwait variable apsSlaveMonProcFlag$ID
        set processFlag [set apsSlaveMonProcFlag$ID]
        if $processFlag!=1 {
            if $processFlag==-1 {
                close [set apsSlaveMonProcFid$ID]
                return -code error \
                  "APSWaitForSddsmonitorSlave: Problem with readback from subprocess (ID=$ID)."
            } else {
                close [set apsSlaveMonProcFid$ID]
                if $processFlag!=2 {
                    return -code error \
                      "APSWaitForSddsmonitorSlave: Unexpected return from process (ID=$ID): $processFlag"
                } else {
                    return
                }
            }
        }
    }
    set apsSlaveMonProcFlag$ID 0
}

proc APSSddsMonitorSlaveTakePoint {args} {
    set ID ""
    set postPause 0
    APSStrictParseArguments {ID postPause}
    if ![string length $ID] {
        return -code error "APSSddsMonitorSlaveTakePoint: ID is blank."  }

    global apsSlaveMonProcFlag$ID apsSlaveMonProcFid$ID apsSlaveModProcCommand$ID debugSddsmonitorSlave
    set procFidVar apsSlaveMonProcFid$ID
    set procFlagVar apsSlaveMonProcFlag$ID 

    set command [set apsSlaveModProcCommand$ID]
    if $debugSddsmonitorSlave {
        puts stderr "APSSddsMonitorSlaveTakePoint: $command"
    }
    if [string length $command] {
        if [catch {eval $command} result] {
            return -code error \
          "APSSddsMonitorSlaveTakePoint: $result"
        }
    }

    if ![string length [set $procFidVar]] {
        return -code error \
          "APSSddsMonitorSlaveTakePoint: Subprocess not running (ID is $ID)"  }
    set $procFlagVar 0
    puts [set $procFidVar] y
    flush [set $procFidVar] 
    after 2000

    if [catch {APSWaitForSddsmonitorSlave -ID $ID} result] {
        return -code error "APSSddsMonitorSlaveTakePoint: $result" }
    APSWaitWithUpdate -updateInterval 1 -waitSeconds $postPause
}


proc APSStopSddsmonitorSlave {args} {
    set ID ""
    APSStrictParseArguments {ID}
    if ![string length $ID] {
        return -code error "APSStopSddsmonitorSlave: ID is blank."  }

    global apsSlaveMonProcFlag$ID apsSlaveMonProcFid$ID
    set procFidVar apsSlaveMonProcFid$ID
    set procFlagVar apsSlaveMonProcFlag$ID 

    if ![string length [set $procFidVar]] {
        return -code error \
          "APSStopSddsmonitorSlave: Subprocess not running (ID is $ID)"  }

    # terminate the subprocess
    catch {puts [set $procFidVar] q}
    catch {flush [set $procFidVar]}
    catch {close [set $procFidVar]}
    set $procFidVar ""
}
