;+
;WIDGET Procedure:
;
;PURPOSE:
; Widget tool that records streaming data from a server (host) and can save it to a file.
; This tool will run in the background.
; Author:
;    Davin Larson - April 2011
;
; $LastChangedBy: davin-win $
; $LastChangedDate: 2011-05-01 21:53:57 -0700 (Sun, 01 May 2011) $
; $LastChangedRevision: 8617 $
; $URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/ssl_general/trunk/tools/misc/recorder.pro $
;
;-

PRO recorder_event, ev   ; recorder

    widget_control, ev.top, get_uvalue= info   ; get all widget ID's
    wids = info.wids
    localtime=1

    CASE ev.id OF                         ;  Timed events
    wids.base:  begin
        if info.hfp gt 0 then begin
            eofile =0
            treceived = systime(1)
            buffer= uintarr(info.maxsize)
            b=buffer[0]
            for i=0L,n_elements(buffer)-1 do begin
                flag = file_poll_input(info.hfp,timeout=0)
                if flag eq 0 then break
                if eof(info.hfp) then begin
                    dprint,dlevel=1,'Connection to Host: '+info.hostname+':'+info.hostport+' broken. ',i
                    eofile = 1
                    break
                endif
                readu,info.hfp,b
                buffer[i] = b
            endfor
            if i gt 0 then begin
                buffer = buffer[0:i-1]
                if keyword_set(info.dfp) then writeu,info.dfp,swap_endian(buffer,/swap_if_little_endian)
                flush,info.dfp
                printdat,/hex,buffer,output=msg
                msg = time_string(treceived,tformat='hh:mm:ss - ',local=localtime) + msg
                if widget_info(/button_set,wids.proc_button) then begin
                    widget_control,wids.proc_name,get_value = proc_name
                    if keyword_set(proc_name) then call_procedure,proc_name[0],buffer,time=treceived
                endif
            endif else begin
                buffer=0
                msg =time_string(treceived,tformat='hh:mm:ss - No data available',local=localtime)
            endelse
            widget_control,wids.output_text,set_value=msg
            dprint,dlevel=5,msg
            if not keyword_set(eofile) then WIDGET_CONTROL, wids.base, TIMER=info.pollinterval else widget_control,wids.host_button,timer=2
        endif
        return
    end
    wids.host_button : begin
        widget_control,ev.id,get_value=status
        widget_control,wids.host_text, get_value=server_name
        widget_control,wids.host_port, get_value=server_port
        server_n_port = server_name+':'+server_port
        case status of
        'Connect to': begin
            WIDGET_CONTROL, ev.id, set_value = 'Connecting',sensitive=0
            WIDGET_CONTROL, wids.host_text, sensitive=0
            WIDGET_CONTROL, wids.host_port, sensitive=0
            dprint,dlevel=2,'Opening server:','"'+server_n_port+'"'
            socket,hfp,/get_lun,server_name,fix(server_port),error=error ,/swap_if_little_endian,connect_timeout=10
            if keyword_set(error) then begin
                dprint,dlevel=0,!error_state.msg   ;strmessage(error)
                widget_control, wids.output_text, set_value=!error_state.msg
                WIDGET_CONTROL, ev.id, set_value = 'Failed:',sensitive=1
                WIDGET_CONTROL, wids.host_text, sensitive=1
                WIDGET_CONTROL, wids.host_port, sensitive=1
            endif else begin
                info.hfp = hfp
                WIDGET_CONTROL, wids.base, TIMER=1    ; , set_uvalue=hfp
                WIDGET_CONTROL, ev.id, set_value = 'Disconnect',sensitive=1
            endelse
        end
        'Disconnect': begin
            WIDGET_CONTROL, ev.id, set_value = 'Closing'  ,sensitive=0
            WIDGET_CONTROL, wids.host_text, sensitive=1
            WIDGET_CONTROL, wids.host_port, sensitive=1
            msg = 'Disconnected from server:"'+server_n_port+'"'
            widget_control, wids.output_text, set_value=msg
            dprint,dlevel=2,msg
            free_lun,info.hfp
            info.hfp =0
            wait,1
            WIDGET_CONTROL, ev.id, set_value = 'Connect to',sensitive=1
        end
        else: begin
            WIDGET_CONTROL, wids.host_text, sensitive=1
            WIDGET_CONTROL, wids.host_port, sensitive=1
            WIDGET_CONTROL, ev.id, set_value = 'Connect to',sensitive=1
            dprint,'Error'
        end
        endcase
    end
    wids.dest_button: begin
        widget_control,ev.id,get_value=status

        widget_control,wids.dest_text, get_value=filename
        case status of
        'Write to': begin
            if keyword_set(info.dfp) then begin
                free_lun,info.dfp
                info.dfp = 0
            endif
            WIDGET_CONTROL,   ev.id       , set_value = 'Opening' ,sensitive=0
            widget_control, wids.dest_text, get_value = fileformat,sensitive=0
            filename = time_string(systime(1),tformat = fileformat[0])
            widget_control, wids.dest_text, set_uvalue = fileformat,set_value=filename
            if keyword_set(filename) then begin
                dprint,dlevel=3,'Opening file: ',filename
                file_open,'u',filename, unit=dfp,dlevel=4
                info.dfp = dfp
                info.filename= filename
                widget_control, wids.dest_flush, sensitive=1
            endif
;              wait,1
            WIDGET_CONTROL, ev.id, set_value = 'Close   ',sensitive =1
        end
        'Close   ': begin
            WIDGET_CONTROL, ev.id,          set_value = 'Closing',sensitive=0
            widget_control, wids.dest_flush, sensitive=0
            widget_control, wids.dest_text ,get_uvalue= fileformat,get_value=filename
            if info.dfp gt 0 then begin
                free_lun,info.dfp
                info.dfp =0
            endif
            dprint,dlevel=3,'Closing file:',filename
;            wait,1
            widget_control, wids.dest_text ,set_value= fileformat,sensitive=1
            WIDGET_CONTROL, ev.id, set_value = 'Write to',sensitive=1
        end
        else: begin
            dprint,'Invalid'
        end
        endcase
    end
    wids.dest_flush: begin
        widget_control, wids.dest_text ,get_uvalue= fileformat,get_value=filename
        if info.dfp gt 0 then begin
            free_lun,info.dfp
            info.dfp =0
            info.filename= ''
        endif
        dprint,dlevel=3,'Closed file:',filename,get_check_events=cev,check_events=0
;        wait,1
        filename = time_string(systime(1),tformat = fileformat[0])
        widget_control, wids.dest_text, set_uvalue = fileformat,set_value=filename
        if keyword_set(filename) then begin
            file_open,'u',filename, unit=dfp,dlevel=4
            info.dfp = dfp
            info.filename= filename
            widget_control, wids.dest_flush, sensitive=1
        endif
        dprint,dlevel=3,'Opened file: '+info.filename,check_events=cev
        flush,info.dfp
    end
;    wids.host_text:  begin
;        widget_control,ev.id,get_value=value
;        dprint,'"'+value+'"'
;    end
    wids.proc_button: begin
      widget_control,wids.proc_name,get_value=proc_name
      widget_control,wids.proc_name,sensitive = (ev.select eq 0)
      info.run_proc = ev.select
    end
    wids.done: begin   ;    'DONE' ;  close files here!
        if info.hfp gt 0 then begin
            fs = fstat(info.hfp)
            dprint,'Closing '+fs.name
            free_lun,info.hfp
        endif
        if info.dfp gt 0 then begin
            fs = fstat(info.dfp)
            dprint,'Closing '+fs.name
            free_lun,info.dfp
        endif
        WIDGET_CONTROL, ev.TOP, /DESTROY
        return
    end
    else: begin
        msg = string('Base ID is: ',wids.base)
        widget_control, wids.output_text, set_value=msg
        dprint,msg
        printdat,ev
        printdat,info
    end
    ENDCASE
    widget_control,wids.base,set_uvalue=info
END




PRO recorder,ids=ids,host=host,port=port,destination=destination,exec_proc=exec_proc
  if not keyword_set(host) then host = 'localhost'
  if not keyword_set(port) then port = '2020'
  port=strtrim(port,2)
  if not keyword_set(destination) then destination = 'STREAM_YYYYMMDD_hhmmss.dat'
  ids = create_struct('base', WIDGET_BASE(/COLUMN, title='Stream Recorder' ) )
  ids = create_struct(ids,'host_base',   widget_base(ids.base,/row, uname='HOST_BASE') )
  ids = create_struct(ids,'host_button', widget_button(ids.host_base, uname='HOST_BUTTON',value='Connect to') )
  ids = create_struct(ids,'host_text',   widget_text(ids.host_base,  uname='HOST_TEXT' ,VALUE=host ,/EDITABLE ,/NO_NEWLINE ) )
  ids = create_struct(ids,'host_port',   widget_text(ids.host_base,  uname='HOST_PORT',xsize=6, value=port   , /editable, /no_newline))
  ids = create_struct(ids,'dest_base',   widget_base(ids.base,/row, uname='DEST_BASE'))
  ids = create_struct(ids,'dest_button', widget_button(ids.dest_base, uname='DEST_BUTTON',value='Write to'))
  ids = create_struct(ids,'dest_text',   widget_text(ids.dest_base,  uname='DEST_TEXT',xsize=40 ,/EDITABLE ,/NO_NEWLINE  ,VALUE=destination))
  ids = create_struct(ids,'dest_flush',  widget_button(ids.dest_base,uname='DEST_FLUSH', value='Flush' ,sensitive=0))
  ids = create_struct(ids,'output_text', WIDGET_TEXT(ids.base, uname='OUTPUT_TEXT'))
;  if n_elements(exec_proc) ne 0 then begin
        ids = create_struct(ids,'proc_base',   widget_base(ids.base,/row, uname='PROC_BASE'))
        ids = create_struct(ids,'proc_base2',  widget_base(ids.proc_base ,/nonexclusive))
        ids = create_struct(ids,'proc_button', widget_button(ids.proc_base2,uname='PROC_BUTTON',value='Procedure:'))
        ids = create_struct(ids,'proc_name',   widget_text(ids.proc_base,xsize=35, uname='PROC_NAME', value = exec_proc,/editable, /no_newline))
;  endif
  ids = create_struct(ids,'done',        WIDGET_BUTTON(ids.base, VALUE='Done', UNAME='DONE'))
  info = {wids:ids, hostname:host, hostport:port, hfp:0,  $
      fileformat:destination,  filename:'',   dfp:0 ,maxsize:2L^14, $
      pollinterval:1., $
          run_proc:1 }
  WIDGET_CONTROL, ids.base, SET_UVALUE=info
  WIDGET_CONTROL, ids.base, /REALIZE
  XMANAGER, 'recorder', ids.base,/no_block
END
