	FUNCTION WRITE_CAP, OP_DAY, OBSERVER=OBSERVER, COMMENT=COMMENT, $
		ERRMSG=ERRMSG, FILE=FILE
;+
; Project     :	SOHO - CDS
;
; Name        :	WRITE_CAP
;
; Purpose     :	Write out the CAP from the science plan.
;
; Category    :	Planning
;
; Explanation :	Writes out the Combined instrument Activity Plan (CAP) file
;		using the keyword format from the Interface Control Document,
;		based on the information in the science plan database.  The CAP
;		file differs from the IAP file in that all the instruments but
;		only SCI_PROG entries are included.
;
; Syntax      :	Result = WRITE_CAP( OP_DAY )
;
; Examples    :	IF WRITE_CAP('1995/03/30') THEN ...
;
; Inputs      :	OP_DAY	= Operational day in any CDS UTC format.  Only the UTC
;			  date will be used--any time-of-day information will
;			  be ignored.
;
; Opt. Inputs :	None.
;
; Outputs     :	The CAP is written to a file in the directory given by the
;		environment variable SOHO_CAP.  The filename has the format
;		"ECSyyyymmddvvv.CAP", where the number is chosen to make the
;		filename unique.
;
;		The result of the function is 1 for successful and 0 for
;		unsuccessful. 
;
; Opt. Outputs:	None.
;
; Keywords    :	OBSERVER = Name to place in the OBSERVER field in the output
;			   file.  If not passed, then "ECS Staff" is used.
;		COMMENT	 = Optional string array containing comments to put in
;			   the file header.
;		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.  In
;			   order to use this feature, ERRMSG must be defined
;			   first, e.g.
;
;				ERRMSG = ''
;				Result = WRITE_CAP(OP_DAY, ERRMSG=ERRMSG)
;				IF ERRMSG NE '' THEN ...
;
;		FILE     = Name of output CAP file.
;
; Calls       :	LIST_PLAN, TRIM, BREAK_FILE, CONCAT_PNT
;
; Common      :	None.
;
; Restrictions:	Env. var. ZDBASE must point to directory containing the dbase.
;
; Side effects:	Even if this routine is successful, it will return a non-null
;		value for ERRMSG.
;
; Prev. Hist. :	None
;
; History     :	Version 1, 1-Aug-1995, William Thompson, GSFC
;		Version 2, 25-Aug-1995, William Thompson, GSFC
;			Brought into conformance with what ECS tool expects
;		Version 3, William Thompson, GSFC, 18 October 1995
;			Added XCEN, YCEN to SCIPLAN entries.
;               Version 4, Dominic Zarro, GSFC, 24 April 1996
;                       Converted SCIPLAN slots for CELIAS, SWAN, and ERNE
;                       for use by JOP, SOC, and CMP
;
; Contact     :	WTHOMPSON
;-
;
;  Initialize the message to be returned.  Also initialize the RESULT to 0.  If
;  the routine is successful, this parameter will be updated below.
;
	MESSAGE = ''
	RESULT = 0
;
;  Check the input parameters.
;
	IF N_PARAMS() NE 1 THEN BEGIN
		MESSAGE = 'Syntax:  Result = WRITE_CAP( OP_DAY )'
		GOTO, HANDLE_ERROR
	ENDIF
;
;  Parse the operational day into CDS internal format.  Calculate the start
;  time and end time.
;
	START_TIME = ANYTIM2UTC(OP_DAY, ERRMSG=ERRMSG)
	IF N_ELEMENTS(ERRMSG) NE 0 THEN		$
		IF ERRMSG(0) NE '' THEN GOTO, HANDLE_ERROR
	START_TIME.TIME = 0
	END_TIME = START_TIME
	END_TIME.MJD = END_TIME.MJD + 1
;
;  Form the first part of the filename.
;
	DATE = ANYTIM2UTC(START_TIME, /EXTERNAL)
	NAME = 'ECS' + TRIM(DATE.YEAR) +		$
		STRMID(TRIM(100+DATE.MONTH),1,2) +	$
		STRMID(TRIM(100+DATE.DAY),1,2)
;
;  Find all the CAP files with names starting with those characters.  Get the
;  highest version number and add one to it.
;
	FOUND = LOC_FILE(CONCAT_DIR('$SOHO_CAP', NAME + '*.CAP'), COUNT=COUNT)
	IF COUNT EQ 0 THEN VERSION = 1 ELSE BEGIN
		FOUND = FOUND(SORT([FOUND]))
		BREAK_FILE, FOUND(COUNT-1), DISK, DIR, FILENAME, EXT
		VERSION = FIX(STRMID(FILENAME,11,3)) + 1
	ENDELSE
	NAME = NAME + STRMID(TRIM(1000+VERSION),1,3) + '.CAP'
;
;  Open the output file, and write the header.  Use ".CAP" as the default
;  extension.
;
	FILE = CONCAT_DIR('$SOHO_CAP', NAME)
	ON_IOERROR, ERROR_POINT
	OPENW, UNIT, FILE, /GET_LUN
	PRINTF, UNIT, 'DATATYPE = COMBINED ACTIVITY PLAN'
	PRINTF, UNIT, 'FILENAME = ' + NAME
	PRINTF, UNIT, 'INSTRUME = ECS'
	SPAWN, 'hostname', HOSTNAME
	PRINTF, UNIT, 'ORIG_ID  = ' + GETENV('LOGNAME') + '@' + HOSTNAME
;
;  If OBSERVER was not passed, then use "ECS Staff"
;
	IF N_ELEMENTS(OBSERVER) EQ 0 THEN OBSERVER = 'ECS Staff'
	PRINTF, UNIT, 'OBSERVER = ' + OBSERVER
	GET_UTC, UTC, /ECS, /TRUNCATE
	PRINTF, UNIT, 'DATE_CRE = ' + UTC
	PRINTF, UNIT, 'STARTIME = ' + ANYTIM2UTC(START_TIME, /ECS, /TRUNCATE)
	PRINTF, UNIT, 'ENDTIME  = ' + ANYTIM2UTC(END_TIME,   /ECS, /TRUNCATE)
;
;  If COMMENT was passed, then write out the comments.
;
	FOR I = 0, N_ELEMENTS(COMMENT)-1 DO	$
		PRINTF, UNIT, 'COMMENT  = ' + COMMENT(I)
	PRINTF, UNIT, 'END'
;
;  Convert the input times to TAI.
;
	IF DATATYPE(START_TIME,1) EQ 'Double' THEN TAI_START = START_TIME $
		ELSE TAI_START = UTC2TAI(START_TIME)
	IF DATATYPE(END_TIME,1) EQ 'Double' THEN TAI_END = END_TIME ELSE $
		TAI_END = UTC2TAI(END_TIME)
;
;  Retrieve the information from the sci_plan database.
;
	LIST_PLAN, START_TIME, END_TIME, PLAN, N
;
;  For each entry, write out the data to the file.
;
	FOR I = 0, N-1 DO BEGIN
;
;  Ignore it if it starts before the operational day, or just at the end of the
;  operational day.
;

	    IF (TAI_START LE PLAN(I).START_TIME) AND	$
			(TAI_END GT PLAN(I).START_TIME) THEN BEGIN
;
;  Form the header from the scientific objective.  Use no more than 10
;  characters.  Replace any nonalphanumeric characters with underscores.
;

                GET_INSTRUMENT, PLAN(I).INSTRUME, INS

;-- patch to map CELIAS, SWAN, and ERNE SCI_plans back into
;                JOP, SOC, and CMP Activities

                
		B = BYTE( STRMID( STRTRIM( PLAN(I).SCI_OBJ, 2), 0, 10))
		W = WHERE((B LT 48B) OR			$
			((B GT 57B) AND (B LT 65B)) OR	$
			((B GT 90B) AND (B LT 97B)) OR	$
			(B GT 122B), COUNT)
		IF COUNT GT 0 THEN B(W) = 95B
		PRINTF, UNIT, ''

                ilook=where(plan(i).instrume eq get_soho_map(['jop','soc','cmp']),count)
                if count gt 0 then key='ACTIVITY_' else key='SCIPLAN_'
                 PRINTF, UNIT, key + STRING(B)
                if count gt 0 then $
        	 PRINTF, UNIT, '        INSTRUME = SOC'

;
;  Write out the start and end times.
;
		 PRINTF, UNIT, '        STARTIME = ' +	$
			TAI2UTC(PLAN(I).START_TIME, /ECS, /TRUNCATE)
		PRINTF, UNIT, '	ENDTIME  = ' +	$
			TAI2UTC(PLAN(I).END_TIME,   /ECS, /TRUNCATE)

               if count eq 0 then begin

		PRINTF, UNIT,  '        INSTRUME = ' + trim(ins.name)
;
;  Add the other keywords.
;
;
		PRINTF, UNIT, '	SCI_OBJ  = ' + TRIM(PLAN(I).SCI_OBJ)
;
		TEST = TRIM(PLAN(I).SCI_SPEC)
		IF TEST NE '' THEN PRINTF, UNIT, '	SCI_SPEC = ' + TEST
;
		PRINTF, UNIT, '	OBJECT   = ' + TRIM(PLAN(I).OBJECT)
;
		TEST = TRIM(PLAN(I).OBJ_ID)
		IF TEST NE '' THEN PRINTF, UNIT, '	OBJ_ID   = ' + TEST
;
		TEST = TRIM(PLAN(I).XCEN)
		IF TEST NE '' THEN PRINTF, UNIT, '	XCEN     = ' + TEST
;
		TEST = TRIM(PLAN(I).YCEN)
		IF TEST NE '' THEN PRINTF, UNIT, '	YCEN     = ' + TEST
;
		TEST = TRIM(PLAN(I).NOTES)
		IF TEST NE '' THEN PRINTF, UNIT, '	NOTES    = ' + TEST
;
		IF PLAN(I).PROG_ID GT 0 THEN		$
			PRINTF, UNIT, '	PROG_ID  = ' + TRIM(PLAN(I).PROG_ID)
;
		IF PLAN(I).CMP_NO GT 0 THEN		$
			PRINTF, UNIT, '	CMP_NO   = ' + TRIM(PLAN(I).CMP_NO)
;
		TEST = TRIM(PLAN(I).DISTURBANCES)
		IF TEST NE '' THEN PRINTF, UNIT, '	DISTURB  = ' + TEST
               endif
	    ENDIF
	ENDFOR
;
;  Print out a message stating that the file was written.
;
	FILE_STATUS = FSTAT(UNIT)
	MESSAGE = 'Wrote file ' + FILE_STATUS.NAME
	IF N_ELEMENTS(ERRMSG) EQ 0 THEN PRINT, MESSAGE
	RESULT = 1
	GOTO, EXIT_POINT
;
;  If you reach this point, you've hit an error.
;
ERROR_POINT:
	ON_IOERROR, NULL
	MESSAGE = 'Error writing file ' + FILE
;
;  This is the error handling point, where the message is either printed
;  immediately, or returned as a keyword.
;
HANDLE_ERROR:
	IF N_ELEMENTS(ERRMSG) EQ 0 THEN MESSAGE, MESSAGE, /CONTINUE
;
;  Whether you hit an error or not, you will reach this point.  Close the file
;  and return.
;
EXIT_POINT:
	IF N_ELEMENTS(UNIT) NE 0 THEN FREE_LUN, UNIT
	IF N_ELEMENTS(ERRMSG) NE 0 THEN ERRMSG = MESSAGE
	RETURN, RESULT
	END
