;+
; NAME:
;     WRITE_DAILY
; PURPOSE:
;     Writes the DAILY phase cal solution to an OVSA data (.ARC)
;     file.
; CATEGORY:
;     OVSA APC CALIBRATION SUPPORT
; CALLING SEQUENCE:
;     result = write_daily(filename,lines,refscan)
; INPUTS:
;     filename   The name of the .ARC file containing the data that were
;                  analyzed, and into which the results of the analysis
;                  are to be written.
;     lines      The fit parameters, encoded as an array of text strings.
;                  There are two header lines, then one line for each scan
;                  containing HREC, TREF, and then PSLP and POFF for each
;                  baseline (NANT*2 - 3 baselines).
;     scan       The array of SCAN structures (defined in DAILY()),
;                  corresponding to the scans used.
; OPTIONAL (KEYWORD) INPUT PARAMETERS:
; ROUTINES CALLED:
; OUTPUTS:
;     result     A flag to indicate the success or failure of the call.
; COMMENTS:
; SIDE EFFECTS:
; RESTRICTIONS:
; MODIFICATION HISTORY:
;     Written 23-Jul-2000 by Dale E. Gary
;-

function write_daily,filename,lines,scan

   ; Find out how many baselines there are, from NANT, and set the format
   ; string accordingly
   nant = scan[0].nant
   nbl = nant*2 - 3
   fmt = '(5x,3(1x,I2),'+string(nbl,format='(I2)')+'(F7.1,I5))'

   ; Format for last line, corresponding to phase info relative to Ref Cal
   fmt2 = '('+string(nbl,format='(I2)')+'(F7.1,I5))'

   ; Find out how many scans there are, from the array of SCAN structures
   ns = n_elements(scan)
   sdat = fltarr(nbl*2)
   ; Phase information for each scan (PSLP and POFF for each baseline)
   pinfo = fltarr(nbl*2,ns)
   ; Reference time for each scan [msec]
   tref = lonarr(ns)
   ; Refcal phase info, from last line
   refcal = fltarr(nbl*2)

   ON_IOERROR,bail
   ; Extract information from LINES into a useful form
   for i = 0,ns-1 do begin
      reads,lines[i+2],hh,mm,ss,sdat,format=fmt
      pinfo[*,i] = sdat
      tref[i] = (hms2sec(hh*10000L+mm*100L+ss))*1000L
   endfor
   reads,lines[ns+2],refcal,format=fmt2
   goto,lines_ok

bail:
   ON_IOERROR,NULL
   print,'WRITE_DAILY: Error in structure of phase info LINES array'
   return,-1

lines_ok:
   ; Combine scan data with REFCAL info (just add), to get final phase
   ; info, and update the scan structure Time/Label structures for the
   ; reference time
   for i = 0, ns-1 do begin
      pinfo[*,i] = pinfo[*,i] + refcal
      scan[i].tls.msec = tref[i]
      scan[i].tls.timstr = msec2str(tref[i])
   endfor

   ; If we get here, everything looks good, and we now have what we need
   ; to fill in the DAILYPHZ segments in the data (.ARC) file
   lun = openarc(filename,a,nrec,/update)
   if (lun le 0) then return,-1

   ; Generate a DAILYPHZ segment for each scan.  The Time/Label structure
   ; will be dealt with later.
   datout = intarr(1024,ns)
   ; IANT is the index to the phase slopes of the first NANT-1
   ; baselines, i.e. 12, 14, 15, ... which represent the *antenna-based*
   ; phase slopes for antenna 2, 4, 5, ..., since the phase info for
   ; ant 1 is zero by definition.  The index to the corresponding phase
   ; offsets is just IANT+1
   iant = indgen(nant-1)*2
   for i = 0, ns-1 do begin
      datout[12:23,i] = tl_encode(scan[i].tls)

      ; Antenna-based phase slopes, with zero for ant 1.  Signed int, scaled by 10
      datout[24:24+nant-1,i] = nint([0,pinfo[iant,i]]*10)
      ; Antenna-based phase offsets, with zero for ant 1. Signed int, scaled by 1
      datout[32:32+nant-1,i] = nint([0,pinfo[iant+1,i]])
      nf = n_elements(scan[i].amf[0,*,0])
      datout[48,i] = nf
      datout[49,i] = nbl
      ; Extract the relevant part of the AMF data
      amf = scan[i].amf[0:4,*,0:nbl-1]
      ; Scale the values so that integer conversion maintains precision
      for j = 0, nbl-1 do begin
         amf[*,*,j] = amf[*,*,j]*([10,1000,1000,10,10]#replicate(1,nf))
      endfor
      ; Enter AMF table as signed integer
      datout[50:50+5*nf*nbl-1,i] = nint(reform(amf,5*nf*nbl))
   endfor

   ; Set up the TLS for the segments according to today's date/time
   tls_now = tlsnow(!SEGM.DAILYPHZ)
   wrote_end = 0

   ; The SCAN array has the list of PCAL headers.  Read the record after
   ; the header record and see if it is a DAILYPHZ segment.  If not, we
   ; will write new DAILYPHZ segments at the end of the file.
   for i = 0, ns-1 do begin
      data = getdata(scan[i].srec,a)
      tls = tl_decode(data)
      if (tls.segmentcode eq !SEGM.DAILYPHZ) then begin
         ; This is a DAILYPHZ segment, so we are free to overwrite it
         ; Transfer the info from the DAILYPHZ segment to the data to
         ; be output
         tls_now.nrc = tls.nrc
         tls_now.nro  = tls.nro
         tls_now.scancode = tls.scancode
         ; Encode the Time/Label structure to binary form and insert
         ; into the data to be output
         datout[0:11,i] = tl_encode(tls_now)
         ; Write out the data record, overwriting the existing record
         a(scan[i].srec) = datout[*,i]
      endif else begin
         ; This is not a DAILYPHZ segment, so we must write the output
         ; data to the end of the file

         ; Things to take care of on the first time writing
         ; to the end of the file
         if (wrote_end eq 0) then begin
            ; First check that the file has reasonable data at the end,
            ; since some files have garbage at the end, or an EOF segment.
            data = getdata(nrec-1,a)
            while (data[0] le 0) do begin
               ; This is garbage, so back up one record
               nrec = nrec - 1
               data = getdata(nrec-1,a)
            endwhile
            ; We are at the end of the good data, so check whether the last
            ; record is an EOF
            tls_last = tl_decode(data)
            if (tls_last.segmentcode eq !SEGM.EOF) then begin
               eofdata = data   ; Save the EOF record
               nrec = nrec-1    ; Decrement last record indicator to point to prev
               data = getdata(nrec-1,a)
            endif
            ; We may need to back up further to overwrite DAILYPHZ
            ; scans created from an earlier analysis
            tls = tl_decode(data)
            while (tls.segmentcode eq !SEGM.DAILYPHZ) do begin
               ; This is a DAILYPHZ, so back up one record
               nrec = nrec - 1
               data = getdata(nrec-1,a)
               tls = tl_decode(data)
            endwhile
            wrote_end = 1
         endif

         ; NREC now points to the last good record, excluding any EOF
         ; and DAILYPHZ segments.  Go forward one, to point to the one
         ; we are about to write
         nrec = nrec + 1
         tls_now.nrc = nrec
         tls_now.scancode = !SCAN.TEST   ; It is not really part of a scan
         ; Encode the Time/Label structure to binary form and insert
         ; into the data to be output
         datout[0:11,i] = tl_encode(tls_now)
         ; Write out the data record, creating a new record
         a(nrec-1) = datout[*,i]
      endelse
   endfor

   ; If we had earlier read an EOF segment, then write out the EOF segment
   if (n_elements(tls_last) ne 0) then begin
      if (tls_last.segmentcode eq !SEGM.EOF) then begin
         nrec = nrec + 1
         tls_last.nrc = nrec
         eofdata[0:11] = tl_encode(tls_last)
         a(nrec-1) = eofdata
      endif
   endif

   free_lun,lun

return,0
end