;+

pro plot_hxt, index0, data0, force_number=force_number, A4=A4, $
              levels=level, independent=independent, ps=ps, fileps=psfile, $
              noerase = noerase, title=title, sample=sample, image=image, $
              rowcol=rowcol, legal=legal, nowords=nowords, nogrids=nogrids, $
              noboxes=noboxes, nocontours=nocontours,limb=limb,latlon=latlon, $
              bin=bin,nocloseps=nocloseps,colorbox=colorbox,colorcontour=color, $
              labels=plotlabel,noscaleimg=noscaleimg,nlevels=nlevels,nolimb=nolimb

;NAME:
;     PLOT_HXT
;PURPOSE:
;     Plots a series of HXT images as contours.
;CATEGORY:
;CALLING SEQUENCE:
;     plot_hxt,index,data
;INPUTS:
;     index = index with index.hxi and index.gen substructures
;     data = HXT image data cube
;OPTIONAL INPUT PARAMETERS:
;KEYWORD PARAMETERS
;     rowcol = number of rows,columns to plot, [rows,cols].  rows*columns
;              must be GE to the number of images.
;     level = contour levels in fraction of max value.
;             default = [0.04,0.08,0.15,0.25,0.4,0.65,0.95]
;     nlevels = specify the number of equally spaced levels.  Ignored if level is
;               set.
;     independent = Scale each image indepently.  The default is to scale
;                   the entire data cube so that relative intensities are
;                   preserved from image to image.
;     /sample = use /sample in rebin
;     image = data cube of images to display under the contours.  Must have
;             the same dimensions as data.  However, if image is a 2-D array
;             with the same dimension as the images in data, the single image
;             is displayed under each data image.
;     /noscaleimg = Do no bytescale the underlying images.  the default is
;                   to display each image independently with tvscl.  If
;                   /noscaleimg is set, the images must be byte type and
;                   will be displayed with tv rather than tvscl.
;     force_number = force this number of plots on the output
;     /limb = Plot a contour representing the solar limb.  See restrictions, 
;             below.  This is now the default.  Use /nolimb to turn the limb 
;             off.
;     /latlon = Plot a lat/lon grid.  See restrictions, below.
;     labels = String array giving a label for each image.
;     /nowords = do not annotate the plots
;     /nogrids = do not plot grids on images
;     /noboxes = do not plot boxes around images
;     /noerase = do not erase the display before plotting.
;     /nocontours = do not plot contours.  This makes little sense unless you
;                   set the image keyword.
;     /ps = Use PostScript.  If the current graphics device is 'PS', the /ps
;           keyword is the default.
;     fileps = PostScript file, default is idl.ps 
;     /nocloseps = Do not close the PS device after plotting.  This is useful if you
;                  want to add more annotations etc to the plot.  the side effects are
;                  that the device is left as PS after the program and, of course,
;                  you will have to close the PS file yourself.
;     /legal = Use legal size paper size. Ignored except for PostScript output.
;     /A4 = Use A4 paper size.  Ignored except for PostScript output.
;     title = title for plot
;     bin = binup factor for the images (def = 4)
;OUTPUTS:
;COMMON BLOCKS:
;SIDE EFFECTS:
;RESTRICTIONS:
;     The /independent keyword only makes sense if the /nonorm keyword was
;     passed to hxt_multimg.  If /nonorm was not used, the images are
;     already scaled independently.
;PROCEDURE:
;     The data cube is byte scaled and plotted as contours.  Use the 
;     /independent keyword to scale each image independently
;MODIFICATION HISTORY:
;     T. Metcalf 1995-06-29  Borrowed lots of code from N. Nitta's routines
;                1995-08-21  Added /limb and /latlon keywords
;                1996-11-13  Added bin keyword.
;                1997-01-24  Added nlevels keyword.
;                            Modified so that the index need not be specified.
;                1998-03-25  Fixed bug in the lat/lon calculation.
;                1998-05-11  Made the limb contour smoother.  Removed 
;                            restrictions on lat/lon which made the grid fail
;                            if the FOV center was off the limb.
;-

if n_elements(sample) NE 1 then sample = 0

data=data0

sz=size(data0)
if sz(0) LT 2 then message,'Data must have at least 2 dimensions'
nx = sz(1) & ny = sz(2) & nimages = n_elements(data0(0,0,*))
if n_elements(bin) NE 1 then bin = 4L
xbin=nx*long(bin) & ybin=ny*long(bin)

sindex = size(index0)
qhxiindex = 0
;;index = {}
if n_elements(index0) EQ nimages and sindex(n_elements(sindex)-2) EQ 8 then begin
   if tag_index(index0,'HXI') GE 0 then begin
      index=index0 
      qhxiindex = 1
   endif
endif

psave = !p

got_x0_y0 = 0
if keyword_set(latlon) OR NOT keyword_set(nolimb) then begin
   if qhxiindex then begin
      if tag_index(index.hxi,'X0') GE 0 AND tag_index(index.hxi,'Y0') GE 0 then begin
         x0 = index.hxi.x0
         y0 = index.hxi.y0
         xy = transpose([[x0],[y0]])
         llhxt = conv_hxt2h(xy,index)
         aahxt = conv_hxt2a(xy,index)
         message,/info,'Assuming SXT sized pixels for lat/lon calculation'
         lat = fltarr(xbin,ybin,nimages)
         cmd = fltarr(xbin,ybin,nimages)
         rho = fltarr(xbin,ybin,nimages)
         for i=0L,nimages-1L do begin
            ll = get_latlon(nx=xbin,ny=ybin,x0=(aahxt(0)/gt_pix_size())*float(bin), $
                                y0=(aahxt(1)/gt_pix_size())*float(bin), $
                                pixsize=gt_pix_size()/float(bin),date=index(i),/solar, $
                                rho=rhos,theta=theta, $
                                b0=get_rb0p(index(i),/b0))
            off_limb = where(rhos GE 1.0,noff_limb)
            on_limb = where(rhos LT 1.0,non_limb)
            if noff_limb GT 0 then begin
               ; Recalculate rhos so that the values off the limb are also
               ; computed.   Makes the limb contour smoother.
               rnx = n_elements(rhos(*,0))
               rny = n_elements(rhos(0,*))
               x0y0 = aahxt(*,i) / get_rb0p(index(i),/radius)
               x = (lindgen(rnx,rny) MOD rnx - (rnx-1)/2.)*gt_pix_size()/get_rb0p(index(i),/radius)/float(bin)
               y = (lindgen(rnx,rny) / rnx - (rny-1)/2.)*gt_pix_size()/get_rb0p(index(i),/radius)/float(bin)
               rhos = sqrt((x+x0y0(0))^2+(y+x0y0(1))^2)
               ; Make sure that contours are not plotted off the limb
               ll.latitude(off_limb) = !values.f_nan
               ll.cmd(off_limb) = !values.f_nan
            endif
            lat(*,*,i) = ll.latitude
            cmd(*,*,i) = ll.cmd
            rho(*,*,i) = rhos
         endfor
         got_x0_y0  = 1
      endif else message,/info,'No X0 and/or Y0 tags in HXI index'
   endif else message,/info,'No HXI tag in index'
endif

chan_str = ['LO','M1','M2','HI']

ntot=nimages   ;n_elements(index) ; actual number of images
nplot=ntot 

tot_str=strarr(ntot) 
if qhxiindex then $
   for i=0,ntot-1 do tot_str(i)=string(index(i).hxi.cnts_p_cm2,format='(f7.1)')
max_str=strarr(ntot)
if qhxiindex then $
   for i=0,ntot-1 do max_str(i)=string(index(i).hxi.max_bright/ $
                          index(i).hxi.actim*10.,format='(f9.5)')

if n_elements(level) eq 0 then begin
   if keyword_set(nlevels) then level = (findgen(nlevels)+1.)/float(nlevels)$
   else level=[0.04,0.08,0.15,0.25,0.4,0.65,0.95]
endif
level1=level*255

data = make_array(size=sz,/byte)
if keyword_set(independent) then begin
   for i=0L,ntot-1L do data(*,*,i) = bytscl(data0(*,*,i))
endif else begin
   data = bytscl(data0)
endelse

yt = long(sqrt(nplot)+0.5)             ; Number of rows to plot
xt = float(nplot)/yt                   ; Number of cols to plot
if xt-long(xt) NE 0.0 then xt=xt+1
xt = long(xt)
nplot = xt*yt
if keyword_set(force_number) then nplot = force_number(0) > nplot
if n_elements(rowcol) EQ 2 then begin
   if rowcol(0)*rowcol(1) GE ntot then begin
      xt = rowcol(1)
      yt = rowcol(0)
   endif
endif

if qhxiindex then begin
   t_st=gt_time(index,/str)
   t_en=gt_time(addtime(index,delta_min=index.hxi.interval/10./60.),/str)
endif else begin
   t_st=strarr(nimages)
   t_en=strarr(nimages)
endelse

if keyword_set(ps) OR !d.name eq 'PS' then begin
   ylong=27.94 & xlong=21.59
   if n_elements(legal) gt 0 then begin & ylong=35.56 & xlong=21.59 & endif
   if n_elements(a4) gt 0 then begin & ylong=29.72 & xlong=21.06 & endif
   ys = ylong - 4.0
   xs = xlong - 4.0
   xoff=(xlong-ys)/2. & yoff=(ylong-xs)/2.+ xs   ; landscape mode
   old_device = !d.name
   if !d.name ne 'PS' then set_plot,'ps'
   device,/land,xs=xs,ys=ys,xoff=xoff,yoff=yoff,/helv
   spsf = size(psfile)
   if spsf(n_elements(spsf)-2) EQ 7 then device,file=psfile
   if n_elements(image) EQ n_elements(data) then begin
      if n_elements(color) LE 0 then color=!d.n_colors-1
      if n_elements(colorbox) LE 0 then colorbox = 0
   endif else begin
      if n_elements(color) LE 0 then color = 0
      if n_elements(colorbox) LE 0 then colorbox = 1
   endelse
endif else begin
   if n_elements(color) LE 0 then color = !d.n_colors-1
   if n_elements(colorbox) LE 0 then colorbox = 0
endelse

position = pixsquare(xt,yt,position=[0.,0.,1.,1.])

if NOT keyword_set(noerase) then erase

xnorm = position(2)-position(0) ; Size of plotting region (normal coords)
ynorm = position(3)-position(1)

xs=xnorm/xt & ys=ynorm/yt ; Size of box (normal coords)

ii=indgen(nplot)
xx=xs*(ii mod xt)+position(0)     ; Normal coord of LL box corners
yy=ys*((yt-1)-ii/xt)+position(1)

; Draw Contours and images

device_sz = convert_coord(xx+xs,yy+ys,/normal,/to_device) - $
            convert_coord(xx,yy,/normal,/to_device)

imageok = 0
image2d = 0
szimage = size(image)
if szimage(0) EQ 2 and n_elements(image) EQ sz(1)*sz(2) then begin
   imageok = 1
   image2d = 1
endif
if szimage(0) EQ 3 and n_elements(image) EQ n_elements(data) then begin
   imageok = 1
endif
if n_elements(image) GT 0 AND NOT imageok then message,/info,'Image has an incompatible dimension'

for i=0,ntot-1 do begin
   if imageok then begin
      if image2d then idisplay = image else idisplay = image(*,*,i)
      if !d.name eq 'PS' then begin
         if keyword_set(noscaleimg) then $
            tv,rebin(idisplay,xbin,ybin,sample=sample),xx(i),yy(i), $
               xsize=xs,ysize=ys,/normal $
         else $
            tvscl,rebin(idisplay,xbin,ybin,sample=sample),xx(i),yy(i), $
                  xsize=xs,ysize=ys,/normal
      endif else begin
         if sample NE 0 then interp = 0 else interp = 1
         if keyword_set(noscaleimg) then $
            tv,congrid(idisplay,device_sz(0,i),device_sz(1,i),interp=interp), $
               xx(i),yy(i),/normal $
         else $
            tvscl,congrid(idisplay,device_sz(0,i),device_sz(1,i),interp=interp),xx(i),yy(i),/normal
      endelse
   endif
   if NOT keyword_set(nocontours) then $
      ocontour2,rebin(data(*,*,i),xbin,ybin,sample=sample),xx(i),yy(i), $
                xx(i)+xs,yy(i)+ys,/norm,color=color,c_color=[color], $
                level=level1 $
   else $
      contour,/nodata,rebin(data(*,*,i),xbin,ybin,sample=sample), $
              xstyle=1+4,ystyle=1+4,/noerase, $
              position=[xx(i),yy(i),xx(i)+xs,yy(i)+ys], $
              /normal,color=color
   if got_x0_y0 then begin
      if keyword_set(latlon) then begin
         lllev = [0.,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80]
         labels = intarr(n_elements(lllev)) & labels(*)=1
         ocontour2,lat(*,*,i),xx(i),yy(i), $
            xx(i)+xs,yy(i)+ys,/norm,color=color,c_color=[color], $
            level=lllev,c_labels=labels
         ocontour2,cmd(*,*,i),xx(i),yy(i), $
            xx(i)+xs,yy(i)+ys,/norm,color=color,c_color=[color], $
            level=[lllev,90],c_labels=labels
         ocontour2,lat(*,*,i),xx(i),yy(i), $
            xx(i)+xs,yy(i)+ys,/norm,color=color,c_color=[color], $
            level=-rotate(lllev,2),c_labels=labels
         ocontour2,cmd(*,*,i),xx(i),yy(i), $
            xx(i)+xs,yy(i)+ys,/norm,color=color,c_color=[color], $
            level=[-90,-rotate(lllev,2)],c_labels=labels
      endif
      if NOT keyword_set(nolimb) then begin  ; draw the limb
         ocontour2,rho(*,*,i),xx(i),yy(i), $
            xx(i)+xs,yy(i)+ys,/norm,color=color,c_color=[color],level=[1.0], $
            c_labels=[0]
      endif
   endif
endfor
 
; Draw Annotations
 
if NOT keyword_set(nowords) AND qhxiindex then begin
   for i=0,ntot-1 do xyouts,xx(i)+xs/20,yy(i)+0.93*ys,t_st(i)+' - '+t_en(i)+'  '+chan_str(index(i).hxi.chan), $
       font=6,col=color,/norm
   for i=0,ntot-1 do xyouts,xx(i)+xs/20.,yy(i)+0.05*ys, $
       'Max = '+max_str(i)+' cts/s',font=6,col=color,/norm
   for i=0,ntot-1 do xyouts,xx(i)+xs/20.,yy(i)+0.15*ys, $
       'Total(16)= '+tot_str(i)+' cts/cm!u2!n',font=6,col=color,/norm
endif
if n_elements(plotlabel) GT 0 then begin
   for i=0,ntot-1 do xyouts,xx(i)+xs*0.95,yy(i)+0.05*ys, $
      plotlabel(i<(n_elements(plotlabel)-1)),font=6,col=color,/norm,align=1.0
endif
if keyword_set(title) then $
    xyouts,position(0)+xnorm/2., $
           position(3)+float(!d.y_ch_size)/!d.y_size, $
           string(title),/normal,align=0.5,font=6,col=color
 
; Draw Boxes
 
if NOT keyword_set(noboxes) then begin
   !p.thick=4 & draw_box_nn,position(0),position(1),position(2),position(3),/norm,color=colorbox & !p.thick=0
   for i=0,xt-1 do plots,[xs,xs]*i+position(0),[position(1),position(3)],/norm,col=colorbox
   for i=0,yt-1 do plots,[position(0),position(2)],[ys,ys]*i+position(1),/norm,col=colorbox
endif
 
if NOT keyword_set(nogrids) then begin
   !p.linestyle=1
   for i=1,4*xt-1 do plots,[xs/4,xs/4]*i+position(0),[position(1),position(3)],/norm,col=colorbox
   for i=1,4*yt-1 do plots,[position(0),position(2)],[ys/4,ys/4]*i+position(1),/norm,col=colorbox
   !p.linestyle=0
endif
 
if (keyword_set(ps) OR !d.name eq 'PS') AND  $
      (NOT keyword_set(nocloseps)) then begin
   device,/close 
   set_plot,old_device
endif
 

!p = psave

return
end
