; docformat = 'rst'

;+
; $Id: nrl_savegen.pro 3888 2014-06-17 14:09:04Z mariska $
;-

;+
; Save an arbitrary number of IDL variables to an HDF 5 file
; using the same calling syntax as savegen.pro. Warning, when IDL
; string arrays are stored, all the strings are shortened to the
; length of the first array element. Variable length arrays in
; HDF5 are challenging!
;
; :Params:
;
; :Keywords:
;   file:
;     Output file name (defaults to save.h5).
;   names:
;     String or string array containing names of positional
;     parameters.
;   struct:
;     An IDL structure to be saved. No positional parameters
;     allowed if this keyword is used.
;   text:
;     A text string or string array describing the file contents.
;
; :Author:
;   John Mariska GMU, 
;   jmariska@gmu.edu, jtmariska@gmail.com
;
; :History:
;   (2014-Jun-09) JTM: first working test version.
;-
pro nrl_savegen, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, $
                 p12, p13, p14, p15, $
                 file=file, names=names, text=text, struct=struct

    compile_opt strictarr

    ; Set up the hdf5 file
    if n_elements(file) eq 0 then file = 'save'
    fileout = file_dirname(file) + path_sep() + $
              file_basename(file, '.h5', /fold_case) + '.h5'
    if file_test(fileout) then file_delete, fileout

    ; Need some names
    nargs = n_params()
    if n_elements(names) eq 1 then names = strsplit(names, ' ,', /extract)
    if n_elements(names) eq 0 and n_elements(struct) eq 0 then begin
        names = 'p' + strtrim(sindgen(nargs), 2)
    endif
    
    ; Build output structure
    if n_elements(struct) ne 0 then begin ; User provided a structure
        if nargs ne 0 then begin
            message, /info, $
                "Can't specifiy both struct keyword and positional params."
        endif else begin
            structure = struct
        endelse
    endif else begin ; Work through positional params instead
        struct_string = '{'
        for i = 0, nargs-1 do begin
            struct_string = struct_string + names[i] + ': ' + $
                            'p' + strtrim(i, 2) + ', '
        endfor
        struct_string = strmid(struct_string, 0, $
                               strpos(struct_string, ',', /reverse_search))
        struct_string = 'structure = ' + struct_string + '}'
        ; print, struct_string
        status = execute(struct_string)
        ; print, status
    endelse

    ; Produce the file
    file_id = h5f_create(fileout)
    dtype_id = h5t_idl_create(structure)
    dspace_id = h5s_create_simple(1)
    dset_id = h5d_create(file_id, 'nrl_savegen', dtype_id, dspace_id)
    h5d_write, dset_id, structure

    ; Take care of text if any
    ; First make it a single string. Arrays don't play nice with hdf5.
    if n_elements(text) eq 0 then begin
        text = 'No user supplied text.'
    endif else begin
        if n_elements(text) gt 1 then text = strjoin(text, 10b, /single)
    endelse
    str_dtype_id = h5t_idl_create(text)
    str_dspace_id = h5s_create_simple(1)
    str_dset_id = h5d_create(file_id, 'nrl_text', str_dtype_id, $
                             str_dspace_id)
    h5d_write, str_dset_id, text

    ; Close things out
    h5f_close, file_id

end
