;  12-Nov-2008 Hide firstFrame ne 0 within this routine, so calling program can ask
;		for first frame.
;  10-Nov-2008 don't force frame=0 when /INIT [BD]
;  02-Jul-2008 added capability for MIRO color cameras [BD]
;  19-Apr-2007 added keyword INIT in case frames don't start at 1 [BD]
;
;
;   IDL> img = CINELOAD('/p/nstxusr2/miro/MIRO_130363.cin', 100, /debug)
;   IDL> img = CINELOAD('/p/nstxusr2/phantom4/NSTX_130363.cin', 100, /debug)
;
; WRITTEN by Ricky Maqueda, Bill Davis & Werner Boeglin
;-----------------------------------------------------------------------------
FUNCTION CINELOAD, cine, frame, fps, exposure, init=init, bitcount=bitcount_out,  $
                   verbose=verbose, debug=debug, outMsg=outMsg, status=stat

COMMON cineload_local, lastFileName, lastIndex, lastShotOpened, $
   trigger, firstimage, LUN, imagecount, $
   offset_image_header, offset_setup, offset_image_offsets, $
   xpix, ypix, compression, bitcount, image_size, fps_local, exposure_local, $
   pimage, revXindex, revYindex, image

COMMON pointer_information, $
   file_get_type, $
   file_get_total_image_count, $
   file_get_first_image_number,$
   file_get_image_count, $
   file_get_offset_image_header, $
   file_get_offset_setup, $
   file_get_offset_image_offsets, $
   file_get_tigger_time, $
   get_xpix, $
   get_ypix, $
   get_bit_count, $
   get_compression, $
   get_image_size, $ 
   get_fps, $
   get_exposure

if n_elements( debug ) eq 0 then debug = 0
if debug then verbose = 1
if n_elements( verbose ) eq 0 then verbose = 0
;;;if not debug then on_ioerror, the_end

stat=1

Error_status=0
; Establish error handler. When errors occur, the index of the
; error is returned in the variable Error_status:
if not debug then CATCH, Error_status

;This statement begins the error handler:
IF Error_status NE 0 THEN BEGIN
   PRINT, 'FROM '+proname()+':'
   PRINT, 'Error index: ', Error_status
   PRINT, 'Error message: ', !ERROR_STATE.MSG
;;;   writelog, logFile, '   >>>(in sumEvents.pro) error:'+!ERROR_STATE.MSG, nlines=3
;;;   CATCH, /CANCEL
   stat=0
   if n_elements( lun ) gt 0 then begin
      close, lun
      free_lun, lun
   endif
   wait, 5
   if debug then stop
   return, -1
ENDIF

if n_params() lt 2 then begin
   print, 'Usage: IDL> image=CINE_LOAD( cine, frame [,...] )'
   return, -1
endif
outMsg = ''

if n_elements( lastShotOpened ) eq 0 then lastShotOpened  =  -99
if n_elements( lastFileName ) eq 0 then lastFileName  =  'none'

   ; don't open if used last time

if cine ne lastFileName then begin
   if n_elements( LUN ) gt 0 then begin
      close, LUN
      FREE_LUN, LUN
   endif
   if keyword_set( verbose ) then begin
      print, ' '
      print, 'Opening file '+cine
      print, ' '
   endif
   
   openr, LUN, cine, /get_LUN, /swap_if_big_endian, err=err
   if err ne 0 then begin
      a=dialog_message( 'In '+proname()+': '+cine+' not found')
      outMsg =  cine+' not found'
      stat=0
      return, -1
   endif

   lastFileName = cine
   firstImage = 0
   
; Pointer information

;
; Offsets into file
;

; file offsets

   file_get_type = 0l
   file_get_total_image_count = 12l
   file_get_first_image_number = 16l
   file_get_image_count = 20l
   file_get_offset_image_header = 24l
   file_get_offset_setup = 28l
   file_get_offset_image_offsets = 32l
   file_get_tigger_time = 36l

; offsets into image header
   get_xpix = 4l
   get_ypix = 8l
   get_bit_count = 14l
   get_compression = 16l
   get_image_size = 20l

; offsets into setup
   get_fps = 768l
   get_exposure = 772l

   firstimage=1l
   point_lun, lun, file_get_first_image_number
   if n_elements( firstImage ) le 1 then readu, lun, firstimage
   
   frameInFile = frame + firstImage

   imagecount=1ul
   point_lun, lun, file_get_image_count
   readu, lun, imagecount

   if keyword_set( verbose ) and frameInFile le firstImage then begin
      print, '----------------------------------------------------------------------'
      print, '----------------------------------------------------------------------'
      print, 'first image = ', firstimage
      print, 'image count = ', imagecount
   endif

; read offset for image header
   offset_image_header = 0l
   point_lun, lun, file_get_offset_image_header
   readu, lun, offset_image_header

; read file offset for setup information
   offset_setup = 0l
   point_lun, lun, file_get_offset_setup
   readu, lun, offset_setup

; read offset for frame pointers
   offset_image_offsets = 0l
   point_lun, lun, file_get_offset_image_offsets
   readu, lun, offset_image_offsets

   if keyword_set( verbose ) and frameInFile le firstImage then begin

      print, '----------------------------------------------------------------------'
      print, 'offsets information :'
      print, 'image header offsets = ', offset_image_header
      print, 'image setup offsets = ', offset_setup
      print, 'image frame offsets offsets = ', offset_image_offsets
   endif
; get image size

   xpix=1l
   point_lun, lun, offset_image_header+get_xpix
   readu, lun, xpix

   ypix=1l
   point_lun, lun, offset_image_header+get_ypix
   readu, lun, ypix

   bitcount = 1u
   point_lun, lun, offset_image_header+get_bit_count
   readu, lun, bitcount
   bitcount_out = bitcount

;;;   compression = 1ul
;;;   point_lun, lun, offset_image_header+get_compression
;;;   readu, lun, compression
Compression=0U
point_lun, lun, 4
readu, lun, Compression
   
   if compression eq 2 then begin
         ; with color camera have to unpack, etc.
      revXindex=reverse(indgen(xpix/2))
      revYindex=reverse(indgen(ypix/2))
      image = uintarr(3,xpix/2,ypix/2)
   endif

   imagesize = 1ul
   point_lun, lun, offset_image_header+get_image_size
   readu, lun, imagesize

   if keyword_set( verbose ) and frameInFile le firstImage then begin

      print, '----------------------------------------------------------------------'
      print, 'image size = ', xpix, ' by ', ypix
      print, 'compression = ', compression
      print, 'bitcount = ', bitcount
      print, 'image size (bytes) = ', imagesize
   endif
; get setup values

   fps_local=1ul
   point_lun, lun, offset_setup+get_fps
   readu, lun, fps_local
   
   exposure=1ul
   point_lun, lun, offset_setup+get_exposure
   readu, lun, exposure_local

; get pointers to image objects
   pimage=ulon64arr(imagecount)
   point_lun, lun, offset_image_offsets
   readu, lun, pimage

endif else begin
   frameInFile = frame + firstImage
endelse

fps = fps_local
exposure = exposure_local

if keyword_set( init ) then begin
   if n_elements( frameInFile ) eq 0 then frameInFile = 0
   if ((frameInFile lt firstimage) or (frameInFile gt firstimage+imagecount-1)) then begin
      outMsg='Desired frame ('+strtrim(frameInFile,2)+') not available, first is '+strtrim(firstimage,2)
      print, outMsg
      outMsg2='   Last is '+strtrim(firstimage+imagecount-1,2)
      print, outMsg2
      a=dialog_message( ['In '+proname()+':', ' ','for file '+cine, outMsg, outMsg2 ] )
      if debug then stop
      goto,the_end
   endif
endif

; get pointer to image object of current frame
pframe = pimage(frameInFile-firstimage)

; get length of annotation
aux=1ul
point_lun, lun, pframe
readu, lun, aux

;;;if keyword_set( verbose ) and frame eq 0 then begin
if keyword_set( verbose ) then begin
      
   print, 'annotation size : ', aux, frameInFile, firstimage, frameInFile-firstimage
   print, 'frame pointer : ', pframe
;;;   print, '----------------------------------------------------------------------'
   print, '----------------------------------------------------------------------'
endif
; read selected frame's picel array

; for 8 bit ADC's
if bitcount eq 8 then img=BYTARR(xpix,ypix)

; for 10 - 16 bit ADC's
if bitcount gt 8 then img=UINTARR(xpix,ypix)

point_lun, lun, pframe+aux
readu, lun, img

if compression eq 2 then begin
      ; color camera data packed with two greens, one red and one blue pixel
   img=reform(img,2,xpix/2,2,ypix/2,/overwrite)

   red=reform(img[0,*,0,*])

   g1 =reform(img[1,*,0,*])
   g2 =reform(img[0,*,1,*])
   green=NINT((g1+g2)/2.)

   blue=reform(img[1,*,1,*])

   image[0,*,*]=red
   image[1,*,*]=green
   image[2,*,*]=blue
      ; 
   img=image[*,revXindex,revYindex]   
endif

if debug then stop

bitcount_out = bitcount

;free_lun,lun
return, img
stat = 0

the_end:&

if keyword_set(verbose) then print, 'jumped to the_end'
stat = 0

return,[-1]
end