;+
; Project     :	SOHO - CDS
;
; Name        :	GET_CDHS_INDEX()
;
; Purpose     :	Returns an internal CDHS index for a table.
;
; Explanation : Interrogates the commprep database to find whether the series, raster,
;               dexwin or vdswin table is currently loaded on the CDS. 
;               If already loaded then returns the CDHS index assigned to it else gives
;               the table a new index and enters it into the database.
;               Allows CDS indices to be re-used if prior to last time tagged study.
;               NB. If loading science plan from the past will allow older tables to be overwritten.
;
; Use         : <get_cdhs_index, type, initial_table, cut_off_time>
;
; Inputs      : type   = character string indicating table type
;                        i.e SERIES, RASTER, DEXWIN, VDSWIN.
;               initial_table = structure containing table information.
;                    table.time   = the observation time of the study using the table
;                                   taken from the sci_details database
;                    table.cdhsid = the internal CDHS ID used to reference the table
;               cut_off_time = DOUBLE TAI format time before which tables may be overwritten
;                   
; Opt. Inputs : None.
;
; Outputs     : Structure containing table information with CDHS index and table OK
;               entries set.
;                    table.ok     = an integer flag indicating whether table has already 
;                                  been loaded onto the CDS.
;                    table.cdhsx  = the internal CDHS index where the table is loaded
;
; Opt. Outputs:	None.
;
; Keywords    : None.
;
; Calls       :	dbopen, db_info, dbbuild, dbfind, dbext, dbclose, dbsort, dbupdate,
;               get_utc, utc2tai, anytim2cal.
;                
; Common      :	None.
;
; Restrictions:	None.
;
; Side effects:	None.
;
; Category    :	Command preparation.
;
; Prev. Hist. :	None.
;
; Written     :	Version 0.0, Martin Carter, RAL, 14/10/94
;
; Modified    :	Version 0.1, Martin Carter, RAL, 28/11/94
;                            Added proforma.
;               Version 0.2, MKC, RAL, 18/4/95
;                            Separated table type into another input.
;               Version 0.3, MKC, RAL, 5/9/95
;                            Fixed bug due to passing by value to dbext.
;                            Only affected when all indeces used.
;               Version 0.4, MKC, 25/9/95
;                            Pointed SW at duplicate database.
;               Version 0.5, MKC, 3/11/95
;                            Added /SILENT keyword to dbbuild.
;               Version 0.6, MKC, 5/9/96
;                            Modified printout if no space available.
;               Version 0.7, MKC, 3/10/96
;                            Added cut off time to allow previous tables to be overwritten.
;                            Removed bug in defining last 24 hours.
;                            Removed bug in setting up time table last used. 
;
; Version     :	Version 0.7, 3/10/96
;-
;**********************************************************

FUNCTION get_cdhs_index, type, initial_table, cut_off_time

  ; check if table loaded and if not return new index for loading

  ; copy initial table

  table = initial_table

  ; set up maximum index number for table type

  IF type EQ 'SERIES' THEN maxindex = 59 ELSE $
  IF type EQ 'RASTER' THEN maxindex = 49 ELSE $
  IF type EQ 'DEXWIN' THEN maxindex = 39 ELSE $
  IF type EQ 'VDSWIN' THEN maxindex = 19 

  ; set up minimum index number for table type

  IF type EQ 'SERIES' THEN minindex = 12 ELSE $
  IF type EQ 'RASTER' THEN minindex =  2 ELSE $
  IF type EQ 'DEXWIN' THEN minindex =  2 ELSE $
  IF type EQ 'VDSWIN' THEN minindex =  1 

  ; set priviledge to update database

  !PRIV = 2

  ; open command preparation database for updating

  dbopen, 'dcommprep', 1

  ; check if table exists already

  ; check database has some entries
  ;  else dbfind will flag error

  nentries = db_info ( 'entries' )

  IF nentries(0) EQ 0 THEN BEGIN

    ; database is empty

    ; table is not loaded

    table.ok = 0

    ; set first table index

    table.cdhsx = minindex

    ; create first entry in database

    dbbuild, table.time, type, table.cdhsid, table.cdhsx, /SILENT

  ENDIF ELSE BEGIN

    ; database has at least some entries

    ; check whether database has any entries of the required type

    ; set up search criteria

    search = 'TYPE=' + type 

    typelist = dbfind ( search, /SILENT )

    IF typelist(0) LT 1 THEN BEGIN

      ; no entries of this table type loaded yet

      ; table is not loaded

      table.ok = 0

      ; set first table index

      table.cdhsx = minindex

      ; create first entry in database

      dbbuild, table.time, type, table.cdhsid, table.cdhsx, /SILENT

    ENDIF ELSE BEGIN

      ; at least some tables of this type loaded

      ; refine search criteria

      search = 'CDHS_ID=' + STRING(table.cdhsid)

      list = dbfind ( search, typelist, /SILENT )

      ; check only one entry

      IF N_ELEMENTS(list) NE 1 THEN BEGIN
        !PRIV = 1  
        MESSAGE, 'IMPLEMENTATION ERROR, NUMBER OF ENTRIES NOT EQUAL TO 1'
      END

      ; is table already loaded

      IF list(0) LT 1 THEN BEGIN

        ; table is not loaded

        table.ok = 0

        ; get indeces already used

        ; sort indeces into numerical order

        list = dbsort ( typelist, 'CDHS_X')

        ; extract cdhs indeces used

        dbext, list, 'CDHS_X', cdhsxs

        ; cdhsxs contains a sorted list of indeces used
        ; check if all indeces used already

        IF N_ELEMENTS(cdhsxs) EQ (maxindex-minindex+1) THEN BEGIN

          ; all indeces used
          ; re-use index number

          ; get oldest table index

          ; sort times into numerical order

          list = dbsort ( list, 'DATE')

          ; extract TAI times table entries last used

          dbext, list, 'DATE', tais

          ; check oldest before last time tagged study

          IF tais(0) GT cut_off_time THEN BEGIN

            ; get some info about what tables are on board

            dbext, list, 'CDHS_ID, CDHS_X', cdhsids, cdhsxs

            ; print info

            PRINT, 'WARNING, ON-BOARD ' + type + ' TABLE AREA FULL'
            PRINT, ''

            ; check table type for info output

            IF type EQ 'SERIES' THEN BEGIN

              PRINT, 'CDHS INDEX   TIME LAST USED   CDHS ID   PLANNING ID, VAR'

              FOR k = 0, N_ELEMENTS(list)-1 DO BEGIN

                ; get info about this CDHS ID

                st = get_cdhs_series(cdhsids(k),/DTYPE)

                PRINT, cdhsxs(k), anytim2cal(tais(k)), cdhsids(k), st.id, st.var

              ENDFOR

            ENDIF

            PRINT, ''

            ; stop processing

            ; close table ID database

            dbclose, 'dcommprep'

            ; reset priviledges

            !PRIV = 1  

            MESSAGE,'ERROR, NO SPACE AVAILABLE ON-BOARD FOR LOADING ' + type + ' TABLE'

          ENDIF

          ; get index for this entry
          ; NB take care not to pass variable by value

          dbext, list(0), 'CDHS_X', cdhsxs

          table.cdhsx = cdhsxs(0)

          ; update table entry

          dbupdate, list(0), 'DATE,TYPE,CDHS_ID,CDHS_X', $
                    table.time, type, table.cdhsid, table.cdhsx
   
        ENDIF ELSE BEGIN
    
          ; find first unused index
      
          index = minindex
          notfound = 1
          WHILE ( ((index-minindex) LT (N_ELEMENTS(cdhsxs))) AND notfound ) DO $
             IF (cdhsxs(index-minindex) EQ index) THEN index=index+1 ELSE  notfound = 0 

          table.cdhsx = index

          ; create new entry in database

          dbbuild, table.time, type, table.cdhsid, table.cdhsx, /SILENT

        ENDELSE

      ENDIF ELSE BEGIN

        ; table does exist

        table.ok = 1

        ; get table entry

        dbext, list, 'DATE,CDHS_X', tais, cdhsxs

        ; update table entry time

        IF tais(0) LT table.time THEN dbupdate, list, 'DATE', table.time

        ; set table index 

        table.cdhsx = cdhsxs(0)

      ENDELSE

    ENDELSE

  ENDELSE

  ; close table ID database

  dbclose, 'dcommprep'

  ; reset priviledges

  !PRIV = 1  

  ; return table

  RETURN, table

END

