; Routines in the file: make_32, get_dn_rate, valid_pass4
; Last change was 25-apr-95
;+
; Name:
;   valid_pass4
;
; Purpose:
;
;   Called by op_edit (from op_first_guess)
;
;   1. Check there are more than 5 contiguous KSC contacts.  
;      If so, give the user the option to remove one.
;
;   2. Also, change los to QT M if the sun light time to the next contact
;      exceeds op_rules.min_sun.a
;
;   3. Eliminate events prior to the first KSC AOS and after last KSC LOS
;
;   4. Make last two KSC LOSs QT M on the next day.
;
;   5. Change to Quiet Rate Med at times of SAA if in Quiet Rate High and 
;      not night.
;
; Modification History:
;  Written, 11-dec-91, J. R. Lemen
;  Modified, 11-jan-92, J. R. L. -- Fixed bug in code which counted KSC passes 
;  Modified, 16-sep-92, JRL: Make KSC pass(es) of the next day LOS QT M
;  Modified, 12-nov-92, JRL, Fixed bug: eliminating a pass made the part of
;				the code that changed los to QT M fail for
;				multiple contacts on next day.
;  12-oct-93, JRL, Call make_32 to force the alignment of the times to be on 32sec boundaries
;  29-nov-93, JRL, After calling make_32, use bsort to preserve orginal order
;		   Fix the start time (moved code from op_edit to here)
;  13-jun-94, JRL, Added code to add Quiet Rate Med / Quiet Rate High during SAAs
;  20-jun-94, JRL, Make only last 2 KSC LOSs on 2nd day QT/M (instead of all on 2nd day KSC LOSs).
;  30-jul-94, JRL, Always ask if user wants to delete a pass (for ASCA conflicts)
;  28-mar-95, JRL, Pass in the og_table to contacts_sum
;  25-apr-95, JRL, Enable deletion of 2nd day KSC passes 
;- ------------------------------------------------------------------------------------
function make_32, event
;+
; NAME:
;   make_32
; PURPOSE:
;   Align the event times on the nearest 32 sec boundaries.
;   Adjust the offset times.
; INPUTS:
;   event	= The event structure from op_get_event
; RETURNS:
;   A new event structure with modified times.
; MODIFICATION HISTORY:
;   12-oct-93, JRL, Written.
;-
; zero out the msec of event2(0) -- round off to nearest sec
event2 = event
event2(0).timarr = addtime(event2(0).timarr,del=500.d0/1000./60.)
event2(0).timarr(3) = 0

for i=1,n_elements(event2)-1 do begin
  diff = addtime(event2(i).timarr,diff=event2(0).timarr)*60.	; Get the difference (sec)
  n32  = long((diff+16.) / 32.)			; Number of 32 sec intervals
  Temp_timarr = event2(i).timarr
  event2(i).timarr = addtime(event2(0).timarr,del=n32*32.d0/60.)
  event2(i).offset = event2(i).offset + addtime(event2(i).timarr,diff=Temp_timarr)
endfor

return,event2
end					; End of make_32
;- ------------------------------------------------------------------------------------
pro get_dn_rate, event, og_table, dn, rate, saa
;+
; NAME:
;  get_dn_rate
; PURPOSE:
;  Return the Day/night status, rate and saa status for EVENT items
; INPUTS:
;   event	= The event structure from op_get_event
; OUTPUTS:
;  dn		= Byte array 0: Night, 1: Day
;  rate		= Byte array 0: High,  1: Med
;  saa		= Byte array 0: No SAA, 1: in SAA
; MODIFICATION HISTORY:
;  14-jun-94, JRL, Written
;  24-jun-94, JRL, Fixed a bug which caused rate/saa/dn to be not checked
;		   until after KSC Pass 2
;-
   
; --------  Set the rate from the first KSC LOS ---------
;           Look for the First KSC LOS
   i=0
   while (event(i).og ne og_table(15).og) and	$
         (event(i).og ne og_table(16).og) and 	$
	  i le n_elements(event)-1 do begin
     i=i+1
     if i gt n_elements(event)-1 then first_rate = 0	; In case no KSC LOSs events
   endwhile

; Set the first rate (0=High, 1=Medium)
   if event(i).og eq og_table(15).og then first_rate = 0 else $
   if event(i).og eq og_table(16).og then first_rate = 1

; --------  Set up the output arrays --------------
   npts = n_elements(event)
   rate = replicate(1b,npts)		; 1=Med, 0=Hight telemtry rate
   rate(0) = first_rate
   DN   = replicate(0b,npts)		; 0=night, 1=day
   saa  = replicate(0b,npts)		; 0=No SAA, 1= In SAA

; --------  Loop through and assign the events ----

   for j=1,npts-1 do begin
     og = event(j).og

     Rate(j) = Rate(j-1)		; Assume no change
     DN(j)   = DN(j-1)
     SAA(j)  = SAA(j-1)

; Check for Rate Change
; These are QT/H cases
     if (og eq og_table(15).og) or (og eq og_table(28).og) then Rate(j) = 0
     if (og eq og_table(22).og) then Rate(j) = 0		; DSN QT H
     if (og eq og_table(28).og) then Rate(j) = 0		; Quiet Rate High
; These are the QT/M cases
     if (og eq og_table(16).og) or (og eq og_table(23).og) then Rate(j) = 1
     if (og eq og_table(29).og) then Rate(j) = 1		; Quiet Rate Med

; Check for Day/Night Change
     if (og eq og_table(5).og ) then DN(j) = 0			; Night OG
     if (og eq og_table(55).og) then DN(j) = 1			; Day OG

; Check for SAA
     if (og eq og_table(26).og) then saa(j) = 1			; RB HV RDCT ON
     if (og eq og_table(27).og) then saa(j) = 0			; RB HV RDCT OFF

   endfor

end
;- ------------------------------------------------------------------------------------
;-					; Beginning of valid_pass4
function valid_pass4, event, og_table, op_rules, qrate_change=qrate_change, $
			str_remove=str_remove, ksc_pass_num=ksc_pass_num

; ------------------------
; Eliminate entries until a KSC LOS is detected
; ------------------------
event2 = event					; Save the original 
npts = n_elements(event2)
while( not ((event2(npts-1).og ge 15) and (event2(npts-1).og le 16))) do begin
   event2 = event2(0:npts-2)
   npts = n_elements(event2)
endwhile
contacts = contact_sum( event2, og_table  )	; Get the pass summary

; ------------------------
;  Count the KSC contacts
; ------------------------

j = 0 & Nstn = 0 & k1 = 0 & Nstn2 = 0 & k2 = 0
not_finished = 1
if n_elements( contacts ) le 2 then not_finished = 0
while( not_finished ) do begin
  if contacts(j).station eq 'U' then begin
     if Nstn eq 0 then begin
	Nstn = Nstn + 1
	k1 = j
     endif else begin					; Nstn eq 0
       if addtime(contacts(j).aos_time,diff=contacts(k1(Nstn-1)).aos_time)  $
		lt 12*60 then begin
	  Nstn = Nstn + 1
	  k1 = [k1,j]
       endif else begin
; Count the passes that occur on the "next" day
	 Nstn2 = Nstn2 + 1
	 if Nstn2 eq 1 then k2 = j else k2 = [k2,j]
       endelse
     endelse						; Nstn eq 0
  endif							; contacts(j) ...
	
  j = j + 1
  if j eq N_elements(contacts) then not_finished = 0
endwhile

; ----------------------------------------------------------
; Make the KSC contacts that occur on the next day los QT M
; ----------------------------------------------------------

if Nstn2 gt 0 then begin
  for i=(Nstn2-2)>0,Nstn2-1 do begin		; JRL 20-jun-94
       jj = where(event2.pass_num eq contacts(k2(i)).pass_num)
       kk = where((event2(jj).og eq 15) or (event2(jj).og eq 22))
       if kk(0) ne -1 then begin
          indx = jj(kk(0))			; Index
	  og = event2(indx).og			; Get the original index
	  op_cmd = og + 1			; <<This could change>>
	  op_cmd = where(og_table.og eq op_cmd) & op_cmd = op_cmd(0)
	  event2(indx).com = og_table(op_cmd).og_comm
	  event2(indx).og  = og_table(op_cmd).og
       endif					; kk(0) ne -1
   endfor					; i=0,Nstn2-1
endif						; Nstn2 gt 0

; --------------------------------------------------------
; If more than 5 KSC contacts in a row, offer to remove 1
; 30-jul-94:  Always ask, and allow user to eliminate various contacts
; --------------------------------------------------------
;if Nstn gt 5 then begin
  ksc_pass_num = indgen(Nstn) + 1		; We start from 1
  print,' ' & print,'* There are ',strtrim(Nstn,2),' first day KSC passes and ',$
	strtrim(Nstn2,2),' second day KSC passes',format='(5a)'
  pass_sum = fmt_pass( contacts )
  for i=0,Nstn-1 do print,i+1,strmid(pass_sum(0,k1(i)),0,58),format='(i3,2x,a)'
  print,' '
  for i=0,Nstn2-1 do print,i+Nstn+1,strmid(pass_sum(0,k2(i)),0,58),format='(i3,2x,a)'

  print,' '
  if Nstn gt 5 then ans = 'Y' else ans = 'N'
  input,'* Do you want to eliminate any contacts?', ans, ans
  ans = strmid(strupcase(ans),0,1)

  if ans ne 'N' then begin
     print,'* Enter the station number(s) to eliminate (separated by blanks or commas):'
     Estn = ''		; initialize
     read,'* Enter between 1 and '+strtrim(Nstn+Nstn2,2)+', or 0 to keep all contacts: ',Estn
     Estn = fix(str2arr(strcompress(str_replace(strtrim(estn,2),',',' ')),' '))
     if max(Estn) gt 0 then begin
       print,'Remove the following station contact(s):'
       if n_elements(str_remove) eq 0 then str_remove = ' '
       if str_remove(0) eq '-1' then str_remove = ' '
       if Nstn2 gt 0 then kk = [k1,k2] else kk = k1
       for ik=0,n_elements(Estn)-1 do begin
         jj = where(contacts(kk(Estn(ik)-1)).pass_num eq event2.pass_num) 
;         temp_str = string(strmid(pass_sum(0,kk(Estn(ik)-1)),0,58),format='(5x,a)')
	 temp_str = '  KSC  '+fmt_tim(event2(jj(0)).timarr)+'  '+event2(jj(0)).station
	 print,temp_str & str_remove = [str_remove, temp_str]
         for i=0,n_elements(jj)-1 do begin
            event2(jj(i)).og = - abs(event2(jj(i)).og)
  	    if event2(jj(i)).og eq 0 then event2(jj(i)).og = -99	; Nop case
         endfor					; i=0,n_elements(jj)-1
       endfor					; ik=0,n_elements(Estn)-1
       contacts = contact_sum( event2, og_table )
       for i=0,n_elements(Estn)-1 do ksc_pass_num = ksc_pass_num(where(ksc_pass_num ne Estn(i)))
     endif 					; Esnt gt 0
  endif						; ans ne 'N'
;endif						; Nstn gt 5


; ------------------------------------------------
; Check contacts see if the los should be QT M
; ------------------------------------------------
if op_rules.min_sun.a gt 0 then begin
  for i=0,n_elements(contacts)-2 do begin
    if contacts(i+1).day_elaps gt op_rules.min_sun.a then begin
       jj = where(event2.pass_num eq contacts(i).pass_num)
       kk = where((event2(jj).og eq 15) or (event2(jj).og eq 22))
       if kk(0) ne -1 then begin
          indx = jj(kk(0))			; Index
	  og = event2(indx).og			; Get the original index
	  op_cmd = og + 1			; <<This could change>>
	  op_cmd = where(og_table.og eq op_cmd) & op_cmd = op_cmd(0)
	  event2(indx).com = og_table(op_cmd).og_comm
	  event2(indx).og  = og_table(op_cmd).og
       endif					; kk(0) ne -1
    endif					; contacts(i+1).day_elaps ...
  endfor					; i=0,n_elements(contacts)-2	
endif

; ----------------------------------------------------------
; Remove events that occur before first KSC AOS
; ----------------------------------------------------------

while( not ((event2(0).og ge 8) and (event2(0).og le 11) )) do  $
                        event2 = event2(1:*)    ; KSC AOS is 8,9,10,11
event2 = make_32( event2 )		; Align to 32 sec boundaries
contacts = contact_sum( event2, og_table )	; Get the contact information again

; ----------------------------------------------------------
; Make sure that KSC contact is entered in H telemetry rate
; ----------------------------------------------------------
npts = n_elements( event2 )
qt_h = 1		; Assume we start in qt high 
resort = 0		; Don't need to time sort event2
for i=0,n_elements( event2 )-1 do begin
  if (event2(i).og eq 15) or (event2(i).og eq 22) then qt_h = 1 else	$
  if (event2(i).og eq 16) or (event2(i).og eq 23) then qt_h = 0 else	$
  if (event2(i).og ge 8) and (event2(i).og le 11) and not qt_h then begin
	    timarr = addtime(event2(i).timarr,delt=-1.)	; 1 minute earlier
	    op_cmd = 28					; Add QT H OG
            save_event,npts,og_table,timarr,op_cmd,            $
        	' ',' ',-1,event2(i).pass_num,event2
	    resort = 1					; must re-sort 
  endif
endfor

; ----------------------------------------
;  Time order everything

if resort then begin
  ex2int,event2.timarr,msod,DS79	; Convert to internal format

  Day = DS79-min(DS79)
  T_sec = msod/1000L+Day*24L*3600

  event2 = event2(bsort(T_sec))		; Don't re-order identical times
  event2 = make_32( event2 )		; Align to 32 sec boundaries
endif					; resort
; ----------------------------------------

; --------------------------------
; Switch to Quiet Rate Med in SAA
; --------------------------------

if op_rules.saa_med_rate.a ne 0 and keyword_set(qrate_change) then begin
   
  event2 = op_saa_med(event2, og_table, op_rules)

; ----------------------------------------
;  Time order everything

  if resort then begin
    ex2int,event2.timarr,msod,DS79	; Convert to internal format

    Day = DS79-min(DS79)
    T_sec = msod/1000L+Day*24L*3600

    event2 = event2(bsort(T_sec))	; Don't re-order identical times
    event2 = make_32( event2 )		; Align to 32 sec boundaries
  endif					; resort
endif
  
return, event2
end
