;+
;
; NAME: 
;   	UVPS_CATPARSE
;
; PURPOSE:
;	Take a string, that is users input list of parameters, and manipulate
;	it until it is pretty.
;
; CATEGORY:
;  	UVSP Catalog
;
; CALLING SEQUENCE:
;    	var = uvsp_catparse(new_param=new_param, exec=exec, $
;			    cat_value=cat_value, rmin=rmin, rmax=rmax)
;
; CALLED BY:
;       UVSP_CATPARAM
;
; CALLS TO:
;	none
;
; INPUTS:
;	NEW_PARAM : string that is the users form of a parameter input
;       CAT_VALUE : string or string array of the uvsp catalog field(s) 
;		    corresponding to the current parameter item
;	RMIN :	a minimun value that is excepted for this parameter
;               both RMIN and RMAX must be set for either to be used
;	RMAX :	a maximum value that is excepted for this parameter
;               both RMIN and RMAX must be set for either to be used
;
; OPTIONAL INPUTS:
;	FLOAT:  if set, then the values of NEW_PARAM are interpretted 
;		as float-point, to 2 significate digits.
;
; OUTPUTS:
;       NEW_PARAM : Returns a string that is the most condensed form of the 
;		    input parameter list.
;       EXEC      : Returns a string that is the where expression to be used
;		    to search the catalog.
;	RMIN :	Returns the minimun value that was input and accepted.
;	RMAX :	Returns the maximum value that was input and accepted.
;
;	The function returns the number of legal parameter groupings returned
;
; OPTIONAL OUTPUTS:
;	none
;
; COMMON BLOCKS:
;	COMMON AEROCASE,
;		 FLAGAERO, 		; flag if !AERO was used at all.
;		 AERORANGE              ; 2xN array containing the start and
;					;     end values for ranges when !AERO
;
; SIDE EFFECTS:
;	Since ranges are expanded to arrays, equal in size to the number
;	of elements in the range, it is possible to run out of memory with
;	large ranges.
;
; RESTRICTIONS:
;	If RMIN and RMAX are supplied, it is assumed that -999 will be outside
;	this range.
;
; PROCEDURE:
;	Ranges are indicated by "-", the order can be backwards (ex: 4-2)
;	Parameter sets are separated by blanks or commas or equals.
;	Expand ranges to one number for each value in the range, 
;	merge this with any single value inputs,
;	sort and get rid of duplicate number,
;	stick any consecutive number ranges together (separated by "-")
;	and return a string that is the parameter list.
;
; MODIFICATION HISTORY:
;	OCT 93 - Elaine Einfalt (HSTX)
;	oct 93 - added !AERO stuff.
;
;-

                                                       
function uvsp_catparse, new_param=new_param, exec=exec, cat_value=cat_value, $
			rmin=rmin, rmax=rmax, floater=floater

common aerocase, flagaero, aerorange


 flagaero  = 0				; very special handling if !AERO
 aerorange = 0				; clear out common 

 if keyword_set(floater) then floater=1 else floater=0
 if (floater) then begin
    rmin = rmin * 100
    rmax = rmax * 100
 endif

 siz = size(cat_value)		; siz(0) is 0 or 1 when checking user input
				; against a single catalog field (does the
				; current experiment have any of the user's
				; inputs for a value)
				; siz(0) is 2 when checking user input
				; against a range (is any part of the users
				; input range fall within the boundaries of
				; of this experiments fields (wavelenths))

 if siz(0) le 1 then span = 0 else span = 1

 good_ones = 0                           	; count up legal parameters
 new_param = ',' +strcompress(new_param,/remove) + ',' ; add start and end markers

 ;
 ; Fields are separated by commas or equals
 ;

 byte_line = byte(new_param) 		; change it into bytes for where
 fields = where((byte_line eq 44b) or $
	        (byte_line eq 61b), n_fields)

 expand = -999				; concatenate and expanded input

 ;
 ; Collect all the values for each field.
 ; Do a basic "Is this a number?" check.
 ; And, expand any ranges (indicated by dashes)
 ;

 for i = 0, n_fields-2 do begin
      ;
      ; Cut out a field from between a pair of delimeters
      ;

      value = strmid(new_param, fields(i)+1, fields(i+1)-fields(i)-1)
      if value eq '' then goto, SKIPIT


      ;
      ; Where are the dashes "-", identifing this as a range of values ?
      ;

      range = where(byte(value) eq 45b)		; a dash in this field ?
      special = where(byte(value) eq 33b)	; a "!" mean special case

      if special(0) ge 0 then begin		; special ! case
	case strupcase(value) of
         '!WLD'  : expand = [temporary(expand), lindgen(16632 - 30+1 )+30,$
					        lindgen(30685 - 21123+1)+21123]
         '!80'   : expand = [temporary(expand), lindgen(16632 - 1+1)+1]
         '!84'   : expand = [temporary(expand), lindgen(24874 - 16899+1)+16899]
         '!85'   : expand = [temporary(expand), lindgen(35105 - 24875+1)+24875]
         '!86'   : expand = [temporary(expand), lindgen(47510 - 35106+1)+35106]
         '!87'   : expand = [temporary(expand), lindgen(60633 - 47511+1)+47511]
         '!88'   : expand = [temporary(expand), lindgen(81643 - 60634+1)+60634]
         '!89'   : expand = [temporary(expand), lindgen(99771 - 81644+1)+81644]

         '!AERO' : begin
			; 
			; Restore a long array (GOODONES) from an IDL /XDR
			; save file.  There are 23,230 experiment numbers.
			; 
			print,'Restoring file with good aeronomy experiments.'
			restore,file='uvcat_aero:goodaero.cat'

			expand = [temporary(expand), goodones]
                        goodones=0		;clean up some

			flagaero = 1 		; very special handling
		   end

	  else:
	 endcase

      endif else if range(0) eq -1 then begin  	; no dash means a single value

	   on_ioerror, SKIPIT                   ; jump if not a number
	     if not(floater) then number = rmin>long(value)<rmax  $
			     else number = rmin > $
					    long(float(value) * 100) < $
					   rmax
	   on_ioerror, null

           expand = [temporary(expand), number]    ; add this to the list

      endif else begin 			; dash means this was a range

	   value = value + '-' 			; add a terminator
	   end_pts = where(byte(value) eq 45b)  

	   on_ioerror, SKIPIT
	      if not(floater) then begin
 	         num_1 = long(strmid(value, 0, end_pts(0)))
	         num_2 = long(strmid(value, end_pts(0)+1, $
					    end_pts(1)-end_pts(0)-1))
		 num_1 = rmin > num_1 < rmax
		 num_2 = rmin > num_2 < rmax
	      endif else begin
 	         num_1 = long(float(strmid(value, 0, end_pts(0))) * 100)
	         num_2 = long(float(strmid(value, end_pts(0)+1, $
					     end_pts(1)-end_pts(0)-1)) * 100)
		 num_1 = rmin > num_1 < rmax
		 num_2 = rmin > num_2 < rmax
	      endelse

	   on_ioerror, null

           expand = [temporary(expand), $
			lindgen((num_2>num_1)-(num_1<num_2)+1)+(num_1<num_2)]

      endelse 

SKIPIT:

 endfor

 if n_elements(expand) eq 1 then return,0		; none valid

 expand = expand(sort(expand))  			  ; sort first
 expand = expand(where(expand ne shift(expand,1)))        ; get rid of repeats
 expand = expand(1:*)		; lose the "-999"



 rmin = min(expand, max=rmax)			; min/max accepted for input
						; Rsun is the only float and
						; it doesn't use accepted range
						; If is did this would need to
						; be divided by 100


 ;
 ; Condense consecutive numbers into ranges.
 ;

 r_starts = expand( where(expand-1 ne shift(expand, 1), good_ones)) 
 r_ends   = expand( where(expand+1 ne shift(expand,-1)))           


 if (flagaero) then begin
    aerorange = lonarr(2,good_ones)

    aerorange(0,*) = r_starts
    aerorange(1,*) = r_ends
     
    new_param = '!AERO Case'
    return, good_ones
 endif

 if not(floater) then begin
    r_starts = strtrim(r_starts,2)
    r_ends   = strtrim(r_ends,  2)
 endif else begin
    r_starts = string(r_starts/100.,'(f4.2)')
    r_ends   = string(r_ends/100., '(f4.2)')
 endelse


 expand = 0b                                    ; clean up some
 ranges  = where(r_starts ne r_ends, cnt2)	; consecutive # ranges indices 

 valid_param = '' 			; construct the "SHOW" string
 
 ; 
 ; Loop to construct a where expression for later UVSP catalog searching.
 ;

 for i = 0, good_ones-1 do begin
    if (where(ranges eq i))(0) eq -1 then $     	 ; not a range
         valid_param = valid_param + ',' + r_starts(i)  $ 
    else valid_param = valid_param + ',' + r_starts(i) + '-' + r_ends(i)
 endfor

 ;
 ; Return the string condensed, checked and better organized.
 ;

 new_param = strmid(valid_param,1,999)		; leave off 1st ","

return, good_ones 	; how many good parameter inputs were there
end
