; Copyright (c) 1998-2011 A.P. Hitchcock  All rights reserved
;+
;NAME:
;		READ_CSV.PRO
;
;LAST CHANGED: ----------------------------------- 	31-Jul-11
;
; PURPOSE:
;	This procedure reads comma separated variable format files (*.csv)
; as written by Excel; closely related to 'mapper' type files
; and places te result into a user defined array variable, 'items'
;
; CATEGORY:
;	Read in
;
; CALLING SEQUENCE:
; for functions:
;	Result = READ_CSV(filename, items, help=help, quiet=quiet, string=string)
;
; INPUTS:
; 	FILENAME    the name of the mapper file to be read
;	ITEMS		output of ITEMS that were in the file
;
; KEYWORDS:
;	HELP		prints help instructions
;	QUIET		do not print values as they are read-in
;	ALL_STRING	if set, report all variables as strings
;
; OUTPUTS:
;	items as 2D array.  You can also do x=items(0,*) and y=items(1,*)
;
; COMMON BLOCKS:none
;
; MODIFICATION HISTORY:
; (01-apr-99 cjj) work with 2d array
; (19-jul-00 cjj) Switch to using strsplit() to allow commas or spaces as delimiters
; (31-Jul-11 aph) AXIS standard header added;  string keyword replaced by all_string
;-

PRO read_csv, filename, items, help=help, quiet=quiet, all_string=all_string

  IF (keyword_set(help) OR (n_elements(filename) EQ 0) OR $
      (n_params() EQ 0)) THEN BEGIN
      print, 'read_csv,filename,items [/quiet]'
      print, '  Reads in data in the format of Excel .CSV files'
      print, '  /all_string for reading all data as character strings'
      return
  ENDIF

  filelist = file_search(filename)
  svec = size(filelist)
  IF (svec(0) EQ 0) THEN BEGIN
      message,'Could not open file "'+filename+'"',/informational
      return
  ENDIF

  on_ioerror,bailout
  get_lun,lun
  openr, lun, filename

  input_string = ""
  got_firstline = 0
  n_lines = 0L
  items_per_line = 0
  zero_byte = byte('0')
  zero_byte = zero_byte(0)
  nine_byte = byte('9')
  nine_byte = nine_byte(0)
  point_byte = byte('.')
  point_byte = point_byte(0)
  plus_byte = byte('+')
  plus_byte = plus_byte(0)
  minus_byte = byte('-')
  minus_byte = minus_byte(0)
  space_byte = byte(' ')
  space_byte = space_byte(0)
  tab_byte = byte(9)

  is_comma_separated = 0

  idlversion = idl_version()

  WHILE (NOT EOF(lun)) DO BEGIN
      readf, lun, input_string

      firstchar = byte(strmid(input_string,0,1))
      firstchar = firstchar(0)
      IF ((firstchar EQ space_byte) OR (firstchar EQ tab_byte) OR $
          (firstchar EQ plus_byte) OR (firstchar EQ minus_byte) OR $
          (firstchar EQ point_byte) OR $
          ((firstchar GE zero_byte) AND (firstchar LE nine_byte)) ) THEN BEGIN

          IF (got_firstline EQ 0) THEN BEGIN
              IF (strpos(input_string, ',') EQ (-1)) THEN BEGIN
                  ;; We will want to look for spaces as delimiters
                  IF (idlversion GE 5.3) THEN BEGIN
                      sepitems = strsplit(input_string)
                  ENDIF ELSE BEGIN
                      sepitems = str_sep(input_string,' ')
                  ENDELSE
              ENDIF ELSE BEGIN
                  ;; Use commas as delimiters
                  is_comma_separated = 1
                  IF (idlversion GE 5.3) THEN BEGIN
                      sepitems = strsplit(input_string, ',')
                  ENDIF ELSE BEGIN
                      sepitems = str_sep(input_string,',')
                  ENDELSE
              ENDELSE

              svec = size(sepitems)
              IF (svec(0) EQ 0) THEN BEGIN
                  ;; We got no split, so something is wrong
                  GOTO, bailout
              ENDIF
              items_per_line = svec(1)
              words = strarr(items_per_line)
              i_item = 0
              WHILE (i_item LT (items_per_line-1)) DO BEGIN
                  words[i_item] = strmid(input_string, sepitems[i_item], $
                                         (sepitems[i_item+1]-sepitems[i_item]))
                  i_item = i_item+1
              ENDWHILE
              words[i_item] = strmid(input_string, sepitems[i_item])

              n_lines = 1L
              IF keyword_set(all_string) THEN BEGIN
                  items = strarr(items_per_line,n_lines)
                  items[0:(items_per_line-1),0] = $
                    words[0:(items_per_line-1)]
              ENDIF ELSE BEGIN
                  this_items = fltarr(items_per_line)
                  items = fltarr(items_per_line,n_lines)
                  reads,words,this_items
                  items[0:(items_per_line-1),0] = $
                    this_items[0:(items_per_line-1)]
              ENDELSE
              got_firstline = 1
          ENDIF ELSE BEGIN
              IF (is_comma_separated EQ 0) THEN BEGIN
                  ;; We will want to look for spaces as delimiters
                  IF (idlversion GE 5.3) THEN BEGIN
                      sepitems = strsplit(input_string)
                  ENDIF ELSE BEGIN
                      sepitems = str_sep(input_string,' ')
                  ENDELSE
              ENDIF ELSE BEGIN
                  ;; Use commas as delimiters
                  IF (idlversion GE 5.3) THEN BEGIN
                      sepitems = strsplit(input_string, ',')
                  ENDIF ELSE BEGIN
                      sepitems = str_sep(input_string,',')
                  ENDELSE
              ENDELSE

              svec = size(sepitems)
              IF (svec(0) EQ 0) THEN BEGIN
                  ;; We got no split, so something is wrong
                  GOTO, bailout
              ENDIF
              items_per_this_line = svec(1)
              IF (items_per_this_line NE items_per_line) THEN BEGIN
                  print, 'Line "'+input_string+'" has '+$
                         strtrim(string(items_per_this_line), 2)+', not '+$
                         strtrim(string(items_per_line), 2)+', items'
                  GOTO, bailout
              ENDIF

              i_item = 0
              WHILE (i_item LT (items_per_line-1)) DO BEGIN
                  words[i_item] = strmid(input_string, sepitems[i_item], $
                                       (sepitems[i_item+1]-sepitems[i_item]))
                  i_item = i_item+1
              ENDWHILE
              words[i_item] = strmid(input_string, sepitems[i_item])

              n_lines = n_lines+1L
              old_items = items
              IF keyword_set(all_string) THEN BEGIN
                  items = strarr(items_per_line,n_lines)
                  items[0:(items_per_line-1),0:(n_lines-2)] = $
                    old_items[0:(items_per_line-1),0:(n_lines-2)]
                  items[0:(items_per_this_line-1),(n_lines-1)] = words
              ENDIF ELSE BEGIN
                  reads,words,this_items
                  items = fltarr(items_per_line,n_lines)
                  items[0:(items_per_line-1),0:(n_lines-2)] = $
                    old_items[0:(items_per_line-1),0:(n_lines-2)]
                  items[0:(items_per_this_line-1),(n_lines-1)] = this_items
              ENDELSE
          ENDELSE
      ENDIF
  ENDWHILE

bailout:
  close,lun
  free_lun,lun

  return
END
