
pro get_pnt_times, date, ts_win=ts_win, dt_op_start=dt_op_start, dt_dwell_min=dt_dwell_min, $
  dt_post_saa=dt_post_saa, dt_pre_saa=dt_pre_saa, dt_plot_win_hr=dt_plot_win_hr, $
  pnt_arr=pnt_arr, t_pnt_arr=t_pnt_arr, latitude=latitude, longitude=longitude, $
  horizontal=horizontal, vertical=vertical, no_plot=no_plot, no_print=no_print, _extra=_extra

;+
; NAME:
;   GET_PNT_TIMES
; PURPOSE:
;   Calculate pointing positions for the N-S and E-W scans for the HOP 79 irradiance program.
;   Then use OBEV file to calculate re-point times to avoid any SAAs.
; CALLING SEQUENCE:
;   GET_PNT_TIMES, DATE, PNT_ARR=PNT_ARR, T_PNT_ARR=T_PNT_ARR [, TS_WIN=TS_WIN, DT_DWELL_MIN=DT_DWELL_MIN, $
;                  DT_POST_SAA=DT_POST_SAA, DT_PRE_SAA=DT_PRE_SAA, NO_PLOT=NO_PLOT, NO_PRINT=NO_PRINT, $
;                  _EXTRA=_EXTRA]
; EXAMPLE CALLS:
;   IDL> get_pnt_times, latitude=15, /bfi
;   IDL> get_pnt_times, longitude=0, /bfi, dt_dwell_min=10, '04-feb-2010', ts_win='05-feb-2010 05:30'
; REQUIRED INPUTS:
;   DATE: Date of timeline begin planned, in any valid SSW format.
; OPTIONAL INPUTS:
;   TS_WIN         Optional earliest time to begin first scan (automatically constrained to be
;                  after OP_START time and before OP_END time.
;   DT_DWELL_MIN:  Dwell period between re-points in minutes (default is 15 min for EW scan and
;                  30 min for NS scan).
;   DT_POST_SAA:   Offset in minutes between end of an SAA and start of a re-point (default is 1 min).
;   DT_PRE_SAA:    Minimum offset in minutes between end of dwell interval (DT_DWELL_MIN) and start of an SAA
;                  (default is 1 min).
;   NO_PLOT:       If set, suppress plots of FOVs on helio grid and times of SAAs and pointings.
;   NO_PRINT:      If set, suppress print to screen of calculated times and pointings.
; KEYWORD INPUTS (for call to HINODE_POINTING_SCAN):
; --------------------------------------------------------------------
; NOTE! One (AND ONLY ONE) OF THE KEYWORDS [BFI, NFI, SP] MUST BE SET!
; --------------------------------------------------------------------
;   BFI:           Use the BFI FOV when calculating positions and overlaps on the Sun.
;   NFI:           Use the NFI FOV when calculating positions and overlaps. 
;   SP:            Use the SP slit dimensions when calculating positions and overlaps.
; ---------------------------------------------------------------------------
; NOTE! One (AND ONLY ONE) OF THE KEYWORDS [LATITUDE, LONGITUDE] MUST BE SET!
; ---------------------------------------------------------------------------
;   LATITUDE:      Calculate pointing coordinates for an E-W scan along a
;                    constant latitude given by this keyword. 
;   LONGITUDE:     Calculate pointing coordinates for a N-S scan along a
;                    constant longitude given by this value. Currently
;                    limited to LONGITUDE=0 (central meridian).
; ---------------------------------------------------------------------------
;   HORIZONTAL:    Calculate pointing coordinates for a scan along the E-W                
;                    lateral through disk center. Note that this is not an
;                    "equatorial" scan along latitude = 0. 
;   GRID_SPAC:     Optional helio grid spacing (default is 10 deg).
; OUTPUTS:
;   PNT_ARR:       [2,N] array of (x,y) spacecraft pointing values in arcseconds
;                    relative to heliocentric disk center. 
;   T_PNT_ARR:     Vector of N times for re-points
; USAGE:
;   For N-S scan:
;   xyns = hinode_pointing_scan('22-Oct-2008',/BFI, /long, overlap=0.1, color=253, /round)
;
;   For E-W scans:
;   xyp15 = hinode_pointing_scan('22-Oct-2008',/BFI, lat=15, overl=0.1, color=251, /round)
;  
;   xym15 = hinode_pointing_scan('22-Oct-2008',/BFI, lat=-15,overl=0.1, color=252, /noerase, /round)
;
;   For Horizontal scan:
;   xyh = hinode_pointing_scan('22-Oct-2008',/BFI,/horizontal,overl=0.1,color=252, /noerase, /round)
; REVISION HISTORY:                                                                         
;   v 1.0    Written by G. Slater, LMSAL, February, 2010.
;-                                                                                          

; Set default timing parameters:
if not exist(dt_dwell_min) then begin
  if exist(latitude) then dt_dwell_min = 15
  if exist(longitude) then dt_dwell_min = 30
  if exist(horizontal) then dt_dwell_min = 15
  if exist(vertical) then dt_dwell_min = 30
endif
if not exist(dt_op_start) then dt_op_start = 10
if not exist(dt_post_saa) then dt_post_saa = 1
if not exist(dt_pre_saa) then dt_pre_saa = 1
if not exist(dt_plot_win_hr) then dt_plot_win_hr = 1

; Set defaults for hinode_pointing_scan:
if keyword_set(no_plot) then quiet = 1
if not exist(xs_win_helio) then xs_win_helio = 256+128
if not exist(ys_win_helio) then ys_win_helio = xs_win_helio
if not exist(grid_spac) then grid_spac = 15

;get_obev, date, ts_saa=ts_saa, te_saa=te_saa, t_op_start=t_op_start, t_op_end=t_op_end, $
;  t0_evt=t0_evt, t1_evt=t1_evt
merge_events, date, ts_evt=ts_evt, te_evt=te_evt, ts_saa=ts_saa, te_saa=te_saa, $
  t_op_start=t_op_start, t_op_end=t_op_end, t0_evt=t0_evt, t1_evt=t1_evt, $
  do_plot=do_plot, verbose=verbose, qstop=qstop

ts_saa = ts_evt
te_saa = te_evt

case ts_saa[0] of
   0: begin
        print, 'No OBEV file for ' + strtrim(date) + '.  Returning.'
        return
      end
  -1: begin
        print, 'No SAAs found in OBEV file for ' + strtrim(date) + '.  Returning.'
        return
      end
  else: break
endcase

case t_op_start[0] of
   0: begin
        print, 'No OP_PERIOD file for ' + strtrim(date) + '.  Returning.'
        return
      end
  -1: begin
        print, 'No OP_START found in OP_PERIOD file for ' + strtrim(date) + '.  Returning.'
        return
      end
  else: break
endcase

set_plot, 'x'
pnt_arr = hinode_pointing_scan(date, BFI=bfi, NFI=NFI, SP=sp, SCAN=scan, OVERLAP=overlap, CCD=ccd, $
            LATITUDE=latitude, NPOINT=npoint, LONGITUDE=longitude, HORIZONTAL=horizontal, MUVALUE=muvalue, $
            MUARC=muarc, MUCIRCLES=MUCIRCLES, NOERASE=noerase, COLOR=color, OUTFILE=outfile, ROUND=round, $
            xs_win=xs_win_helio, ys_win=ys_win_helio, GRID_SPAC=grid_spac, QUIET=quiet, _extra=_extra)

if not keyword_set(no_plot) then begin
  plot_buff = tvrd()
  wdelete
endif

n_reps_req = n_elements(pnt_arr[0,*])

ts_saa_sec = anytim(ts_saa)
te_saa_sec = anytim(te_saa)

;if min(ts_saa_sec) lt min(te_saa_sec) then $
;  te_saa_sec = [anytim(t0_evt), te_saa_sec]
;if max(te_saa_sec) gt max(ts_saa_sec) then $
;  ts_saa_sec = [ts_saa_sec, anytim(t1_evt)]
if min(te_saa_sec) lt min(ts_saa_sec) then $
  ts_saa_sec = [anytim(t0_evt), ts_saa_sec]
if max(ts_saa_sec) gt max(te_saa_sec) then $
  te_saa_sec = [te_saa_sec, anytim(t1_evt)]

n_ts_saa = n_elements(ts_saa_sec)
n_te_saa = n_elements(te_saa_sec)

ts_interv_arr = te_saa
te_interv_arr = ts_saa

;if not exist(ts_win) then ts_win = anytim(min([anytim(ts_interv_arr), anytim(te_interv_arr)]) )
;if not exist(te_win) then te_win = anytim(max([anytim(ts_interv_arr), anytim(te_interv_arr)]) )
if not exist(ts_win) then begin
  ts_win_sec = anytim(t_op_start) + dt_op_start*60d0
endif else begin
  if anytim(ts_win) gt anytim(t_op_end) then begin
    print, 'Specified TS_WIN is after OP_END time found in OP_PERIOD file for ' + strtrim(date) + '.  Returning.'
STOP
    return
  endif
  if anytim(ts_win) lt (anytim(t_op_start) + dt_op_start*60d0) then $
    ts_win_sec = anytim(t_op_start) + dt_op_start*60d0 else $
    ts_win_sec = anytim(ts_win)
endelse

if not exist(te_win) then begin
  te_win_sec = anytim(t_op_end)
endif else begin
  if anytim(te_win) gt anytim(t_op_end) then te_win_sec = anytim(t_op_end) else $
    te_win_sec = anytim(te_win)
endelse

select_times, ts_win_sec, te_win_sec, t_rep_dur=dt_dwell_min, ts_interv_arr, te_interv_arr, $
  n_reps_req=n_reps_req, ts_offset=dt_post_saa, te_offset=dt_pre_saa, $
  n_reps_good=n_reps_good, ts_rep_arr = ts_rep_arr, te_rep_arr = te_rep_arr, $
  ts_interv_out = ts_interv_out, te_interv_out = te_interv_out, status=status

t_pnt_arr = anytim(ts_rep_arr, /ccsds)

if not keyword_set(no_plot) then begin
  cleanplot
  window, xs=1024+256, ys=256+128, /free

;  timerange = [anytim(min([ts_rep_arr, te_rep_arr]) - 3600d0, /ccsds), $
;               anytim(max([ts_rep_arr, te_rep_arr]) + 3600d0, /ccsds)]
  timerange = [anytim(min([ts_rep_arr, te_rep_arr]) - dt_plot_win_hr*3600d0, /ccsds), $
               anytim(max([ts_rep_arr, te_rep_arr]) + dt_plot_win_hr*3600d0, /ccsds)]

  p_old = !p
  !p.region = [(256.+128.)/(1024.+256.),0,1,1]

  tv, plot_buff
  utplot, t_pnt_arr, pnt_arr[0,*], timerange=timerange, xstyle=1, yrange=[-1000,1000], ystyle=1, $
    psym=6, linestyle=0, /noerase

; Plot and fill in any SAAs included in plot time window:
;  ss_saa_good = where( (ts_saa_sec[0:n_ts_saa-1] gt anytim(timerange[0]) )  and $
;                         (te_saa_sec[1:*]          lt anytim(timerange[1]) ), n_saa_good)
  ss_saa_good = where( (ts_saa_sec gt anytim(timerange[0]) )  and $
                         (te_saa_sec lt anytim(timerange[1]) ), n_saa_good)
  if n_saa_good gt 0 then begin 
;    ts_saa_good = (ts_saa_sec[0:n_ts_saa-1])[ss_saa_good]
;    te_saa_good = (te_saa_sec[1:*]         )[ss_saa_good]
    ts_saa_good = ts_saa_sec[ss_saa_good]
    te_saa_good = te_saa_sec[ss_saa_good]
;    t0 = anytim(timerange[0])
    pattern_saa = bytarr(10,10)
    for i=0,9 do pattern_saa[i,i] = 255b
    for i=0, n_elements(ts_saa_good)-1 do begin
      x_poly = [ts_saa_good[i], te_saa_good[i], te_saa_good[i], ts_saa_good[i]] - anytim(timerange[0])
      y_poly = [!y.crange[0],!y.crange[0],!y.crange[1],!y.crange[1]]
      polyfill, x_poly, y_poly, pattern=pattern_saa
    endfor
  endif

; Fill in selected intervals:
  pattern_rep = bytarr(20,20)
  for i=0,19 do pattern_rep[i,19-i] = 255b
  for i=0, n_elements(ts_rep_arr)-1 do begin
    x_poly = [ts_rep_arr[i], te_rep_arr[i], te_rep_arr[i], ts_rep_arr[i]] - anytim(timerange[0])
    y_poly = [!y.crange[0],!y.crange[0],!y.crange[1],!y.crange[1]]
    polyfill, x_poly, y_poly, pattern=pattern_rep
  endfor

  outplot, t_pnt_arr, pnt_arr[0,*], psym=6, linestyle=0, thick=2
  outplot, t_pnt_arr, pnt_arr[1,*], psym=5, linestyle=0, thick=2

  if n_saa_good gt 0 then begin 
    evt_grid, anytim(ts_saa_good, /ccsds), fillstyle=1, linestyle=1
    evt_grid, anytim(te_saa_good, /ccsds), fillstyle=1, linestyle=2
  endif

  evt_grid, anytim(ts_rep_arr, /ccsds), fillstyle=2, linestyle=3
  evt_grid, anytim(te_rep_arr, /ccsds), fillstyle=2, linestyle=4

; Make a legend (TODO - Replace current logic with calls to polyfill):
  x_sym_saa = [-2, 2, 2,-2,-2,-1,-2,-2,-1, 0,-2,-2, 0, 1,-2,-2, 1, 2]*2
  y_sym_saa = [-1,-1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1]*2
  x_sym_rep = -x_sym_saa
  x_sym_saa = [-4, x_sym_saa] + 2
  y_sym_saa = [-2, y_sym_saa]
  x_sym_rep = [-4, x_sym_rep] + 2
  y_sym_rep =  y_sym_saa

;  usersym, x_sym_saa, y_sym_saa
  legend, ['    SAA/Night intervals', '    Scan interval', '    Helio X coord (arcsec)', '    Helio Y coord (arcsec)'], $
          psym=[8,3,5,6], usersym=transpose([[x_sym_saa],[y_sym_saa]])
;  usersym, x_sym_rep, y_sym_rep
  legend, ['    SAA interval', '    Scan interval', '    Helio X coord (arcsec)', '    Helio Y coord (arcsec)'], $
          psym=[3,8,5,6], usersym=transpose([[x_sym_rep],[y_sym_rep]])

;  x0 = !x[0].crange & x1 = !x[1].crange & y0 = !y[0].crange & y1 = !y[1].crange
;  xwid = x1-x0 & ywid = y1-y0
;  x_poly = [x0+.05*xwid, x0+.10*xwid, x0+.10*xwid, x0+.05*xwid]
;  y_poly = [y0+.05*ywid, y0+.05*ywid, y0+.10*ywid, y0+.10*ywid]
;  x_poly = [.05*xwid, .10*xwid, .10*xwid, .05*xwid]
;  y_poly = [.05*ywid, .05*ywid, .10*ywid, .10*ywid]
;  polyfill, x_poly, y_poly, pattern=pattern_saa

  !p = p_old
endif

if not keyword_set(no_print) then begin
  print, ''
  print, 'Time (UT)              Helio X (sec)   Helio Y (sec)'
  for i=0, n_reps_req-1 do print, strmid(t_pnt_arr[i],0,19) + '     ' + string(pnt_arr[0,i], format='$(f8.2)') + $
                                                 '        ' + string(pnt_arr[1,i], format='$(f8.2)')
  print, ''
endif

end
