	FUNCTION ADD_OTHER_OBS, DEF, ERRMSG=ERRMSG
;+
; Project     :	SOHO - CDS
;
; Name        :	ADD_OTHER_OBS()
;
; Purpose     :	Adds a plan entry for another observatory to database
;
; Explanation :	This procedure takes an "Other_Obs" science plan entry from the
;		KAP and adds it to the database "other_obs".  This database
;		contains a series of such entries, making a historical list.
;
; Use         :	Result = ADD_OTHER_OBS( DEF )
;
;		IF NOT ADD_OTHER_OBS( DEF ) THEN ...
;
; Inputs      :	DEF = This is an anonymous structure containing the following
;		      tags:
;
;			TELESCOP     = The name of the telescope.
;			MNEMONIC     = The mnemonic for the telescope.
;			SCI_OBJ      = Science objective
;			SCI_SPEC     = Specific science objective
;			NOTES	     = Further notes about the observation
;			START_TIME   = Date/time of beginning of observation,
;				       in TAI format
;			END_TIME     = Date/time of end of observation, in TAI
;				       format
;			OBJECT	     = Code for object planned to be observed
;			OBJ_ID	     = Object identification
;			CMP_NO	     = Campaign number
;
;		      It can also be an array of such structures.
;
; Opt. Inputs :	None.
;
; Outputs     :	The result of the function is a logical value representing
;		whether or not the operation was successful, where 1 is
;		successful and 0 is unsuccessful.
;
; Opt. Outputs:	None.
;
; Keywords    :
;       ERRMSG    = If defined and passed, then any error messages will be
;                   returned to the user in this parameter rather than
;                   depending on the MESSAGE routine in IDL.  If no errors are
;                   encountered, then a null string is returned.  In order to
;                   use this feature, ERRMSG must be defined first, e.g.
;
;                       ERRMSG = ''
;                       Result = ADD_OTHER_OBS( ERRMSG=ERRMSG, ... )
;                       IF ERRMSG NE '' THEN ...
;
;
; Calls       :	DATATYPE, DBOPEN, DBBUILD, DBCLOSE, TRIM, GET_OBJECT,
;		GET_CAMPAIGN
;
; Common      :	None.
;
; Restrictions:	Only this routine or DEL_PLAN can be used to add or delete
;		science plan descriptions to or from the database.
;		Modifying the database by hand could corrupt its integrity.
;
;		The data types and sizes of the structure elements must match
;		the definitions in the database.
;
;		!PRIV must be 2 or greater to use this routine.
;
; Side effects:	None.
;
; Category    :	Planning, Databases.
;
; Prev. Hist. :	None.
;
; Written     :	William Thompson, GSFC, 12 April 1995
;
; Modified    :	Version 1, William Thompson, GSFC, 12 April 1995
;
; Version     :	Version 1, 12 April 1995
;-
;
	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_OTHER_OBS(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
;
;  Check each of the structure components to verify that it is of the correct
;  type and size.
;
	FOR I = 0,N_ELEMENTS(DEF)-1 DO BEGIN
	    IF DATATYPE(DEF(I).MNEMONIC,1) NE 'String' THEN BEGIN
	       MESSAGE = 'Tag MNEMONIC must be a character string'
	       GOTO, HANDLE_ERROR
	    END ELSE IF N_ELEMENTS(DEF(I).MNEMONIC) NE 1 THEN BEGIN
	       MESSAGE = 'Tag MNEMONIC must be a scalar'
	       GOTO, HANDLE_ERROR
	    END ELSE IF STRLEN(DEF(I).MNEMONIC) GT 10 THEN BEGIN $
	       MESSAGE = 'Tag MNEMONIC must be 10 characters or less'
	       GOTO, HANDLE_ERROR
	    ENDIF
;
	    IF DATATYPE(DEF(I).TELESCOP,1) NE 'String' THEN BEGIN
	       MESSAGE = 'Tag TELESCOP must be a character string'
	       GOTO, HANDLE_ERROR
	    END ELSE IF N_ELEMENTS(DEF(I).TELESCOP) NE 1 THEN BEGIN
	       MESSAGE = 'Tag TELESCOP must be a scalar'
	       GOTO, HANDLE_ERROR
	    END ELSE IF STRLEN(DEF(I).TELESCOP) GT 50 THEN BEGIN $
	       MESSAGE = 'Tag TELESCOP must be 50 characters or less'
	       GOTO, HANDLE_ERROR
	    ENDIF
;
	    IF DATATYPE(DEF(I).SCI_OBJ,1) NE 'String' THEN BEGIN
	       MESSAGE = 'Tag SCI_OBJ must be a character string'
	       GOTO, HANDLE_ERROR
	    END ELSE IF N_ELEMENTS(DEF(I).SCI_OBJ) NE 1 THEN BEGIN
	       MESSAGE = 'Tag SCI_OBJ must be a scalar'
	       GOTO, HANDLE_ERROR
	    END ELSE IF STRLEN(DEF(I).SCI_OBJ) GT 50 THEN BEGIN $
	       MESSAGE = 'Tag SCI_OBJ must be 50 characters or less'
	       GOTO, HANDLE_ERROR
	    ENDIF
;
	    IF DATATYPE(DEF(I).SCI_SPEC,1) NE 'String' THEN BEGIN
	       MESSAGE = 'Tag SCI_SPEC must be a character string'
	       GOTO, HANDLE_ERROR
	    END ELSE IF N_ELEMENTS(DEF(I).SCI_SPEC) NE 1 THEN BEGIN
	       MESSAGE = 'Tag SCI_SPEC must be a scalar'
	       GOTO, HANDLE_ERROR
	    END ELSE IF STRLEN(DEF(I).SCI_SPEC) GT 50 THEN BEGIN
	       MESSAGE = 'Tag SCI_SPEC must be 50 characters or less'
	       GOTO, HANDLE_ERROR
	    ENDIF
;
	    IF DATATYPE(DEF(I).NOTES,1) NE 'String' THEN BEGIN
	       MESSAGE = 'Tag NOTES must be a character string'
	       GOTO, HANDLE_ERROR
	    END ELSE IF N_ELEMENTS(DEF(I).NOTES) NE 1 THEN BEGIN
	       MESSAGE = 'Tag NOTES must be a scalar'
	       GOTO, HANDLE_ERROR
	    END ELSE IF STRLEN(DEF(I).NOTES) GT 50 THEN BEGIN
	       MESSAGE = 'Tag NOTES must be 50 characters or less'
	       GOTO, HANDLE_ERROR
	    ENDIF
;
	    IF DATATYPE(DEF(I).START_TIME,1) NE 'Double' THEN BEGIN
	       MESSAGE = 'Tag START_TIME must be a double precision number'
	       GOTO, HANDLE_ERROR
	    END ELSE IF N_ELEMENTS(DEF(I).START_TIME) NE 1 THEN BEGIN
	       MESSAGE = 'Tag START_TIME must be a scalar'
	       GOTO, HANDLE_ERROR
	    ENDIF
;
	    IF DATATYPE(DEF(I).END_TIME,1) NE 'Double' THEN BEGIN
	       MESSAGE = 'Tag END_TIME must be a double precision number'
	       GOTO, HANDLE_ERROR
	    END ELSE IF N_ELEMENTS(DEF(I).END_TIME) NE 1 THEN BEGIN
	       MESSAGE = 'Tag END_TIME must be a scalar'
	       GOTO, HANDLE_ERROR
	    ENDIF
;
	    IF DATATYPE(DEF(I).OBJECT,1) NE 'String' THEN BEGIN
	       MESSAGE = 'Tag OBJECT must be a character string'
	       GOTO, HANDLE_ERROR
	    END ELSE IF N_ELEMENTS(DEF(I).OBJECT) NE 1 THEN BEGIN
	       MESSAGE = 'Tag OBJECT must be a scalar'
	       GOTO, HANDLE_ERROR
	    END ELSE IF STRLEN(DEF(I).OBJECT) GT 3 THEN BEGIN
	       MESSAGE = 'Tag OBJECT must be 3 characters or less'
	       GOTO, HANDLE_ERROR
	    ENDIF
;
	    IF DATATYPE(DEF(I).OBJ_ID,1) NE 'String' THEN BEGIN
	       MESSAGE = 'Tag OBJ_ID must be a character string'
	       GOTO, HANDLE_ERROR
	    END ELSE IF N_ELEMENTS(DEF(I).OBJ_ID) NE 1 THEN BEGIN
	       MESSAGE = 'Tag OBJ_ID must be a scalar'
	       GOTO, HANDLE_ERROR
	    END ELSE IF STRLEN(DEF(I).OBJ_ID) GT 6 THEN BEGIN
	       MESSAGE = 'Tag OBJ_ID must be 6 characters or less'
	       GOTO, HANDLE_ERROR
	    ENDIF
;
	    IF DATATYPE(DEF(I).CMP_NO,1) NE 'Integer' THEN BEGIN
	       MESSAGE = 'Tag CMP_NO must be a short integer'
	       GOTO, HANDLE_ERROR
	    END ELSE IF N_ELEMENTS(DEF(I).CMP_NO) NE 1 THEN BEGIN
	       MESSAGE = 'Tag CMP_NO must be a scalar'
	       GOTO, HANDLE_ERROR
	    ENDIF
;
;  Make sure that the campaign number matches an entry in the SoHO campaign
;  database.
;
	    IF DEF(I).CMP_NO NE 0 THEN BEGIN
		GET_CAMPAIGN, DEF(I).CMP_NO, TEMP
		IF TEMP.CMP_NO LE 0 THEN BEGIN
		   MESSAGE = 'Campaign number ' + STRTRIM(DEF(I).CMP_NO,2) + $
		      ' not found in database'
		   GOTO, HANDLE_ERROR
		ENDIF
	    ENDIF
;
;  Make sure that the object code matches an entry in the database.
;
	    GET_OBJECT, DEF(I).OBJECT, TEMP
	    IF TEMP.OBJECT EQ '' THEN BEGIN
	       MESSAGE = 'Object code ' + DEF(I).OBJECT + $
	          ' not found in database'
	       GOTO, HANDLE_ERROR
	    ENDIF
	    IF I EQ 0 THEN OBJ = REPLICATE(TEMP,N_ELEMENTS(DEF)) ELSE	$
		OBJ(I) = TEMP
;
;  Make sure that the stop date is greater than the start date.
;
	    IF DEF(I).END_TIME LE DEF(I).START_TIME THEN BEGIN
	       MESSAGE = 'The stop date must be after the start date'
	       GOTO, HANDLE_ERROR
	    ENDIF
	ENDFOR
;
;  Reformat the times to millisecond accuracy.  This is necessary so that
;  the times are written out in a controlled way.
;
	START_TIME = DOUBLE( STRING( DEF.START_TIME, FORMAT='(F15.3)' ))
	END_TIME   = DOUBLE( STRING( DEF.END_TIME,   FORMAT='(F15.3)' ))
;
;  Open the science plan database for write access, and add the entry.
;
	DBOPEN, 'other_obs', 1
	DBBUILD, DEF.MNEMONIC, DEF.TELESCOP, DEF.SCI_OBJ, DEF.SCI_SPEC, $
		DEF.NOTES, START_TIME, END_TIME, OBJ.OBJECT, DEF.OBJ_ID, $
		DEF.CMP_NO, STATUS=STATUS
	IF STATUS EQ 0 THEN BEGIN
	   MESSAGE = 'Write to other_obs database was not successful'
	   GOTO, HANDLE_ERROR
	ENDIF
;
;  Signal success.
;
	RESULT = 1
	GOTO, FINISH
;
;  Error handling point.
;
HANDLE_ERROR:
	IF N_ELEMENTS(ERRMSG) NE 0 THEN ERRMSG = 'ADD_OTHER_OBS: ' + MESSAGE $
		ELSE MESSAGE, MESSAGE, /CONTINUE
;
;  Close the database, and return whether the routine was successful or not.
;
FINISH:
	DBCLOSE
;
	RETURN, RESULT
	END
