	FUNCTION READ_MSP_FILE, FILENAME,                  $
                                BLOCK=IBLCK,               $
                                SVM=SVM,                   $ 
                                ERRMSG=ERRMSG,             $
                                IGNORE=IGNORE
;+
; Project     :	SOHO - CDS/SUMER
;
; Name        :	READ_MSP_FILE()
;
; Purpose     :	Reads in a Microsoft Project file.
;
; Explanation :	Reads in a Microsoft Project file, and stores the 
;               information in the appropriate databases.
;
; Use         :	Result = READ_MSP_FILE ( FILENAME )
;
;		Result = READ_MSP_FILE ( FILENAME, IGNORE='CDS')
;		Result = READ_MSP_FILE ( FILENAME, IGNORE='SUMER')
;
; Inputs      :	FILENAME = The name of the file to read.
;
; 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    :	IGNORE	 = If passed, then contains the name or code value 
;                          (see GET_INSTRUMENT) of an instrument to ignore when
;			   reading in entries.  This is so that one can
;			   avoid overwriting one's own SCIPLAN entries, if
;			   desired.
;
;               SVM      = If passed, then this keyword will cause activities 
;                          for the spacecraft (SVM) to be processed and 
;                          entered into the database.  Normally, spacecraft 
;                          activities are ignored.
;
;               BLOCK    = If passed, then this keyword will block header
;                          activities -- which are used to group experiment
;                          activities into blocks -- will be processed and
;                          entered into the database.  Normally, block header
;                          activities are ignored.  Note setting this flag may
;                          cause other software to crash since the block header
;                          activity will span the same time frame as all of
;                          the activities in the block.
;
;		ERRMSG   = If defined and passed, then any error messages will
;			   be returned to the user in this parameter rather
;			   than being handled by the IDL MESSAGE utility.  If
;			   no errors are encountered, then a null string is
;			   returned.  In order to use this feature, the string
;			   ERRMSG must be defined first, e.g.,
;
;		           ERRMSG = ''
;		           Result = READ_MSP_FILE (FILENAME, ERRMSG=ERRMSG )
;				IF ERRMSG NE '' THEN ...
;
; Calls       :	OPEN_MSP_FILE, 
;               READ_MSP_ITEM, 
;               UPD_PLAN, 
;		PRG_PLAN 
;
; Common      :	None.
;
; Restrictions:	When using the CDS database system, !PRIV must be 3 or greater
;		to use this routine.  This restriction is enforced except in
;		VMS, where it is assumed that the Oracle-based SUMER system is
;		used instead.
;
; Side effects:	None.
;
; Category    :	Planning, science.
;
; Prev. Hist. :	This procedure is based on READ_KAP, version 8.
;               Written by William Thompson, GSFC, 8 August 1995.
;
; Written     :	Ron Yurow, 7 November 1995
;
; Modified    :	Version 1, Ron Yurow, 7 November 1995
;
; Version     :	Version 1, 7 November 1995
;-
;
	ON_ERROR, 2
;
;  Make sure that UNIT is initialized to -1 so that errors can be handled
;  correctly.
;
	UNIT = -1
;
;  Check the number of parameters.
;
	IF N_PARAMS() NE 1 THEN BEGIN
		MESSAGE = 'Syntax:  Result = READ_MSP_FILE ( FILENAME, ' 
                MESSAGE = MESSAGE + ' /SVM, /BLOCK, ERRMSG=ERRMSG )'
		GOTO, HANDLE_ERROR
	ENDIF
;
;  Make sure that FILENAME is a character string scalar.
;
	IF N_ELEMENTS(FILENAME) NE 1 THEN BEGIN
		MESSAGE = 'FILENAME must be a scalar'
		GOTO, HANDLE_ERROR
	END ELSE IF DATATYPE(FILENAME,1) NE 'String' THEN BEGIN
		MESSAGE = 'FILENAME must be a character string'
		GOTO, HANDLE_ERROR
	ENDIF
;
;  Make sure that one has sufficient privilege to run the software.
;
	IF !VERSION.OS NE 'vms' THEN BEGIN
	    TEST = EXECUTE('PRIV = !PRIV')
	    IF PRIV LT 3 THEN BEGIN
		MESSAGE = '!PRIV must be 3 or greater to run this routine'
		GOTO, HANDLE_ERROR
	    ENDIF
	ENDIF
;
;  If the IGNORE keyword was passed, then determine which instrument this
;  refers to.
;
	IF N_ELEMENTS(IGNORE) EQ 1 THEN BEGIN
		GET_INSTRUMENT, IGNORE, INS, ERRMSG=ERRMSG
		IF N_ELEMENTS(ERRMSG) NE 0 THEN IF ERRMSG(0) NE '' THEN BEGIN
			MESSAGE = ERRMSG
			GOTO, HANDLE_ERROR
		ENDIF
		INS_IGNORE = INS.CODE
	END ELSE INS_IGNORE = 'None'
;
;  Open the input file.
;
	OPEN_MSP_FILE, UNIT, FILENAME, ERRMSG=ERRMSG
	IF UNIT LT 0 THEN BEGIN
		MESSAGE = 'Unable to open file ' + FILENAME
		GOTO, HANDLE_ERROR
	ENDIF
	PRINT, 'Reading file ' + FILENAME

;
;  Set WRNMSG1 and WRNMSG2 to appropiate warning messages.
;

	WRNMSG1 = "Warning:  END TIME is less then START TIME for ITEM NO. : "
        WRNMSG2 = "Warning:  END TIME is equal to START TIME for ITEM NO. :"

;
;  Keep track of how many items of each type have been read in.
;
	N_SCIPLAN = 0
;
;  Read in the Microsoft Project file item by item until the end is reached.
;
	TYPE = 'Test'
	WHILE TYPE NE '' DO BEGIN
		READ_MSP_ITEM, UNIT, TYPE, BLOCK, ERRMSG=ERRMSG
		IF N_ELEMENTS(ERRMSG) NE 0 THEN IF ERRMSG NE '' THEN	$
			GOTO, HANDLE_ERROR
;
;  Collect all the SCIPLAN entries.  However, ignore any MDI entries with the
;  mnemonic "Struct_Prog", or entries for the instrument that was selected to
;  be ignored.
;


		ITEM = {KAP_SCIPLAN,		           $
                        START_TIME: BLOCK.START_TIME,      $
                        END_TIME:   BLOCK.END_TIME,        $
                        INSTRUME:   BLOCK.INSTRUME,        $
                        SCI_OBJ:    BLOCK.OBJECTIVE,       $
                        SCI_SPEC: '',                      $
                        OBJECT: '',                        $
                        OBJ_ID: '',                        $
                        NOTES:      BLOCK.RESOURCE_STR,    $
                        PROG_ID: 0,                        $
                        CMP_NO: 0,                         $
                        XCEN: '',                          $
                        YCEN: '',                          $
                        DISTURBANCES: '',                  $
                        DATE_MOD: 0.0D0,                   $
                        MNEMONIC: ''}

;
;  Add the current time in TAI format to the DATE_MOD field in the structure
;  ITEM.
;
               
                GET_UTC, UTC
                ITEM.DATE_MOD = UTC2TAI (UTC)

;
;  Determine the value for the logical flag ADD_SCI_PLAN.  If this is
;  1 (TRUE), then the SCIPLAN struncture will be added to the array of SCIPLAN
;  structures being kept at SCIPLAN.  Otherwise, the SCIPLAN structure will
;  be discarded.
;

                ADD_SCI_PLAN = ITEM.INSTRUME NE INS_IGNORE 
                
                IF ITEM.INSTRUME EQ 'X' THEN BEGIN 
                   ADD_SCI_PLAN = ADD_SCI_PLAN AND KEYWORD_SET (SVM)
                ENDIF ELSE IF BLOCK.SUB_BLOCK_NO EQ 0 THEN BEGIN 
                   ADD_SCI_PLAN = ADD_SCI_PLAN AND KEYWORD_SET (IBLCK)
                ENDIF

                IF ADD_SCI_PLAN THEN BEGIN

;
;  Check that the start time is less then the end time.  If it is greater then
;  the end time, then print a warning message and discard that SCIPLAN 
;  entry.
;

	           IF ITEM.END_TIME LT ITEM.START_TIME THEN BEGIN
                      PRINT, WRNMSG1, BLOCK.LINE_NO
                      ADD_SCI_PLAN = 0
	           ENDIF

;
;  Check that the start time is equal to the end time.  If it is then print
;  a warning message and set the end to be the start time plus 5 minutes.
;

	           IF ITEM.END_TIME EQ ITEM.START_TIME THEN BEGIN
                      PRINT, WRNMSG2, BLOCK.LINE_NO
                      ITEM.END_TIME = ITEM.START_TIME + 300
	           ENDIF

                ENDIF


		IF ADD_SCI_PLAN THEN BEGIN
                   IF N_SCIPLAN EQ 0 THEN BEGIN
                      SCIPLAN = ITEM 
                   ENDIF ELSE BEGIN
                      SCIPLAN = [SCIPLAN, ITEM]
                   ENDELSE

		   N_SCIPLAN = N_SCIPLAN + 1
                ENDIF
;
	ENDWHILE

;
;  Print a message telling the user how many SCIPLAN entries we gathered.
;

        PRINT, "Retrieved ",                             $
               N_SCIPLAN,                                $
               " SCIPLAN entries from file ",            $
               FILENAME
               

;
;  Write out those items which were gathered.
;
	IF N_SCIPLAN GT 0 THEN BEGIN
	    PRINT, 'Updating science plan'
	    IF NOT UPD_PLAN(SCIPLAN, ERRMSG=ERRMSG) THEN BEGIN
        	MESSAGE = 'Unable to update science plan'
        	GOTO, HANDLE_ERROR
            ENDIF
	ENDIF
;
;
;  Purge the appropriate databases.
;
	PRINT, 'Purging databases'
	IF NOT PRG_PLAN    (ERRMSG=MESSAGE) THEN GOTO, HANDLE_ERROR
;
;  Signal success.
;
	RESULT = 1
	GOTO, FINISH
;
;  Error handling point.
;
HANDLE_ERROR:
	IF UNIT GT 0 THEN FREE_LUN, UNIT
	IF N_ELEMENTS(ERRMSG) EQ 0 THEN MESSAGE, MESSAGE, /CONTINUE	$
		ELSE IF ERRMSG EQ '' THEN ERRMSG = 'READ_MSP_FILE: ' + MESSAGE
	RESULT = 0
;
;  Return whether successful or not.
;
FINISH:	
	RETURN, RESULT
	END
