;+
;
; Project   : general display tools
;                   
; Name      : threeview
;               
; Purpose   : standalone, used as part of the s3drs GUI
;               
; Explanation: Utility to view imagecubes
;               
; Use       : see documentation in code
;    
; Inputs    : (many, see code below)
;               
; Outputs   : optionally can return the data it creates from the cube
;
; Keywords  : (many, see code below)
;               
; Common    : 
;               
; Restrictions: none
;               
; Side effects: 
;               
; Category    : display
;               
; Prev. Hist. : None.
;
; Written     : Sandy Antunes, NRC, March-April 2009
;               
;-            
; prints a simple labeled 3-view of a given data cube
; does optional downsampling for experimental reduced array cases
; where N^3 is too big to store
;
; Optionally will return images in the 'datum' field, if given
;
; Can handle an image cube or pointer to an image cube (automatically).
;
; Optional /four option includes a 4th 'corner view' at 45,45
;
; /pixon reorients according to classic Pixon axes rather than default IDL
;
; If given /noplot, does not plot but just generates the image sets
; (presumable for return in the optional 'datum' field)
;
; /rtwl will use RTWL to render instead of just doing a projection,
; while /render will use pr_render to render the items.
;
; If given /carve, removes corner of cube leaving only interior
; spherical portion.
; If given /cor2, removes both the outer sphere part and the inner
; sun/occulter region, assuming typical Cor2 geometry.
;
; Optional array 'xyangles' plots in the Z-view lines from the center
; out to those angles.  For example xyangles=[angleSTEREOA,angleSTEREOB]
; is handy to see where the A & B satellites are from the top view.
;

PRO threeview,image,datum,rescale=rescale,dieplot=dieplot,title=title,$
              inverse=inverse,logplot=logplot,render=render,rtwl=rtwl,ps=ps, $
              normalize=normalize,sample=sample,ct=ct,winid=winid, $
              four=four,oom=oom,extras=extras,both=both,fontsize=fontsize,$
              fixedsize=fixedsize,pixon=pixon,noplot=noplot,autocap=autocap,$
              filename=filename,surpressaxes=supressaxes,raw=raw,cm=cm,$
              slideshow=slideshow,header=header,carve=carve,cor2=cor2,$
              xyangles=xyangles

  if (n_elements(title) eq 0) then title=''
  noplot=KEYWORD_SET(noplot)
  dieplot=KEYWORD_SET(dieplot)
  ps=KEYWORD_SET(ps)
  render=KEYWORD_SET(render)
  rtwl=KEYWORD_SET(rtwl)
  normalize=KEYWORD_SET(normalize)
  four=KEYWORD_SET(four)
  raw=KEYWORD_SET(raw)
  carve=KEYWORD_SET(carve)
  cor2=KEYWORD_SET(cor2)
  pixon=KEYWORD_SET(pixon)
  if (n_elements(supressaxes) ne 0) then axes=0 else axes=1
  if (n_elements(ct) ne 0) then loadct,ct
  if (n_elements(sample) eq 0) then sample=0
  extras=KEYWORD_SET(extras); sets extra axes labels of x,y,z, etc
  both=KEYWORD_SET(both); flag to do both normal and log plots together

  current_device=!d.name; in case needed for postscript use

  freeme=1; used to free the pointer in most, but not all, cases
  if (datatype(image) eq 'PTR') then begin

      if (n_elements(image) eq 1) then begin
          ; it is just a single pointer to an image
          timage=image[0]
          freeme=0; because we are accessing the actual pointer, do not free

      end else begin

          ; experimental handling of a large array handling variant
          N=n_elements(image)
          if (sample gt 1) then N=N/sample

          ttemp=fltarr(N,N,N)

          if (sample gt 1) then begin
              for m=0,N-1,sample do ttemp[*,*,m/4] = congrid(*image[m],N,N)
          end else begin
              for m=0,N-1 do ttemp[*,*,m]=*image[m]
          end

          timage=ptr_new(ttemp,/no_copy)

      end

  end else begin
      if (sample gt 1) then begin
          timage=ptr_new(/allocate_heap)
	  *timage = congrid(image,N/sample,N/sample,N/sample)
      end else begin
          timage=ptr_new(/allocate_heap)
	  *timage=image
      end
  end

  if (carve or cor2) then begin
      ; convert cube to sphere
      N=(size(*timage,/DIMENSION))[0]
      r_inner=0
      r_outer=N/2
      if (cor2) then begin
          m=p_getmask('COR2',N,rpixels=rpixels)
          r_inner=rpixels[0]
          r_outer=rpixels[1]
      end
      mask3D=cube_sphere(N,r_inner,r_outer=r_outer); removes corners
      *timage = *timage * mask3D
  end

  if (render) then begin

      N=(size(*timage,/DIMENSION))[0]
      ; save first three for x-y-z, or all 6 for dieplots

      if (pixon) then begin
          gamma=[0.0,90.0,0.0]
          theta=[0.0,0.0,90.0]
      end else begin
          gamma=[0.0,90.0,0.0]
          theta=[90.0,0.0,0.0]
      end
      nframes=3
      if (four) then begin
          nframes=4
          if (pixon) then set2=[45.0,45.0] else set2=[45.0,-45.0]
          gamma=[gamma,set2[0]]
          theta=[theta,set2[1]]
      end else if (dieplot) then begin
          nframes=6
          gamma=[gamma,-90.0,-180.0,0.0]
          theta=[theta,0.0,0.0,-90.0]
      end

      prep_3drv,pxwrapper,views=nframes,gamma=gamma,theta=theta,N=N

      datum=pr_render(pxwrapper,*timage)

      if (four) then begin
          if (pixon) then $
            datum[*,*,3]=rotate(datum[*,*,3],7) else $
            datum[*,*,3]=datum[*,*,3]
      end

      if (pixon eq 0) then $
        datum[*,*,0]=rotate(datum[*,*,0],1)

  end else if (rtwl) then begin

      N=(size(*timage,/DIMENSION))[0]
      ; save first three for x-y-z, or all 6 for dieplots
      if (dieplot) then nframes=6 else nframes=3
      if (four and nframes eq 3) then nframes=4; additional corner view
      datum=fltarr(N,N,nframes)

      modparam=timage2modparam(*timage)

      for i=0,nframes-1 do begin

          if (i eq 0) then neang=[0,180,0]
          if (i eq 1) then neang=[-90,0,0]
          if (i eq 2) then neang=[0,0,0]
          if (i eq 3) then neang=[90,0,0]
          if (i eq 4) then neang=[0,90,0]
          if (i eq 5) then neang=[0,-90,0]

          raytracewl,sbt,imsize=[N,N],losnbp=long(N),losrange=[-20,20],$
            modelid=25,modparam=modparam,neang=neang*!dtor,/cor2

          ; now convert RTWL to Die-frame
          if (i eq 0) then sbt.im=rotate(sbt.im,1); 90 CCW
          if (i eq 1) then sbt.im=rotate(sbt.im,4); transpose
          if (i eq 2) then sbt.im=rotate(sbt.im,3); 90 CW
          if (i eq 3) then sbt.im=rotate(sbt.im,4); transpose
          if (i eq 4) then sbt.im=rotate(sbt.im,6); transpose
          if (i eq 5) then sbt.im=rotate(sbt.im,6); transpose

          datum(*,*,i)=sbt.im
      end

  end else begin

      if (pixon eq 1 and dieplot eq 0) then begin
          ; Pixon's idea of what x/y/z are
          img_ij=ijkproj(*timage,'jk')
          img_ik=rotate(ijkproj(*timage,'ik'),5); 3,5
          img_jk=rotate(ijkproj(*timage,'ji'),7); 1,7
      end else begin
          ; the IDL default 3-axes
          img_ij=ijkproj(*timage,'ij')
          img_ik=ijkproj(*timage,'ik')
          img_jk=ijkproj(*timage,'jk')
      end

      if (dieplot) then begin
          ; only make these if we need all 6 images for a die
          img_kj=ijkproj(*timage,'kj')
          img_ji=ijkproj(*timage,'ji')
          img_ki=ijkproj(*timage,'ki')
      end

      if (four) then begin
      ; rotational way of doing quarter-rotation for corner view
      ; imagetemp=*timage
      ; cuberot3d,imagetemp,[45.0,45.0,45.0]
          if (pixon) then begin
              img_q = $
;                ijkproj(turn_3d(*timage,45.0,45.0,0.0,/resize,/reverse),'ji')
;              img_q=rotate(img_q,7) ; -90 and transpose
                ijkproj(turn_3d(*timage,0.0,45.0,45.0,/resize),'ij')
          end else begin
              img_q = ijkproj(turn_3d(*timage,45.0,0.0,45.0,/resize),'ij')
          end

      end
  end

  if (n_elements(xyangles) ne 0) then begin
      if (pixon) then xylines,img_jk,xyangles+90 else xylines,img_jk,xyangles
      if (n_elements(img_kj) ne 0) then xylines,img_kj,90.0+xyangles
  end

  if (render or rtwl) then begin
      ; important that this be the first, preemptive call of this loop

      ; datum already populated, just build title
      title=title + ' renders'

  end else if (dieplot) then begin

      img_ji=rotate(img_ji,3); 3=rotate 90 CW, 1 = 90 CCW
      img_ki=rotate(img_ki,3); rotate 90 CW
      img_kj=rotate(img_kj,2); rotate 180
      img_jk=rotate(img_jk,3); rotate 180

      datum=[[[img_ij]],[[img_ik]],[[img_ji]],[[img_ki]],[[img_kj]],[[img_jk]]]
      title=title + ' dieplot projection'
      
  end else begin

      ; plus just the normal 3 views
      if (four) then begin
          datum=[[[img_ij]],[[img_ik]],[[img_jk]],[[img_q]]]
          title=title + ' ij, ik, jk, and corner projections'
      end else begin
          datum=[[[img_ij]],[[img_ik]],[[img_jk]]]
          if (pixon) then begin
              title=title + ' cpixon x, y, and z projections'
          end else begin
              title=title + ' ij, ik, and jk projections'
          end
      end

  end
;  help,datum
;  print,title,cubeview

  if (freeme) then ptr_free,timage

  if (noplot) then return

  if (n_elements(filename) eq 0) then filename='threeview.ps'

  if (four) then lb=4 else lb=3

  tv_multi,datum,border='yes',axes=axes,rescale=rescale,title=title, $
    dieplot=dieplot,logplot=logplot,inverse=inverse,ps=ps,winid=winid,oom=oom,$
    ymargin=0,linebreak=lb,both=both,fontsize=fontsize,fixedsize=fixedsize,$
    /land,filename=filename,nocloseps=extras,raw=raw,autocap=autocap,cm=cm,$
    slideshow=slideshow,header=header


  ; scaling still tbd on this, but it works mostly fine like this
;  if (extras) then begin
;      xyouts,0.20,0.9,'+z view',alignment=0.5,/normal
;      xyouts,0.50,0.9,'-y view',alignment=0.5,/normal
;      xyouts,0.80,0.9,'+x view',alignment=0.5,/normal
;  end

  if (extras) then begin
; !M6 = right, !M7 = up, !M5 = down, !M4 = left
      xyouts,0.18,0.88,"z!M7",alignment=0.5,/normal,color=0
      xyouts,0.33,0.55,"!M6y",alignment=0.5,/normal,color=0
      xyouts,0.50,0.88,"z!M7",alignment=0.5,/normal,color=0
      xyouts,0.36,0.55,'x!M4',alignment=0.5,/normal,color=0
      xyouts,0.81,0.25,'x!M5',alignment=0.5,/normal,color=0
      xyouts,0.95,0.55,'!M6y',alignment=0.5,/normal,color=0; !D.N_COLORS-1

      if (ps) then begin
          device,/CLOSE_FILE
          set_plot,current_device
      end

  end

END
