;+
; NAME:
;	SMEI_SEQUENCE::MAKE_AVMV
;
;
; PURPOSE:
;	Generates a movie from a SMEI sequence
;
;
; CATEGORY:
;	SMEI_SEQUENCE
;
;
; CALLING SEQUENCE:
;	seqref -> make_avmv, file
;
;
; INPUTS:
;	file	string	The name of the file to which to write the movie
;
;
; KEYWORD PARAMETERS:
;	frame_rate	(float)	The frame rate desired (fps)
;	/avi			If set, then make a DIVX5 AVI movie.
;	/quicktime		If set, then make a Quicktime movie
;	/xvid			If set, then make an AVI movie using
;				the xvid module
;	/ffmpeg			If set, then make an FFmpeg AVI movie.
;	codec		string	For quicktime and ffmpeg, specify the
;				codec to use for the movie.
;	/no_progress	If set, then disable the progress bars (useful
;			if slow network means the progress bars are
;			slowing operation).
;	/no_delete		If set, then don't delete the PNG files.
;
; RESTRICTIONS:
;	Requires that transcode be installed on the system.
;
;
; MODIFICATION HISTORY:
;	Original (from MAKE_MPEG): 17/2/04; SJT
;	Updated transcode options: 3/12/04; SJT
;	Add ffpmeg & codec selections: 7/6/05; SJT
;	Fix file-decriptor leak: 8/6/05; SJT
;	Add no_progress keyword: 25/8/05; SJT
;	Added xvid option: 28/2/11; SJT
;	Add no_delete keyword: 13/12/12; SJT
;	Fix colour mappings for true-colour displays: 19/12/12; SJT
;-

pro smei_sequence::make_avmv, mpegfilename, frame_rate = frame_rate, $
                              avi = avi, quicktime = quicktime, ffmpeg $
                              = ffmpeg, $ 
                              xvid = xvid, codec = codec, no_progress $
                              = no_progress, no_delete = no_delete


; Verify existence of transcode
  if not have_command("transcode") then begin
     smei_msg, /alert, ['transcode was not found', $
                        'please install it if you', $
                        'wish to make avi or quicktime movies']
     return
  endif


  sz = (self -> get_first()) -> get_size()
  nframes = self -> get_count()

  ndigits = 1+fix(alog10(nframes))
  formatstring = strcompress('(i'+string(ndigits)+'.'+string(ndigits)$
                             +             ')', /remove_all)

; Load current color table into byte arrays

  red = self -> get_colour_map(/red)
  green = self -> get_colour_map(/green)
  blue = self -> get_colour_map(/blue)

  on_ioerror, badwrite

  write = file_test('./', /write)
  if (write ne 1) then dir = '/tmp/' else dir = './'

  tmpdir = dir+'idl2mpeg.frames'+string(systime(1), format = "('_',I0)")
  file_mkdir, tmpdir
  listfile = tmpdir+'/PNG.lis'
  openw, ilu, /get, listfile

; write each frame into tmpdir as an 8-bit .png image file

  namelist = strarr(nframes)

  im = self -> get_first()
  framenum = 0
  owindow = self -> get_window()
  window, /free, /pixmap, xsize = sz[0], ysize = sz[1]
  pwindow = !d.window

  if not widget_info(/active) or keyword_set(no_progress) then isprog = $
     0b $
  else isprog = 1b

  if isprog then $
     pid = cw_progress(/column, $
                       title = 'Saving frames', $
                       xsize = 200, $
                       ysize = 20, $
                       value = 0., $
                       max = nframes) $
  else pid = 0l

  ispid = widget_info(/valid, pid)

  while obj_valid(im) do begin
     if not im -> get_pflags(/skip) then begin
        namelist[framenum] = 'frame.' + string(framenum, format = $
                                               formatstring) + '.png'
        filename = tmpdir + '/'+namelist[framenum]
        printf, ilu, filename
        im -> show, window = pwindow
        wset, pwindow
        if !d.n_colors le 256 then begin
           img = tvrd()
           write_png, filename, img, red, green, blue
        endif else begin
           img =  tvrd(true = 1)
           write_png, filename, img
        endelse
        framenum = framenum+1
        if ispid then widget_control, pid, set_value = framenum
     endif else nframes = nframes-1
     im = im -> get_next()
  endwhile
  wdelete, pwindow
  free_lun, ilu
  namelist = namelist[0:nframes-1]

  if ispid then widget_control, pid, /destroy

  device, window_state = wstat
  if owindow ne -1 && wstat[owindow] then wset, owindow

  if isprog then $
     pid = cw_progress(/column, $
                       title = 'Encoding movie', $
                       xsize = 200, $
                       ysize = 20, $
                       value = 0., $
                       max = nframes) $
  else pid = 0l
;pid = 0l

  ispid = widget_info(/valid, pid)

; Note: For newer versions of transcode, --use_rgb should be replaced
; by -V rgb24 (I think the switch is at 1.1 but I'm not sure).
; certainly 1.0.7 uses --use_rgb and 1.1.5 uses -V rgb24, the next few
; lines try to determine which is needed. Also newer versions
; don't look to need the z inversion, so again I'll stick with 1.1 as
; the changeover until I get a better parameter.

  spawn, 'transcode --version', junk, tcv
  tca = strsplit(tcv, /extr)
  tcvv = fix(strsplit(strmid(tca[1], 1), '.', /extr))
  if tcvv[0] eq 0 or (tcvv[0] eq 1 and  tcvv[1] eq 0) then begin
     rgbopt = '--use_rgb' 
     zopt = '-z'
  endif else begin
     rgbopt = '-V rgb24'
     zopt = ''
  endelse

  if keyword_set(quicktime) then begin
     if ~keyword_set(codec)  then codec = 'mjpa'
     y = 'mov,null -F '+codec+' -k '+zopt
     fext = '.mov'
  endif else if keyword_set(xvid) then begin
     y = 'xvid,null'
     fext = '.avi'
  endif else if keyword_set(ffmpeg) then begin
     if ~keyword_set(codec) then codec = 'mpeg4'
     y = 'ffmpeg,null -F '+codec+' -k '+zopt
     fext = '.avi'
  endif else begin
     y = 'divx5,null'
     fext = '.avi'
  endelse
  if not keyword_set(frame_rate) then frame_rate = 10


  cmd = string(listfile, rgbopt, sz, y, frame_rate, mpegfilename, fext, $
               format = "('transcode -i ',A,' -x imlist,null ',a,' -g " + $
               "',I0,'x',I0,' -y ',a,' -f ',I0,' -o ',a,a,' -H 0')")

  print, cmd

; spawn a shell to process the transcode command
  if ispid then begin
     spawn, cmd, unit = ilu
     inln = ''
     while not eof(ilu) do begin
        readf, ilu, inln
        if strpos(inln, 'encoding frames') eq 0 then begin
           nos = stregex(inln, '-[0-9]+', /extract)
           widget_control, pid, set_value = $
                           1-nos[0]
        endif
     endwhile
     free_lun, ilu
  endif else spawn, cmd

; clean temp dir
  if (~keyword_set(no_delete)) then begin
     file_delete, tmpdir + '/'+namelist, listfile
     file_delete, tmpdir
  endif

  if ispid then widget_control, pid, /destroy

  return

badwrite:
  smei_msg, /alert, 'Unable to write Movie file!'

end
