FUNCTION ADD_GSET, DEF, ERRMSG=ERRMSG
;
    ON_ERROR, 2
;
;  Initialize RESULT to represent non-success.  If the routine is successful,
;  this value will be updated below.
;
    RESULT = 0
;
;  Check the input parameters
;
        IF N_PARAMS() NE 1 THEN BEGIN
           MESSAGE = 'Syntax:  Result = ADD_GSET(DEF)'
       GOTO, HANDLE_ERROR
        ENDIF
;
;  Make sure that the user has privilege to write into the database.
;
    IF !PRIV LT 2 THEN BEGIN
           MESSAGE = '!PRIV must be 2 or greater to write into the database'
           GOTO, HANDLE_ERROR
    ENDIF
;
;  Make sure that the GIS setup ID number is less than or equal to zero.
;
    IF DEF.GSET_ID GT 0 THEN BEGIN
           MESSAGE= 'The GSET ID number must be LE 0. '+$
                 'The final value is assigned by this routine'
           GOTO, HANDLE_ERROR
    ENDIF
;
;  Check each of the structure components to verify that it is of the correct
;  type and size.
;
    IF DATATYPE(DEF.HVOLT,1) NE 'Integer' THEN BEGIN
           MESSAGE = 'Tag HVOLT must be a short integer array'
           GOTO, HANDLE_ERROR
    END ELSE IF N_ELEMENTS(DEF.HVOLT) NE 4 THEN BEGIN
           MESSAGE = 'Tag HVOLT must have four elements'
           GOTO, HANDLE_ERROR
    ENDIF
;
    IF DATATYPE(DEF.LLD,1) NE 'Integer' THEN BEGIN
           MESSAGE = 'Tag LLD must be a short integer array'
           GOTO, HANDLE_ERROR
    END ELSE IF N_ELEMENTS(DEF.LLD) NE 4 THEN BEGIN
           MESSAGE = 'Tag LLD must have four elements'
           GOTO, HANDLE_ERROR
    ENDIF
;
    IF DATATYPE(DEF.LUT_CHKSUM,1) NE 'String' THEN BEGIN
           MESSAGE = 'Tag LUT_CHKSUM must be a character string'
           GOTO, HANDLE_ERROR
    END ELSE IF N_ELEMENTS(DEF.LUT_CHKSUM) NE 4 THEN BEGIN
           MESSAGE = 'Tag LUT_CHKSUM must have four elements'
           GOTO, HANDLE_ERROR
    END ELSE IF NOT SAME_DATA(STRLEN(DEF.LUT_CHKSUM), LONG([4,4,4,4])) $
        THEN BEGIN
       MESSAGE = 'Tag LUT_CHKSUM must have four characters per element.'
       GOTO, HANDLE_ERROR
    ENDIF
;
    IF DATATYPE(DEF.LUT_PAR,1) NE 'Byte' THEN BEGIN
           MESSAGE = 'Tag LUT_PAR must be a byte array'
           GOTO, HANDLE_ERROR
    ENDIF
    SZ = SIZE(DEF.LUT_PAR)
    IF (SZ(0) NE 2) OR (SZ(1) NE 4) OR (SZ(2) NE 11) THEN BEGIN
           MESSAGE = 'Tag LUT_PAR must be a 4x11 array'
           GOTO, HANDLE_ERROR
    ENDIF
;
    IF DATATYPE(DEF.RAW_ID,1) NE 'Integer' THEN BEGIN
           MESSAGE = 'Tag RAW_ID must be a short integer'
           GOTO, HANDLE_ERROR
    END ELSE IF N_ELEMENTS(DEF.RAW_ID) NE 4 THEN BEGIN
           MESSAGE = 'Tag RAW_ID must have four elements'
           GOTO, HANDLE_ERROR
    ENDIF
;
    IF DATATYPE(DEF.SLIT_NUM,1) NE 'Integer' THEN BEGIN
           MESSAGE = 'Tag SLIT_NUM must be a short integer'
           GOTO, HANDLE_ERROR
    END ELSE IF N_ELEMENTS(DEF.SLIT_NUM) NE 1 THEN BEGIN
           MESSAGE = 'Tag SLIT_NUM must be a scalar'
           GOTO, HANDLE_ERROR
    ENDIF
;
    IF DATATYPE(DEF.ZONE_ID,1) NE 'Integer' THEN BEGIN
           MESSAGE = 'Tag ZONE_ID must be a short integer'
           GOTO, HANDLE_ERROR
    END ELSE IF N_ELEMENTS(DEF.ZONE_ID) NE 1 THEN BEGIN
           MESSAGE = 'Tag ZONE_ID must be a scalar'
           GOTO, HANDLE_ERROR
    ENDIF
;
    IF DATATYPE(DEF.FIL_ID,1) NE 'Integer' THEN BEGIN
           MESSAGE = 'Tag FIL_ID must be a short integer'
           GOTO, HANDLE_ERROR
    END ELSE IF N_ELEMENTS(DEF.FIL_ID) NE 1 THEN BEGIN
           MESSAGE = 'Tag FIL_ID must be a scalar'
           GOTO, HANDLE_ERROR
    ENDIF
;
    IF DATATYPE(DEF.FFB,1) NE 'Integer' THEN BEGIN
           MESSAGE = 'Tag FFB must be a short integer'
           GOTO, HANDLE_ERROR
    END ELSE IF N_ELEMENTS(DEF.FFB) NE 1 THEN BEGIN
           MESSAGE = 'Tag FFB must be a scalar'
           GOTO, HANDLE_ERROR
    END ELSE IF (DEF.FFB NE -1) AND (DEF.FFB NE +1) THEN BEGIN
       MESSAGE = 'Tag FFB must be either -1 or +1'
       GOTO, HANDLE_ERROR
    ENDIF
;
    IF DATATYPE(DEF.DET_USED,1) NE 'Integer' THEN BEGIN
           MESSAGE = 'Tag DET_USED must be a short integer'
           GOTO, HANDLE_ERROR
    END ELSE IF N_ELEMENTS(DEF.DET_USED) NE 4 THEN BEGIN
           MESSAGE = 'Tag DET_USED must have four elements'
           GOTO, HANDLE_ERROR
    END ELSE IF (MIN(DEF.DET_USED) LT 0) OR (MAX(DEF.DET_USED) GT 1) $
        THEN BEGIN
       MESSAGE = 'Tag DET_USED must be 0 or 1'
       GOTO, HANDLE_ERROR
    ENDIF
;
    IF DATATYPE(DEF.GSET_DESC,1) NE 'String' THEN BEGIN
           MESSAGE = 'Tag GSET_DESC must be a character string'
           GOTO, HANDLE_ERROR
    END ELSE IF N_ELEMENTS(DEF.GSET_DESC) NE 4 THEN BEGIN
           MESSAGE = 'Tag GSET_DESC must have four elements'
           GOTO, HANDLE_ERROR
    END ELSE IF MAX(STRLEN(DEF.GSET_DESC)) GT 80 THEN BEGIN
       MESSAGE = 'Tag GSET_DESC must be 80 characters or less'
       GOTO, HANDLE_ERROR
    ENDIF
;
;  Concatenate the multiline checksum and description into single strings.
;
    LUT_CHKSUM = STRING(REPLICATE(32B,16))
    FOR I = 0,3 DO STRPUT, LUT_CHKSUM, DEF.LUT_CHKSUM(I), 4*I
    GSET_DESC = STRING(REPLICATE(32B,320))
    FOR I = 0,3 DO STRPUT, GSET_DESC, DEF.GSET_DESC(I), 80*I
;
;  Open the GSET database for write access.
;
    DBOPEN, 'gset', 1
;
;  Find the largest GSET ID number currently in the database, and add one to
;  it.
;
    N_ENTRIES = DB_INFO('entries','gset')
    IF N_ENTRIES EQ 0 THEN GSET_ID = 1 ELSE BEGIN
        DBEXT, -1, 'gset_id', GSET_IDS
        GSET_ID = MAX(GSET_IDS) + 1
    ENDELSE
;
;  Append the data to the opened database.
;
    DBBUILD, GSET_ID, DEF.HVOLT, DEF.LLD, LUT_CHKSUM, DEF.LUT_PAR, $
        DEF.RAW_ID, DEF.SLIT_NUM, DEF.ZONE_ID, DEF.FIL_ID,  $
        DEF.FFB, DEF.DET_USED, GSET_DESC, STATUS=STATUS
    IF STATUS EQ 0 THEN BEGIN
           MESSAGE = 'Write to gset database was not successful'
           GOTO, HANDLE_ERROR
        ENDIF
;
;  Update the GSET ID number in the structure.  Signal success.
;
    DEF.GSET_ID = GSET_ID
    RESULT = 1
    GOTO, FINISH
;
;  Error handling point.
;
HANDLE_ERROR:
    IF N_ELEMENTS(ERRMSG) NE 0 THEN ERRMSG = 'ADD_GSET: ' + MESSAGE $
        ELSE MESSAGE, MESSAGE, /CONTINUE
;
;  Close the database, and return whether the routine was successful or not.
;
FINISH:
    DBCLOSE
;
    RETURN, RESULT
    END