;+
; PROJECT:
;       SOHO - CDS/SUMER
;
; NAME:
;       UPDATE_CAMPAIGN
;
; PURPOSE:
;       Read the ASCII campaign file and update campaign database
;
; CATEGORY:
;       Planning, database
;
; SYNTAX:
;       update_campaign
;
; OPTIONAL INPUTS:
;       ID - ID of a campaign to be inserted/updated
;
; KEYWORDS:
;       TSTART,TEND = times to consider in update
;       ERROR - Named variable, error message returned. A null string is
;               returned if no error occurs
;       PROGRESS - show progress bar
;       VERBOSE - obvious
;       NOCAL   - skip updating calibrations
;
; RESTRICTIONS:
;       Requires campaign ASCII database file located in SOHO_EAP directory
;
; HISTORY:
;       Version 1, September 9, 1996, Liyun Wang, NASA/GSFC. Written
;       Version 2, September 19, 1996, Liyun Wang, NASA/GSFC
;          Modified such that an empty CMP_end will cause CMP_end to
;             be set to 2005/12/31
;       Version 3, 23-Sep-1996, William Thompson, GSFC
;          Changed COMMENTS to COMMENT.  Added CMP_TYPE to CDS structure.
;       Version 4, September 23, 1996, Liyun Wang, NASA/GSFC
;          Added optional input parameter: ID
;       Version 5, September 24, 1996, Liyun Wang, NASA/GSFC
;          Made campaign structure for SUMER similar to that for CDS
;          Filled multiple institutes fields for CDS
;          Taken out TEST keyword
;       Version 6, Sept 24 1996, Zarro, ARC
;          Made CDS campaign structure compatible with GET_CAMPAIGN
;
; CONTACT:
;       dzarro@smmdac.nascon.nasa.gov
;-
;
;-----------------------------------------------------------------------------  
   pro reset_zdbase
   inst = which_inst()
   if inst ne 'S' then status=call_function('fix_zdbase',/orig)
   return
   end
;-----------------------------------------------------------------------------


   pro update_campaign, id,tstart=tstart,tend=tend,error=error,soho=soho,$
                        progress=progress,verbose=verbose,nocal=nocal,$
                        back=back

   on_error, 1
   error = ''

   progress=keyword_set(progress)
   verbose=keyword_set(verbose)
   soho=keyword_set(soho)
   nocal=keyword_set(nocal)

;-- find SOC database

   loc = getenv('SOHO_EAP')
   if trim(loc) eq '' then begin
    error = 'Env. variable SOHO_EAP for SOHO Campaign database not defined'
    message, error, /cont
    return
   endif

   loc=concat_dir(loc,'campaign',/dir)
   cmp_file = concat_dir(loc, 'soho_campaign.dat')
   clook = loc_file(cmp_file, count=count)
   if count eq 0 then begin
    error = 'SOHO Campaign database file not found'
    return
   endif


;-- On SUMER system?

   inst = which_inst()
   if inst ne 'S' then begin
    if soho then begin
     err=''
     if soho then reset_zdbase
     status=call_function('fix_zdbase',/soho,err=err)
     if not status then begin
      message,err,/cont
      reset_zdbase
     endif
     return
    endif
    status=call_function('priv_zdbase', /daily, err=error)
    if not status then begin
     message, error, /cont
     if soho then reset_zdbase
     return
    endif
    s=execute("defsysv,'!priv',3")
   endif
   if verbose then message,'Updating '+getenv('ZDBASE'),/cont

;-- catch errors

   var=0
   catch,var
   if var ne 0 then begin
    error='Caught unexpected error'
    message,err,/cont
    if soho then reset_zdbase
    return
   endif

;-- read SOC DB

   records = rd_ascii(clook(0))
   nrd = n_elements(records)
   delim = '~'
   has_id = n_elements(id) ne 0
   message, 'Checking...', /cont, /info
   if progress then begin
    pid =progmeter(/init,label='Please Wait. Updating...',button='Cancel')
   endif

;-- START/STOP times

   tlast=anytim2tai('2005/12/31')
   err=''
   dstart=anytim2tai(tstart,err=err)
   if err ne '' then begin
    get_utc,dstart,/date,/ecs
    dstart=anytim2tai(dstart)
   endif
   err=''
   dend=anytim2tai(tend,err=err)
   if err ne '' then dend=tlast

   if not exist(back) then tback=0 else tback=abs(back)
   if tback gt 0 then begin
    dend=dstart
    dstart=dstart-tback*24.*3600.
   endif
   aborted=0

   dprint,'% tstart,tend: ',anytim2utc(dstart,/ecs),'    ',anytim2utc(dend,/ecs)

   for i=0, nrd-1 do begin
    last_val=0. & step=1.
    if progress then begin
     val = i/(1.0*nrd)
     if abs((val-last_val))*100. gt step then begin
      if (progmeter(pid,val) eq 'Cancel') then begin
       aborted=1
       goto,finished
      endif
      last_val=val
     endif
    endif
    entry = str2arr(records(i), delim=delim)
    n = n_elements(entry)
    if n lt 9 then begin
     message, 'Invalid data record: has '+strtrim(string(n),2)+$
              ' fields; require at least 9 fields.', /cont
    endif else begin
     if is_number(entry(0)) then begin
      cmp_no = fix(entry(0))
      go_on = 1
      if has_id then if cmp_no ne id then go_on = 0
     endif else go_on=0

     if go_on then begin
      type = strmid(trim(entry(1)),0,120)
      cmp_name = strmid(trim(entry(2)),0,120)

;---------------------------------------------------------------------------
;           Make campaign description string array with maximum 80 character
;           for each element, trim the trailing blanks
;---------------------------------------------------------------------------

      cmp_desc = strtrim(str2lines(entry(3), length=80))
      if n_elements(cmp_desc) gt 5 then cmp_desc = cmp_desc(0:4)

      observer = strmid(trim(entry(4)),0,120)
      comment = strmid(trim(entry(5)),0,80)
      institutes = trim(entry(6))

      if entry(7) eq '' then date_obs = 0.d0 else begin
       err = ''
       date_obs = utc2tai(entry(7), err=err)
       if err ne '' then begin
        date_obs = 0.d0
        message, 'Campaign '+entry(0)+': Invalid DATE_OBS; '+$
                 'set to 0.0 TAI', /cont
       endif
      endelse

      if entry(8) eq '' then date_end = tlast else begin
       err = ''
       date_end = utc2tai(entry(8), err=err)
       if err ne '' then begin
        date_end =tlast
        message, 'Campaign '+entry(0)+': Invalid DATE_END; '+$
                     'set to '+tai2utc(tlast,/ecs), /cont
       endif
      endelse

      if ((1-nocal) or (date_end ne tlast)) and $
       (((date_obs ge dstart) and (date_obs le dend)) or $
        ((date_end ge dstart) and (date_end le dend)) or $
        ((date_obs lt dstart) and (date_end gt dend))) then begin

       if inst eq 'S' then inst_stc = trim(institutes) else begin

;---------------------------------------------------------------------------
;              CDS case
;---------------------------------------------------------------------------

        inst_stc = {CDS_INSTITUTE, institut:'', observer:''}
        a = str2arr(institutes, delim=';')
        nc = n_elements(a)
        if nc gt 1 then inst_stc = replicate(inst_stc, nc)
        for k=0, nc-1 do begin
         b = str2arr(a(k), delim=':')
         if n_elements(b) eq 2 then begin
          inst_stc(k).institut = trim(b(0))
          inst_stc(k).observer = trim(b(1))
         endif else inst_stc(k).institut = a(k)
        endfor
       endelse

       cmp_stc = {cmp_no:cmp_no, cmp_name:cmp_name, $
                  cmp_type:type, cmp_desc:cmp_desc, $
                  date_obs:date_obs, date_end:date_end, $
                  observer:observer, institutes:inst_stc, $
                  comment:comment}
       cmp_str = trim(cmp_stc.cmp_no)

;-- trim all string blanks

       trim_campaign,cmp_stc
       err = ''
       get_campaign, cmp_stc.cmp_no, dd, err=err
       if err eq '' then begin
        if verbose then message,'Checking '+anytim2utc(cmp_stc.date_obs,/ecs)+'   '+anytim2utc(cmp_stc.date_end,/ecs),/cont
        if not tag_exist(dd, 'COMMENT') then dd = add_tag(dd, '', 'COMMENT')
        if not match_struct(dd, cmp_stc, dtag=dtag,/float) then begin
         err = ''
         dprint,'% UPDATE_CAMPAIGN: ',dtag
         t1='dd.'+dtag & t2='cmp_stc.'+dtag
         message, 'Replacing campaign #'+cmp_str+$
                     ' (field differs: '+arr2str(dtag, ',')+')...', /cont
         if not mod_campaign(cmp_stc, err=err) then message, cmp_str+': '+err, /cont
        endif
       endif else begin
        err = ''
        message, 'Adding campaign #'+cmp_str+'...', /cont
        if not add_campaign(cmp_stc, err=err) then message, cmp_str+': '+err, /cont
       endelse
       if has_id then if cmp_no eq id then goto, finished
      endif
     endif
    endelse
   endfor

finished:
   xkill,pid
   if aborted then message, 'Aborted', /cont, /info else $
    message, 'Completed', /cont, /info
   if soho then reset_zdbase
   return
end

