	PRO READ_MSP_ITEM, UNIT, TYPE, ITEM, ERRMSG=ERRMSG
;+
; Project     :	SOHO - CDS/SUMER
;
; Name        :	READ_MSP_ITEM
;
; Purpose     :	Reads an item from a Microsoft Project file.
;
; Explanation :	Reads the information in the next line of a Microsoft 
;               Project file.  The file must have been opened first
;		with OPEN_MSP_FILE.  If the end of the file is reached, 
;               the file is closed automatically.
;
; Use         :	READ_MSP_ITEM, UNIT, TYPE, ITEM
;
;		OPEN_MSP_FILE, UNIT, FILENAME
;		TYPE = 'Test'
;		WHILE TYPE NE '' THEN BEGIN
;			READ_MSP_ITEM, UNIT, TYPE, ITEM
;			...
;		ENDWHILE
;
; Inputs      :	UNIT	 = Unit number from OPEN_MSP_FILE
;
; Opt. Inputs :	None.
;
; Outputs     :	TYPE	 = The type of item read in.  If nothing was found,
;			   then this will be the null string.  Otherwise
;                          this parameter will be MSPBLOCK
;
;		ITEM	 = Structure containing the item read in.  The format
;			   of this structure is as follows:
;
;                          NAME :     MSP_ITEM
;
;                          TAGS :     LINE_NO           INTEGER
;                                     INSTRUME          CHARACTER STRING
;                                     BLOCK_NO          INTEGER
;                                     SUB_BLOCK_NO      INTEGER
;                                     AUX_BLOCK_NO      INTEGER
;                                     BLOCK_LABEL       CHARACTER STRING
;                                     OBJECTIVE         CHARACTER STRING
;                                     START_TIME_STR    CHARACTER STRING
;                                     END_TIME_STR      CHARACTER STRING
;                                     START_TIME        DOUBLE
;                                     END_TIME          DOUBLE
;                                     RESOURCE_STR      CHARACTER STRING
;                                     DURATION_STR      CHARACTER STRING
;
; Opt. Outputs:	None.
;
; Keywords    :	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 = ''
;			     READ_MSP_ITEM, UNIT, TYPE, ITEM, ERRMSG=ERRMSG
;			       IF ERRMSG NE '' THEN ...
;
; Calls       :	GET_FIELD,
;               GET_SECTION_NO,
;               CNVRT_MSPTIME,
;               UTC2TAI,
;               STR2UTC
;
; Common      :	None.
;
; Restrictions:	The file must have been opened with OPEN_MSP_FILE.
;
; Side effects:	None.
;
; Category    :	Planning, science
;
; Prev. Hist. :	This procedure is based on READ_KAP_ITEM, version 6.
;               Written by William Thompson, GSFC, 18 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
;
;  Check the input parameters.
;
	IF N_PARAMS() NE 3 THEN BEGIN
		MESSAGE = 'Syntax:  READ_KAP_ITEM, UNIT, TYPE, ITEM'
		GOTO, HANDLE_ERROR
	ENDIF

;
;  Set LINE and TYPE to empty strings.  This will be useful if we have already
;  reached the end of the Microsoft Project file.
;

	LINE = ''
	TYPE = ''

;
;  Set ERR_TYPE to "Microsoft Project File Format Error". This is only type
;  of error this part of the procedure will return.
;

        ERR_TYPE = "Microsoft Project File Format Error - "

;
;  Define the default MSP_ITEM  structure.  This structure contains all the
;  information that can be extracted from one line of a Microsoft Project 
;  file.  Depending on the nature of the line, not all of the information in
;  this structure may be present in the line.


        ITEM = {MSP_ITEM,                  $
                LINE_NO: 0,                $
                INSTRUME: 'X',  	   $
                BLOCK_NO: 0,               $
                SUB_BLOCK_NO: 0,           $
                AUX_BLOCK_NO: 0,           $
                BLOCK_LABEL:'NULL BLOCK',  $
                OBJECTIVE: '',             $
                START_TIME_STR: '',        $
                END_TIME_STR: '',          $
                START_TIME: 0.0D0,         $
                END_TIME: 0.0D0,           $
                RESOURCE_STR: '',          $
                DURATION_STR: '0h'}

;
;  Set up an array containing the names of all the different instruments.
; 

        INSTRUMENT_NAMES = ["CDS",          $
                            "CELIAS",       $
                            "CEPAC",        $
                            "EIT",          $
                            "GOLF",         $
                            "LASCO",        $
                            "MDI",          $
                            "SUMER",        $
                            "SWAN",         $
                            "VIRGO",        $
                            "UVCS" ]

;
;  Set NO_INSTRUMENTS to the number of instrument names that were inserted
;  into the INSTRUMENT_NAMES array.
;

        NO_INSTRUMENTS = N_ELEMENTS (INSTRUMENT_NAMES)

;
;  Attempt to read a line from the Microsoft Project file.  A line is read
;  unless the End Of File has been reached.  If we are able to read a line, 
;  then we will go on and process it.  
;
	WHILE (NOT EOF(UNIT)) DO  BEGIN
           READF, UNIT, LINE

;
;  Break the line up into fields.
;
 
           FIELD = GET_FIELD (LINE)

;
;  Remove any extra whitespace from the fields we just retrieved.
;

           FIELD = STRCOMPRESS (STRTRIM (FIELD, 2))

;
;  Check to make sure all of the required fields were recovered from the line.
;

           IF N_ELEMENTS (FIELD) LT 8 THEN GOTO, NEXT_ITERATION

;
;  Got a line, so lets get busy with it.  First we set TYPE to MSPBLOCK since
;  everything we try to read from the Microsoft Project file will be stuck
;  into a MSP_ITEM structure
;

           TYPE = 'MSPBLOCK'

;
;  Read in the first field from the line being processed into the structure
;  pointed to by ITEM.  This should corespond to the line number.
;

           TMP = 0
           READS, FIELD (0), TMP
           ITEM.LINE_NO = TMP


;
;  Read in the second field from the line being processed into the structure
;  pointed to by ITEM.  This field should correspond to the BLOCK_LABEL 
;  tag in the structure.
;

           ITEM.BLOCK_LABEL = FIELD (1)

;
;  Read in the third field from the line being processed into the structure
;  pointed to by ITEM.  This field should correspond to the DURATION_STR tag
;  in the structure.
;

           ITEM.DURATION_STR = FIELD (2)  
  

;
;  Read in the forth field from the line being processed into the structure
;  pointed to by ITEM.  This field should correspond to the START_TIME_STR 
;  tag in the structure.
;

           ITEM.START_TIME_STR = CNVRT_MSPTIME (FIELD (3), ERRMSG=ERRMSG)  

;
;  Read in the fifth field from the line being processed into the structure
;  pointed to by ITEM.  This field should correspond to the END_TIME_STR tag 
;  in the structure.
;

           ITEM.END_TIME_STR =  CNVRT_MSPTIME (FIELD (4), ERRMSG=ERRMSG)

;
;  Read in the eigth field from the line being processed into the structure
;  pointed to by ITEM.;  This field should correspond to the RESOURCE_STR tag
;  in the structure.
;

           ITEM.RESOURCE_STR = FIELD (7)

;
;  Convert the the starting time of the block to a floating point number in
;  TAI format.  This stored in the MSP_ITEM type structure ITEM at tag 
;  START_TIME. 
;

           START_TIME = ITEM.START_TIME_STR
           ITEM.START_TIME = UTC2TAI (STR2UTC (START_TIME))

;
;  Convert the the end time of the block to a floating point number in
;  TAI format.  This stored in the MSP_ITEM type structure ITEM at tag 
;  END_TIME. 
;

           END_TIME = ITEM.END_TIME_STR
           ITEM.END_TIME = UTC2TAI (STR2UTC (END_TIME))


;
;  Set the OBJECTIVE field of the ITEM structure to be equal to the BLOCK_LABEL
;  field.  If the this is an instrument sub block, then this field will be 
;  reset later.
;

           ITEM.OBJECTIVE = ITEM.BLOCK_LABEL

;
;  Copy the block label to a temporary string.
;
 
           BL = ITEM.BLOCK_LABEL

;
;  Convert the block label to upper case.
;

           BL = STRUPCASE (BL)

;
;  Determine if the block label contains the keyword BLOCK
;

           BLOCK_POS = STRPOS (BL, "BLOCK")
           
;
;  If the BLOCK keyword is found, then look for an instrument name.  
;  Instrument names are kept in the array INSTRUMENT_NAMES.  If we do find 
;  an instrument name, then we set INAME equal to the instrument name and 
;  attempt to read a block number.  The block number is stored in BLOCK_NO
;
           
           IF BLOCK_POS GE 0 THEN BEGIN
              INAME = ""
              FOR I = 0, NO_INSTRUMENTS - 1 DO BEGIN
                 NAME_POS = STRPOS (BL, INSTRUMENT_NAMES (I))
                 IF NAME_POS NE -1 THEN BEGIN
                    INAME = INSTRUMENT_NAMES (I)
                    GET_INSTRUMENT, INAME, IDESC
                    ITEM.INSTRUME = IDESC.CODE
                    ITEM.BLOCK_NO = (GET_SECTION_NO (BL))(1)
                 ENDIF
              ENDFOR
           ENDIF    

;
;  If we did not find the BLOCK keyword, then look for a block and subblock 
;  number.  If we do find a block and subblock number, then we will set 
;  the instrume field to a null string, since the block refers to an 
;  instrument (and not the SVM) but we can not tell which instrument.
;

           IF BLOCK_POS EQ -1 THEN BEGIN
              BLOCK_NO = GET_SECTION_NO (BL)
              IF N_ELEMENTS (BLOCK_NO) GE 3 THEN BEGIN

                 OBJSTART = BLOCK_NO (0)
                 OBJLEN   = STRLEN (ITEM.BLOCK_LABEL) - OBJSTART
                 OBJ =  STRMID (ITEM.BLOCK_LABEL, OBJSTART, OBJLEN)
                 ITEM.OBJECTIVE = STRCOMPRESS (STRTRIM (OBJ, 2))

                 ITEM.INSTRUME = ''
                 ITEM.BLOCK_NO = BLOCK_NO (1)
                 ITEM.SUB_BLOCK_NO = BLOCK_NO (2)

                 IF N_ELEMENTS (BLOCK_NO) EQ 4 THEN BEGIN
                    ITEM.AUX_BLOCK_NO = BLOCK_NO (3)
                 ENDIF

                 RS = STRUPCASE (ITEM.RESOURCE_STR)

                 FOR I = 0, NO_INSTRUMENTS - 1 DO BEGIN
                    NAME_POS = STRPOS (RS, INSTRUMENT_NAMES (I))
                    IF NAME_POS NE -1 THEN BEGIN
                       INAME = INSTRUMENT_NAMES (I)
                       GET_INSTRUMENT, INAME, IDESC
                       ITEM.INSTRUME = IDESC.CODE
                    ENDIF
                 ENDFOR

              ENDIF
           ENDIF         

;
;  We have got all the relevant information into the structure ITEM, so 
;  we can return.
;

           RETURN

NEXT_ITERATION:

;
;  We could not decipher the line we read, so lets try again.
;

        ENDWHILE

;
;  If the end-of-file was reached, then simply close the file and return.
;
	
        FREE_LUN, UNIT
        RETURN

;
;  Error handling point.
;
HANDLE_ERROR:
	IF N_ELEMENTS(ERRMSG) EQ 0 THEN MESSAGE, MESSAGE, /CONTINUE	$
		ELSE ERRMSG = 'READ_MSP_ITEM: ' + MESSAGE
	FREE_LUN, UNIT
	RETURN
	END

